1 /*
2 **
3 ** Copyright (C) 2008-2013 Ian Firns (SecurixLive) <dev@securixlive.com>
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License Version 2 as
7 ** published by the Free Software Foundation.  You may not use, modify or
8 ** distribute this program under any other version of the GNU General
9 ** Public License.
10 **
11 ** This program is distributed in the hope that it will be useful,
12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 ** GNU General Public License for more details.
15 **
16 ** You should have received a copy of the GNU General Public License
17 ** along with this program; if not, write to the Free Software
18 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 **
20 **
21 */
22 
23 
24 /*
25 ** INCLUDES
26 */
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30 
31 #include <sys/types.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #ifdef SOLARIS
36     #include <strings.h>
37 #endif
38 #include <errno.h>
39 #include <unistd.h>
40 
41 #include <netinet/in.h>
42 #include <arpa/inet.h>
43 
44 
45 #include "barnyard2.h"
46 #include "debug.h"
47 #include "plugbase.h"
48 #include "spi_unified2.h"
49 #include "spooler.h"
50 #include "strlcpyu.h"
51 #include "util.h"
52 #include "unified2.h"
53 
54 /*
55 ** PROTOTYPES
56 */
57 void Unified2Init(char *);
58 
59 /* processing functions  */
60 int Unified2ReadRecordHeader(void *);
61 int Unified2ReadRecord(void *);
62 
63 int Unified2ReadEventRecord(void *);
64 int Unified2ReadEvent6Record(void *);
65 int Unified2ReadPacketRecord(void *);
66 
67 void Unified2PrintCommonRecord(Unified2EventCommon *);
68 void Unified2PrintEventRecord(Unified2IDSEvent_legacy *);
69 void Unified2PrintEvent6Record(Unified2IDSEventIPv6_legacy *);
70 void Unified2PrintPacketRecord(Unified2Packet *);
71 
72 /* restart/shutdown functions */
73 void Unified2CleanExitFunc(int, void *);
74 void Unified2RestartFunc(int, void *);
75 
76 
77 void Unified2PrintEventRecord(Unified2IDSEvent_legacy *);
78 void Unified2PrintEvent6Record(Unified2IDSEventIPv6_legacy *);
79 
80 
81 /*
82  * Function: UnifiedLogSetup()
83  *
84  * Purpose: Registers the input plugin keyword and initialization function
85  *          into the input plugin list.  This is the function that gets called
86  *          InitInputPlugins() in plugbase.c.
87  *
88  * Arguments: None.
89  *
90  * Returns: void function
91  *
92  */
Unified2Setup(void)93 void Unified2Setup(void)
94 {
95     /* link the input keyword to the init function in the input list */
96     RegisterInputPlugin("unified2", Unified2Init);
97     DEBUG_WRAP(DebugMessage(DEBUG_INIT,"Input plugin: Unified2 is setup...\n"););
98 }
99 
Unified2Init(char * args)100 void Unified2Init(char *args)
101 {
102     /* parse the argument list from the rules file */
103     //data = ParseAlertTestArgs(args);
104 
105     DEBUG_WRAP(DebugMessage(DEBUG_INIT,"Linking UnifiedLog functions to call lists...\n"););
106 
107     /* Link the input processor read/process functions to the function list */
108     AddReadRecordHeaderFuncToInputList("unified2", Unified2ReadRecordHeader);
109     AddReadRecordFuncToInputList("unified2", Unified2ReadRecord);
110 
111     /* Link the input processor exit/restart functions into the function list */
112     AddFuncToCleanExitList(Unified2CleanExitFunc, NULL);
113     AddFuncToRestartList(Unified2RestartFunc, NULL);
114 }
115 
116 /* Partial reads should rarely, if ever, happen.  Thus we should not actually
117    call lseek very often
118  */
Unified2ReadRecordHeader(void * sph)119 int Unified2ReadRecordHeader(void *sph)
120 {
121     ssize_t             bytes_read;
122     Spooler             *spooler = (Spooler *)sph;
123 
124     if( NULL == spooler->record.header )
125     {
126         // SnortAlloc will FatalError if memory can't be assigned.
127         spooler->record.header = SnortAlloc(sizeof(Unified2RecordHeader));
128     }
129 
130     /* read the first portion of the unified log reader */
131 #if DEBUG
132     int position = lseek(spooler->fd, 0, SEEK_CUR);
133     DEBUG_WRAP(DebugMessage(DEBUG_LOG,"Header: Reading at byte position %u\n", position););
134 #endif
135 
136     bytes_read = read( spooler->fd, spooler->record.header + spooler->offset, sizeof(Unified2RecordHeader) - spooler->offset);
137 
138     if (bytes_read == -1)
139     {
140         LogMessage("ERROR: Read error: %s\n", strerror(errno));
141         return BARNYARD2_FILE_ERROR;
142     }
143 
144     if (bytes_read + spooler->offset != sizeof(Unified2RecordHeader))
145     {
146         if(bytes_read + spooler->offset == 0)
147         {
148             return BARNYARD2_READ_EOF;
149         }
150 
151         spooler->offset += bytes_read;
152         return BARNYARD2_READ_PARTIAL;
153     }
154 
155     DEBUG_WRAP(DebugMessage(DEBUG_LOG,"Header: Type=%u (%u bytes)\n",
156                 ntohl(((Unified2RecordHeader *)spooler->record.header)->type),
157                 ntohl(((Unified2RecordHeader *)spooler->record.header)->length)););
158 
159     spooler->offset = 0;
160     return 0;
161 }
162 
Unified2ReadRecord(void * sph)163 int Unified2ReadRecord(void *sph)
164 {
165     ssize_t             bytes_read;
166     uint32_t            record_type;
167     uint32_t            record_length;
168     Spooler             *spooler = (Spooler *)sph;
169 
170     /* convert once */
171     record_type = ntohl(((Unified2RecordHeader *)spooler->record.header)->type);
172     record_length = ntohl(((Unified2RecordHeader *)spooler->record.header)->length);
173 
174     DEBUG_WRAP(DebugMessage(DEBUG_LOG,"Reading record type=%u (%u bytes)\n",
175                 record_type, record_length););
176 
177     if(!spooler->record.data)
178     {
179         /* SnortAlloc will FatalError if memory can't be assigned */
180         spooler->record.data = SnortAlloc(record_length);
181     }
182 
183     if (spooler->offset < record_length)
184     {
185 #if DEBUG
186         int position = lseek(spooler->fd, 0, SEEK_CUR);
187         DEBUG_WRAP(DebugMessage(DEBUG_LOG,"Record: Reading at byte position %u\n", position););
188 #endif
189         /* in case we don't have it already */
190 
191         bytes_read = read(spooler->fd, spooler->record.data + spooler->offset,
192                     record_length - spooler->offset);
193 
194         if (bytes_read == -1)
195         {
196             LogMessage("ERROR: read error: %s\n", strerror(errno));
197             return BARNYARD2_FILE_ERROR;
198         }
199 
200         if (bytes_read + spooler->offset != record_length)
201         {
202             spooler->offset += bytes_read;
203             return BARNYARD2_READ_PARTIAL;
204         }
205 
206 #ifdef DEBUG
207         switch (record_type)
208         {
209             case UNIFIED2_IDS_EVENT:
210                 Unified2PrintEventRecord((Unified2IDSEvent_legacy *)spooler->record.data);
211                 break;
212             case UNIFIED2_IDS_EVENT_IPV6:
213                 Unified2PrintEvent6Record((Unified2IDSEventIPv6_legacy *)spooler->record.data);
214                 break;
215             case UNIFIED2_PACKET:
216                 Unified2PrintPacketRecord((Unified2Packet *)spooler->record.data);
217                 break;
218             case UNIFIED2_IDS_EVENT_MPLS:
219             case UNIFIED2_IDS_EVENT_IPV6_MPLS:
220             case UNIFIED2_IDS_EVENT_VLAN:
221             case UNIFIED2_IDS_EVENT_IPV6_VLAN:
222             default:
223                 DEBUG_WRAP(DebugMessage(DEBUG_LOG,"No debug available for record type: %u\n", record_type););
224                 break;
225         }
226 #endif
227 
228         spooler->offset = 0;
229 
230         return 0;
231     }
232 
233     return -1;
234 }
235 
Unified2CleanExitFunc(int signal,void * arg)236 void Unified2CleanExitFunc(int signal, void *arg)
237 {
238     DEBUG_WRAP(DebugMessage(DEBUG_LOG,"Unified2CleanExitFunc\n"););
239     return;
240 }
241 
Unified2RestartFunc(int signal,void * arg)242 void Unified2RestartFunc(int signal, void *arg)
243 {
244     DEBUG_WRAP(DebugMessage(DEBUG_LOG,"Unified2RestartFunc\n"););
245     return;
246 }
247 
248 
249 #ifdef DEBUG
Unified2PrintEventCommonRecord(Unified2EventCommon * evt)250 void Unified2PrintEventCommonRecord(Unified2EventCommon *evt)
251 {
252     if(evt == NULL)
253         return;
254 
255     DEBUG_WRAP(DebugMessage(DEBUG_LOG,
256         "Type: Event -------------------------------------------\n"););
257     DEBUG_WRAP(DebugMessage(DEBUG_LOG,
258         "  sensor_id          = %d\n", ntohl(evt->sensor_id)););
259     DEBUG_WRAP(DebugMessage(DEBUG_LOG,
260         "  event_id           = %d\n", ntohl(evt->event_id)););
261     DEBUG_WRAP(DebugMessage(DEBUG_LOG,
262         "  event_second       = %lu\n", ntohl(evt->event_second)););
263     DEBUG_WRAP(DebugMessage(DEBUG_LOG,
264         "  event_microsecond  = %lu\n", ntohl(evt->event_microsecond)););
265     DEBUG_WRAP(DebugMessage(DEBUG_LOG,
266         "  generator_id       = %d\n", ntohl(evt->generator_id)););
267     DEBUG_WRAP(DebugMessage(DEBUG_LOG,
268         "  signature_id       = %d\n", ntohl(evt->signature_id)););
269     DEBUG_WRAP(DebugMessage(DEBUG_LOG,
270         "  signature_revision = %d\n", ntohl(evt->signature_revision)););
271     DEBUG_WRAP(DebugMessage(DEBUG_LOG,
272         "  classification_id  = %d\n", ntohl(evt->classification_id)););
273     DEBUG_WRAP(DebugMessage(DEBUG_LOG,
274         "  priority_id        = %d\n", ntohl(evt->priority_id)););
275 }
276 
Unified2PrintEventRecord(Unified2IDSEvent_legacy * evt)277 void Unified2PrintEventRecord(Unified2IDSEvent_legacy *evt)
278 {
279     char                sip4[INET_ADDRSTRLEN];
280     char                dip4[INET_ADDRSTRLEN];
281 
282     if(evt == NULL)
283         return;
284 
285     Unified2PrintEventCommonRecord((Unified2EventCommon *)evt);
286 
287     inet_ntop(AF_INET, &(evt->ip_source), sip4, INET_ADDRSTRLEN);
288     DEBUG_WRAP(DebugMessage(DEBUG_LOG,
289         "  ip_source          = %s\n", sip4););
290 
291     DEBUG_WRAP(DebugMessage(DEBUG_LOG,
292         "  sport_itype        = %d\n", ntohs(evt->sport_itype)););
293     inet_ntop(AF_INET, &(evt->ip_destination), dip4, INET_ADDRSTRLEN);
294     DEBUG_WRAP(DebugMessage(DEBUG_LOG,
295         "  ip_destination     = %s\n", dip4););
296     DEBUG_WRAP(DebugMessage(DEBUG_LOG,
297         "  dport_icode        = %d\n", ntohs(evt->dport_icode)););
298 
299     DEBUG_WRAP(DebugMessage(DEBUG_LOG,
300         "  ip_protocol        = %d\n", evt->protocol););
301     DEBUG_WRAP(DebugMessage(DEBUG_LOG,
302         "  impact             = %d\n", evt->impact_flag););
303 }
304 
Unified2PrintEvent6Record(Unified2IDSEventIPv6_legacy * evt)305 void Unified2PrintEvent6Record(Unified2IDSEventIPv6_legacy *evt)
306 {
307     char                sip6[INET6_ADDRSTRLEN];
308     char                dip6[INET6_ADDRSTRLEN];
309 
310     if(evt == NULL)
311         return;
312 
313     Unified2PrintEventCommonRecord((Unified2EventCommon *)evt);
314 
315     inet_ntop(AF_INET6, &(evt->ip_source), sip6, INET6_ADDRSTRLEN);
316     DEBUG_WRAP(DebugMessage(DEBUG_LOG,
317         "  ip_source          = %s\n", sip6););
318 
319     DEBUG_WRAP(DebugMessage(DEBUG_LOG,
320         "  sport_itype        = %d\n", ntohs(evt->sport_itype)););
321     inet_ntop(AF_INET6, &(evt->ip_destination), dip6, INET6_ADDRSTRLEN);
322     DEBUG_WRAP(DebugMessage(DEBUG_LOG,
323         "  ip_destination     = %s\n", dip6););
324     DEBUG_WRAP(DebugMessage(DEBUG_LOG,
325         "  dport_icode        = %d\n", ntohs(evt->dport_icode)););
326 
327     DEBUG_WRAP(DebugMessage(DEBUG_LOG,
328         "  ip_protocol        = %d\n", evt->protocol););
329     DEBUG_WRAP(DebugMessage(DEBUG_LOG,
330         "  impact             = %d\n", evt->impact_flag););
331 }
332 
Unified2PrintPacketRecord(Unified2Packet * pkt)333 void Unified2PrintPacketRecord(Unified2Packet *pkt)
334 {
335     if(pkt == NULL)
336         return;
337 
338     DEBUG_WRAP(DebugMessage(DEBUG_LOG,
339         "Type: Packet ------------------------------------------\n"););
340     DEBUG_WRAP(DebugMessage(DEBUG_LOG,
341         "  sensor_id          = %d\n", ntohl(pkt->sensor_id)););
342     DEBUG_WRAP(DebugMessage(DEBUG_LOG,
343         "  event_id           = %d\n", ntohl(pkt->event_id)););
344     DEBUG_WRAP(DebugMessage(DEBUG_LOG,
345         "  event_second       = %lu\n", ntohl(pkt->event_second)););
346     DEBUG_WRAP(DebugMessage(DEBUG_LOG,
347         "  linktype           = %d\n", ntohl(pkt->linktype)););
348     DEBUG_WRAP(DebugMessage(DEBUG_LOG,
349         "  packet_second      = %lu\n", ntohl(pkt->packet_second)););
350     DEBUG_WRAP(DebugMessage(DEBUG_LOG,
351         "  packet_microsecond = %lu\n", ntohl(pkt->packet_microsecond)););
352     DEBUG_WRAP(DebugMessage(DEBUG_LOG,
353         "  packet_length      = %d\n", ntohl(pkt->packet_length)););
354     DEBUG_WRAP(DebugMessage(DEBUG_LOG,
355         "  packet             = %02x %02x %02x %02x\n",pkt->packet_data[1],
356                                                        pkt->packet_data[2],
357                                                        pkt->packet_data[3],
358                                                        pkt->packet_data[4]););
359 
360 }
361 #endif
362 
363