1 /* $Id$ */
2 /*
3 ** Copyright (C) 2002-2009 Sourcefire, Inc.
4 ** Copyright (C) 1998-2002 Martin Roesch <roesch@sourcefire.com>
5 **
6 ** This program is free software; you can redistribute it and/or modify
7 ** it under the terms of the GNU General Public License Version 2 as
8 ** published by the Free Software Foundation. You may not use, modify or
9 ** distribute this program under any other version of the GNU General
10 ** Public License.
11 **
12 ** This program is distributed in the hope that it will be useful,
13 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ** GNU General Public License for more details.
16 **
17 ** You should have received a copy of the GNU General Public License
18 ** along with this program; if not, write to the Free Software
19 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include <sys/types.h>
27 #include <stdlib.h>
28 #include <string.h>
29
30 #ifdef HAVE_STRINGS_H
31 #include <strings.h>
32 #endif
33
34 #ifndef WIN32
35 #include <sys/socket.h>
36 #include <netinet/in.h>
37 #include <arpa/inet.h>
38 #endif /* !WIN32 */
39 #include <errno.h>
40 #include <signal.h>
41
42 #include "log.h"
43 #include "util.h"
44 #include "debug.h"
45
46 #include "barnyard2.h"
47 #include "log_text.h"
48
49 #ifdef SUP_IP6
50 #include "sfutil/sf_ip.h"
51 #endif
52
53 //extern OptTreeNode *otn_tmp; /* global ptr to current rule data */
54
55 /*--------------------------------------------------------------------
56 * utility functions
57 *--------------------------------------------------------------------
58 */
LogTimeStamp(TextLog * log,Packet * p)59 void LogTimeStamp(TextLog* log, Packet* p)
60 {
61 char timestamp[TIMEBUF_SIZE];
62 ts_print((struct timeval*)&p->pkth->ts, timestamp);
63 TextLog_Puts(log, timestamp);
64 }
65
66 /*--------------------------------------------------------------------
67 * alert stuff cloned from log.c
68 *--------------------------------------------------------------------
69 */
70 /*--------------------------------------------------------------------
71 * Function: LogPriorityData()
72 *
73 * Purpose: Prints out priority data associated with an alert
74 *
75 * Arguments: log => pointer to TextLog to write the data to
76 * doNewLine => tack a \n to the end of the line or not (bool)
77 *
78 * Returns: void function
79 *--------------------------------------------------------------------
80 */
LogPriorityData(TextLog * log,uint32_t classification_id,uint32_t priority_id,bool doNewLine)81 void LogPriorityData(TextLog* log, uint32_t classification_id, uint32_t priority_id, bool doNewLine)
82 {
83 ClassType *cn = ClassTypeLookupById(barnyard2_conf, classification_id);
84
85 if ( cn != NULL )
86 {
87 TextLog_Print(
88 log, "[Classification: %s] [Priority: %d] ",
89 cn->name, cn->priority
90 );
91 }
92 else
93 {
94 TextLog_Print(
95 log, "[Classification ID: %d] [Priority ID: %d] ",
96 classification_id, priority_id
97 );
98 }
99 if ( doNewLine )
100 TextLog_NewLine(log);
101 }
102
103 /*--------------------------------------------------------------------
104 * Layer 2 header stuff cloned from log.c
105 *--------------------------------------------------------------------
106 */
107 #ifndef NO_NON_ETHER_DECODER
108 /*--------------------------------------------------------------------
109 * Function: LogTrHeader(TextLog*, Packet*)
110 *
111 * Purpose: Print the packet TokenRing header to the given TextLog
112 *
113 * Arguments: log => pointer to TextLog to print to
114 *
115 * Returns: void function
116 *--------------------------------------------------------------------
117 */
118
LogTrHeader(TextLog * log,Packet * p)119 void LogTrHeader(TextLog* log, Packet* p)
120 {
121
122 TextLog_Print(log, "%X:%X:%X:%X:%X:%X -> ", p->trh->saddr[0],
123 p->trh->saddr[1], p->trh->saddr[2], p->trh->saddr[3],
124 p->trh->saddr[4], p->trh->saddr[5]);
125 TextLog_Print(log, "%X:%X:%X:%X:%X:%X\n", p->trh->daddr[0],
126 p->trh->daddr[1], p->trh->daddr[2], p->trh->daddr[3],
127 p->trh->daddr[4], p->trh->daddr[5]);
128
129 TextLog_Print(log, "access control:0x%X frame control:0x%X\n", p->trh->ac,
130 p->trh->fc);
131 if(!p->trhllc)
132 return;
133 TextLog_Print(log, "DSAP: 0x%X SSAP 0x%X protoID: %X%X%X Ethertype: %X\n",
134 p->trhllc->dsap, p->trhllc->ssap, p->trhllc->protid[0],
135 p->trhllc->protid[1], p->trhllc->protid[2], p->trhllc->ethertype);
136 if(p->trhmr)
137 {
138 TextLog_Print(log, "RIF structure is present:\n");
139 TextLog_Print(log, "bcast: 0x%X length: 0x%X direction: 0x%X largest"
140 "fr. size: 0x%X res: 0x%X\n",
141 TRH_MR_BCAST(p->trhmr), TRH_MR_LEN(p->trhmr),
142 TRH_MR_DIR(p->trhmr), TRH_MR_LF(p->trhmr),
143 TRH_MR_RES(p->trhmr));
144 TextLog_Print(log, "rseg -> %X:%X:%X:%X:%X:%X:%X:%X\n",
145 p->trhmr->rseg[0], p->trhmr->rseg[1], p->trhmr->rseg[2],
146 p->trhmr->rseg[3], p->trhmr->rseg[4], p->trhmr->rseg[5],
147 p->trhmr->rseg[6], p->trhmr->rseg[7]);
148 }
149 }
150 #endif // NO_NON_ETHER_DECODER
151
152 /*--------------------------------------------------------------------
153 * Function: LogEthHeader()
154 *
155 * Purpose: Print the packet Ethernet header to the given TextLog
156 *
157 * Arguments: log => pointer to TextLog to print to
158 *
159 * Returns: void function
160 *--------------------------------------------------------------------
161 */
LogEthHeader(TextLog * log,Packet * p)162 static void LogEthHeader(TextLog* log, Packet* p)
163 {
164 /* src addr */
165 TextLog_Print(log, "%X:%X:%X:%X:%X:%X -> ", p->eh->ether_src[0],
166 p->eh->ether_src[1], p->eh->ether_src[2], p->eh->ether_src[3],
167 p->eh->ether_src[4], p->eh->ether_src[5]);
168
169 /* dest addr */
170 TextLog_Print(log, "%X:%X:%X:%X:%X:%X ", p->eh->ether_dst[0],
171 p->eh->ether_dst[1], p->eh->ether_dst[2], p->eh->ether_dst[3],
172 p->eh->ether_dst[4], p->eh->ether_dst[5]);
173
174 /* protocol and pkt size */
175 TextLog_Print(log, "type:0x%X len:0x%X\n", ntohs(p->eh->ether_type), p->pkth->len);
176 }
177
178 #ifdef MPLS
LogMPLSHeader(TextLog * log,Packet * p)179 static void LogMPLSHeader(TextLog* log, Packet* p)
180 {
181
182 TextLog_Print(log,"label:0x%05X exp:0x%X bos:0x%X ttl:0x%X\n",
183 p->mplsHdr.label, p->mplsHdr.exp, p->mplsHdr.bos, p->mplsHdr.ttl);
184 }
185 #endif
186 #ifndef NO_NON_ETHER_DECODER
187 /*--------------------------------------------------------------------
188 * Function: LogSLLHeader(TextLog* )
189 *
190 * Purpose: Print the packet SLL (fake) header to the given TextLog
191 * (piece partly is borrowed from tcpdump :))
192 *
193 * Arguments: log => pointer to TextLog to print to
194 *
195 * Returns: void function
196 *--------------------------------------------------------------------
197 */
198 #ifdef DLT_LINUX_SLL
LogSLLHeader(TextLog * log,Packet * p)199 static void LogSLLHeader(TextLog* log, Packet* p)
200 {
201 switch (ntohs(p->sllh->sll_pkttype)) {
202 case LINUX_SLL_HOST:
203 TextLog_Puts(log, "< ");
204 break;
205 case LINUX_SLL_BROADCAST:
206 TextLog_Puts(log, "B ");
207 break;
208 case LINUX_SLL_MULTICAST:
209 TextLog_Puts(log, "M ");
210 break;
211 case LINUX_SLL_OTHERHOST:
212 TextLog_Puts(log, "P ");
213 break;
214 case LINUX_SLL_OUTGOING:
215 TextLog_Puts(log, "> ");
216 break;
217 default:
218 TextLog_Puts(log, "? ");
219 break;
220 }
221
222 /* mac addr */
223 TextLog_Print(log, "l/l len: %i l/l type: 0x%X %X:%X:%X:%X:%X:%X\n",
224 htons(p->sllh->sll_halen), ntohs(p->sllh->sll_hatype),
225 p->sllh->sll_addr[0], p->sllh->sll_addr[1], p->sllh->sll_addr[2],
226 p->sllh->sll_addr[3], p->sllh->sll_addr[4], p->sllh->sll_addr[5]);
227
228 /* protocol and pkt size */
229 TextLog_Print(log, "pkt type:0x%X proto: 0x%X len:0x%X\n",
230 ntohs(p->sllh->sll_pkttype),
231 ntohs(p->sllh->sll_protocol), p->pkth->len);
232 }
233 #endif
234
235 /*--------------------------------------------------------------------
236 * Function: LogWifiHeader(TextLog* )
237 *
238 * Purpose: Print the packet 802.11 header to the given TextLog
239 *
240 * Arguments: log => pointer to TextLog to print to
241 *
242 * Returns: void function
243 *--------------------------------------------------------------------
244 */
LogWifiHeader(TextLog * log,Packet * p)245 static void LogWifiHeader(TextLog* log, Packet * p)
246 {
247 /* This assumes we are printing a data packet, could be changed
248 to print other types as well */
249 const u_char *da = NULL, *sa = NULL, *bssid = NULL, *ra = NULL,
250 *ta = NULL;
251 /* per table 4, IEEE802.11 section 7.2.2 */
252 if ((p->wifih->frame_control & WLAN_FLAG_TODS) &&
253 (p->wifih->frame_control & WLAN_FLAG_FROMDS)) {
254 ra = p->wifih->addr1;
255 ta = p->wifih->addr2;
256 da = p->wifih->addr3;
257 sa = p->wifih->addr4;
258 }
259 else if (p->wifih->frame_control & WLAN_FLAG_TODS) {
260 bssid = p->wifih->addr1;
261 sa = p->wifih->addr2;
262 da = p->wifih->addr3;
263 }
264 else if (p->wifih->frame_control & WLAN_FLAG_FROMDS) {
265 da = p->wifih->addr1;
266 bssid = p->wifih->addr2;
267 sa = p->wifih->addr3;
268 }
269 else {
270 da = p->wifih->addr1;
271 sa = p->wifih->addr2;
272 bssid = p->wifih->addr3;
273 }
274
275 /* DO this switch to provide additional info on the type */
276 switch(p->wifih->frame_control & 0x00ff)
277 {
278 case WLAN_TYPE_MGMT_BEACON:
279 TextLog_Puts(log, "Beacon ");
280 break;
281 /* management frames */
282 case WLAN_TYPE_MGMT_ASREQ:
283 TextLog_Puts(log, "Assoc. Req. ");
284 break;
285 case WLAN_TYPE_MGMT_ASRES:
286 TextLog_Puts(log, "Assoc. Resp. ");
287 break;
288 case WLAN_TYPE_MGMT_REREQ:
289 TextLog_Puts(log, "Reassoc. Req. ");
290 break;
291 case WLAN_TYPE_MGMT_RERES:
292 TextLog_Puts(log, "Reassoc. Resp. ");
293 break;
294 case WLAN_TYPE_MGMT_PRREQ:
295 TextLog_Puts(log, "Probe Req. ");
296 break;
297 case WLAN_TYPE_MGMT_PRRES:
298 TextLog_Puts(log, "Probe Resp. ");
299 break;
300 case WLAN_TYPE_MGMT_ATIM:
301 TextLog_Puts(log, "ATIM ");
302 break;
303 case WLAN_TYPE_MGMT_DIS:
304 TextLog_Puts(log, "Dissassoc. ");
305 break;
306 case WLAN_TYPE_MGMT_AUTH:
307 TextLog_Puts(log, "Authent. ");
308 break;
309 case WLAN_TYPE_MGMT_DEAUTH:
310 TextLog_Puts(log, "Deauthent. ");
311 break;
312
313 /* Control frames */
314 case WLAN_TYPE_CONT_PS:
315 case WLAN_TYPE_CONT_RTS:
316 case WLAN_TYPE_CONT_CTS:
317 case WLAN_TYPE_CONT_ACK:
318 case WLAN_TYPE_CONT_CFE:
319 case WLAN_TYPE_CONT_CFACK:
320 TextLog_Puts(log, "Control ");
321 break;
322 }
323
324 if (sa != NULL) {
325 TextLog_Print(log, "%X:%X:%X:%X:%X:%X -> ", sa[0],
326 sa[1], sa[2], sa[3], sa[4], sa[5]);
327 }
328 else if (ta != NULL) {
329 TextLog_Print(log, "ta: %X:%X:%X:%X:%X:%X da: ", ta[0],
330 ta[1], ta[2], ta[3], ta[4], ta[5]);
331 }
332
333 TextLog_Print(log, "%X:%X:%X:%X:%X:%X\n", da[0],
334 da[1], da[2], da[3], da[4], da[5]);
335
336 if (bssid != NULL)
337 {
338 TextLog_Print(log, "bssid: %X:%X:%X:%X:%X:%X", bssid[0],
339 bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]);
340 }
341
342 if (ra != NULL) {
343 TextLog_Print(log, " ra: %X:%X:%X:%X:%X:%X", ra[0],
344 ra[1], ra[2], ra[3], ra[4], ra[5]);
345 }
346 TextLog_Puts(log, " Flags:");
347 if (p->wifih->frame_control & WLAN_FLAG_TODS) TextLog_Puts(log," ToDs");
348 if (p->wifih->frame_control & WLAN_FLAG_TODS) TextLog_Puts(log," FrDs");
349 if (p->wifih->frame_control & WLAN_FLAG_FRAG) TextLog_Puts(log," Frag");
350 if (p->wifih->frame_control & WLAN_FLAG_RETRY) TextLog_Puts(log," Re");
351 if (p->wifih->frame_control & WLAN_FLAG_PWRMGMT) TextLog_Puts(log," Pwr");
352 if (p->wifih->frame_control & WLAN_FLAG_MOREDAT) TextLog_Puts(log," MD");
353 if (p->wifih->frame_control & WLAN_FLAG_WEP) TextLog_Puts(log," Wep");
354 if (p->wifih->frame_control & WLAN_FLAG_ORDER) TextLog_Puts(log," Ord");
355 TextLog_NewLine(log);
356 }
357 #endif // NO_NON_ETHER_DECODER
358
359 /*--------------------------------------------------------------------
360 * Function: Log2ndHeader(TextLog* , Packet p)
361 *
362 * Purpose: Log2ndHeader -- prints second layber header info.
363 *
364 * Arguments: log => pointer to TextLog to print to
365 *
366 * Returns: void function
367 *--------------------------------------------------------------------
368 */
Log2ndHeader(TextLog * log,Packet * p)369 void Log2ndHeader(TextLog* log, Packet* p)
370 {
371
372 switch(datalink)
373 {
374 case DLT_EN10MB: /* Ethernet */
375 if(p && p->eh)
376 LogEthHeader(log, p);
377 break;
378 #ifndef NO_NON_ETHER_DECODER
379 #ifdef DLT_IEEE802_11
380 case DLT_IEEE802_11:
381 if(p && p->wifih)
382 LogWifiHeader(log, p);
383 break;
384 #endif
385 case DLT_IEEE802: /* Token Ring */
386 if(p && p->trh)
387 LogTrHeader(log, p);
388 break;
389 #ifdef DLT_LINUX_SLL
390 case DLT_LINUX_SLL:
391 if (p && p->sllh)
392 LogSLLHeader(log, p); /* Linux cooked sockets */
393 break;
394 #endif
395 #endif // NO_NON_ETHER_DECODER
396 default:
397 if (BcLogVerbose())
398 {
399 ErrorMessage("Datalink %i type 2nd layer display is not "
400 "supported\n", datalink);
401 }
402 }
403 }
404
405 /*-------------------------------------------------------------------
406 * IP stuff cloned from log.c
407 *-------------------------------------------------------------------
408 */
LogIpOptions(TextLog * log,Packet * p)409 static void LogIpOptions(TextLog* log, Packet * p)
410 {
411 int i;
412 int j;
413 u_long init_offset;
414 u_long print_offset;
415
416 init_offset = TextLog_Tell(log);
417
418 if(!p->ip_option_count || p->ip_option_count > 40)
419 return;
420
421 TextLog_Print(log, "IP Options (%d) => ", p->ip_option_count);
422
423 for(i = 0; i < (int) p->ip_option_count; i++)
424 {
425 print_offset = TextLog_Tell(log);
426
427 if((print_offset - init_offset) > 60)
428 {
429 TextLog_Puts(log, "\nIP Options => ");
430 init_offset = TextLog_Tell(log);
431 }
432
433 switch(p->ip_options[i].code)
434 {
435 case IPOPT_RR:
436 TextLog_Puts(log, "RR ");
437 break;
438
439 case IPOPT_EOL:
440 TextLog_Puts(log, "EOL ");
441 break;
442
443 case IPOPT_NOP:
444 TextLog_Puts(log, "NOP ");
445 break;
446
447 case IPOPT_TS:
448 TextLog_Puts(log, "TS ");
449 break;
450
451 case IPOPT_ESEC:
452 TextLog_Puts(log, "ESEC ");
453 break;
454
455 case IPOPT_SECURITY:
456 TextLog_Puts(log, "SEC ");
457 break;
458
459 case IPOPT_LSRR:
460 case IPOPT_LSRR_E:
461 TextLog_Puts(log, "LSRR ");
462 break;
463
464 case IPOPT_SATID:
465 TextLog_Puts(log, "SID ");
466 break;
467
468 case IPOPT_SSRR:
469 TextLog_Puts(log, "SSRR ");
470 break;
471
472 case IPOPT_RTRALT:
473 TextLog_Puts(log, "RTRALT ");
474 break;
475
476 default:
477 TextLog_Print(log, "Opt %d: ", p->ip_options[i].code);
478
479 if(p->ip_options[i].len)
480 {
481 for(j = 0; j < p->ip_options[i].len; j++)
482 {
483 if (p->ip_options[i].data)
484 TextLog_Print(log, "%02X", p->ip_options[i].data[j]);
485 else
486 TextLog_Print(log, "%02X", 0);
487
488 if((j % 2) == 0)
489 TextLog_Putc(log, ' ');
490 }
491 }
492 break;
493 }
494 }
495 TextLog_NewLine(log);
496 }
497
498 /*--------------------------------------------------------------------
499 * Function: LogIPHeader(TextLog* )
500 *
501 * Purpose: Dump the IP header info to the given TextLog
502 *
503 * Arguments: log => TextLog to print to
504 *
505 * Returns: void function
506 *--------------------------------------------------------------------
507 */
LogIPHeader(TextLog * log,Packet * p)508 void LogIPHeader(TextLog* log, Packet * p)
509 {
510 if(!IPH_IS_VALID(p))
511 {
512 TextLog_Print(log, "IP header truncated\n");
513 return;
514 }
515
516 if(p->frag_flag)
517 {
518 /* just print the straight IP header */
519 TextLog_Puts(log, inet_ntoa(GET_SRC_ADDR(p)));
520 TextLog_Puts(log, " -> ");
521 TextLog_Puts(log, inet_ntoa(GET_DST_ADDR(p)));
522 }
523 else
524 {
525 if(GET_IPH_PROTO(p) != IPPROTO_TCP && GET_IPH_PROTO(p) != IPPROTO_UDP)
526 {
527 /* just print the straight IP header */
528 TextLog_Puts(log, inet_ntoa(GET_SRC_ADDR(p)));
529 TextLog_Puts(log, " -> ");
530 TextLog_Puts(log, inet_ntoa(GET_DST_ADDR(p)));
531 }
532 else
533 {
534 if (!BcObfuscate())
535 {
536 /* print the header complete with port information */
537 TextLog_Puts(log, inet_ntoa(GET_SRC_ADDR(p)));
538 TextLog_Print(log, ":%d -> ", p->sp);
539 TextLog_Puts(log, inet_ntoa(GET_DST_ADDR(p)));
540 TextLog_Print(log, ":%d", p->dp);
541 }
542 else
543 {
544 /* print the header complete with port information */
545 if(IS_IP4(p))
546 TextLog_Print(log, "xxx.xxx.xxx.xxx:%d -> xxx.xxx.xxx.xxx:%d", p->sp, p->dp);
547 else if(IS_IP6(p))
548 TextLog_Print(log, "x:x:x:x:x:x:x:x:%d -> x:x:x:x:x:x:x:x:%d", p->sp, p->dp);
549 }
550 }
551 }
552
553 if(!BcOutputDataLink())
554 {
555 TextLog_NewLine(log);
556 }
557 else
558 {
559 TextLog_Putc(log, ' ');
560 }
561
562 TextLog_Print(log, "%s TTL:%u TOS:0x%X ID:%u IpLen:%u DgmLen:%u",
563 protocol_names[GET_IPH_PROTO(p)],
564 GET_IPH_TTL(p),
565 GET_IPH_TOS(p),
566 IS_IP6(p) ? ntohl(GET_IPH_ID(p)) : ntohs((uint16_t)GET_IPH_ID(p)),
567 GET_IPH_HLEN(p) << 2,
568 GET_IP_DGMLEN(p));
569
570 /* print the reserved bit if it's set */
571 if((uint8_t)((ntohs(GET_IPH_OFF(p)) & 0x8000) >> 15) == 1)
572 TextLog_Puts(log, " RB");
573
574 /* printf more frags/don't frag bits */
575 if((uint8_t)((ntohs(GET_IPH_OFF(p)) & 0x4000) >> 14) == 1)
576 TextLog_Puts(log, " DF");
577
578 if((uint8_t)((ntohs(GET_IPH_OFF(p)) & 0x2000) >> 13) == 1)
579 TextLog_Puts(log, " MF");
580
581 TextLog_NewLine(log);
582
583 /* print IP options */
584 if(p->ip_option_count != 0)
585 {
586 LogIpOptions(log, p);
587 }
588
589 /* print fragment info if necessary */
590 if(p->frag_flag)
591 {
592 TextLog_Print(log, "Frag Offset: 0x%04X Frag Size: 0x%04X\n",
593 (p->frag_offset & 0x1FFF),
594 GET_IP_PAYLEN(p));
595 }
596 }
597
598 /*-------------------------------------------------------------------
599 * TCP stuff cloned from log.c
600 *-------------------------------------------------------------------
601 */
LogTcpOptions(TextLog * log,Packet * p)602 static void LogTcpOptions(TextLog* log, Packet * p)
603 {
604 int i;
605 int j;
606 u_char tmp[5];
607 u_long init_offset;
608 u_long print_offset;
609
610 init_offset = TextLog_Tell(log);
611
612 TextLog_Print(log, "TCP Options (%d) => ", p->tcp_option_count);
613
614 if(p->tcp_option_count > 40 || !p->tcp_option_count)
615 return;
616
617 for(i = 0; i < (int) p->tcp_option_count; i++)
618 {
619 print_offset = TextLog_Tell(log);
620 /**
621 if((print_offset - init_offset) > 60)
622 {
623 TextLog_Puts(log, "\nTCP Options => ");
624 init_offset = TextLog_Tell(log);
625 }
626 **/
627 switch(p->tcp_options[i].code)
628 {
629 case TCPOPT_MAXSEG:
630 memset((char*)tmp, 0, sizeof(tmp));
631 TextLog_Puts(log, "MSS: ");
632 if (p->tcp_options[i].data)
633 memcpy(tmp, p->tcp_options[i].data, 2);
634 TextLog_Print(log, "%u ", EXTRACT_16BITS(tmp));
635 break;
636
637 case TCPOPT_EOL:
638 TextLog_Puts(log, "EOL ");
639 break;
640
641 case TCPOPT_NOP:
642 TextLog_Puts(log, "NOP ");
643 break;
644
645 case TCPOPT_WSCALE:
646 if (p->tcp_options[i].data)
647 TextLog_Print(log, "WS: %u ", p->tcp_options[i].data[0]);
648 else
649 TextLog_Print(log, "WS: %u ", 0);
650 break;
651 case TCPOPT_SACK:
652 memset((char*)tmp, 0, sizeof(tmp));
653 if (p->tcp_options[i].data && (p->tcp_options[i].len >= 2))
654 memcpy(tmp, p->tcp_options[i].data, 2);
655 TextLog_Print(log, "Sack: %u@", EXTRACT_16BITS(tmp));
656 memset((char*)tmp, 0, sizeof(tmp));
657 if (p->tcp_options[i].data && (p->tcp_options[i].len >= 4))
658 memcpy(tmp, (p->tcp_options[i].data) + 2, 2);
659 TextLog_Print(log, "%u ", EXTRACT_16BITS(tmp));
660 break;
661
662 case TCPOPT_SACKOK:
663 TextLog_Puts(log, "SackOK ");
664 break;
665
666 case TCPOPT_ECHO:
667 memset((char*)tmp, 0, sizeof(tmp));
668 if (p->tcp_options[i].data)
669 memcpy(tmp, p->tcp_options[i].data, 4);
670 TextLog_Print(log, "Echo: %u ", EXTRACT_32BITS(tmp));
671 break;
672
673 case TCPOPT_ECHOREPLY:
674 memset((char*)tmp, 0, sizeof(tmp));
675 if (p->tcp_options[i].data)
676 memcpy(tmp, p->tcp_options[i].data, 4);
677 TextLog_Print(log, "Echo Rep: %u ", EXTRACT_32BITS(tmp));
678 break;
679
680 case TCPOPT_TIMESTAMP:
681 memset((char*)tmp, 0, sizeof(tmp));
682 if (p->tcp_options[i].data)
683 memcpy(tmp, p->tcp_options[i].data, 4);
684 TextLog_Print(log, "TS: %u ", EXTRACT_32BITS(tmp));
685 memset((char*)tmp, 0, sizeof(tmp));
686 if (p->tcp_options[i].data)
687 memcpy(tmp, (p->tcp_options[i].data) + 4, 4);
688 TextLog_Print(log, "%u ", EXTRACT_32BITS(tmp));
689 break;
690
691 case TCPOPT_CC:
692 memset((char*)tmp, 0, sizeof(tmp));
693 if (p->tcp_options[i].data)
694 memcpy(tmp, p->tcp_options[i].data, 4);
695 TextLog_Print(log, "CC %u ", EXTRACT_32BITS(tmp));
696 break;
697
698 case TCPOPT_CCNEW:
699 memset((char*)tmp, 0, sizeof(tmp));
700 if (p->tcp_options[i].data)
701 memcpy(tmp, p->tcp_options[i].data, 4);
702 TextLog_Print(log, "CCNEW: %u ", EXTRACT_32BITS(tmp));
703 break;
704
705 case TCPOPT_CCECHO:
706 memset((char*)tmp, 0, sizeof(tmp));
707 if (p->tcp_options[i].data)
708 memcpy(tmp, p->tcp_options[i].data, 4);
709 TextLog_Print(log, "CCECHO: %u ", EXTRACT_32BITS(tmp));
710 break;
711
712 default:
713 if(p->tcp_options[i].len)
714 {
715 TextLog_Print(log, "Opt %d (%d): ", p->tcp_options[i].code,
716 (int) p->tcp_options[i].len);
717
718 for(j = 0; j < p->tcp_options[i].len; j++)
719 {
720 if (p->tcp_options[i].data)
721 TextLog_Print(log, "%02X", p->tcp_options[i].data[j]);
722 else
723 TextLog_Print(log, "%02X", 0);
724
725 if ((j + 1) % 2 == 0)
726 TextLog_Putc(log, ' ');
727 }
728
729 TextLog_Putc(log, ' ');
730 }
731 else
732 {
733 TextLog_Print(log, "Opt %d ", p->tcp_options[i].code);
734 }
735 break;
736 }
737 }
738
739 TextLog_NewLine(log);
740 }
741
742 /*--------------------------------------------------------------------
743 * Function: LogTCPHeader(TextLog* )
744 *
745 * Purpose: Dump the TCP header info to the given TextLog
746 *
747 * Arguments: log => pointer to TextLog to print data to
748 *
749 * Returns: void function
750 *--------------------------------------------------------------------
751 */
LogTCPHeader(TextLog * log,Packet * p)752 void LogTCPHeader(TextLog* log, Packet * p)
753 {
754 char tcpFlags[9];
755
756 if(p->tcph == NULL)
757 {
758 TextLog_Print(log, "TCP header truncated\n");
759 return;
760 }
761 /* print TCP flags */
762 CreateTCPFlagString(p, tcpFlags);
763 TextLog_Puts(log, tcpFlags); /* We don't care about the NULL */
764
765 /* print other TCP info */
766 TextLog_Print(log, " Seq: 0x%lX Ack: 0x%lX Win: 0x%X TcpLen: %d",
767 (u_long) ntohl(p->tcph->th_seq),
768 (u_long) ntohl(p->tcph->th_ack),
769 ntohs(p->tcph->th_win), TCP_OFFSET(p->tcph) << 2);
770
771 if((p->tcph->th_flags & TH_URG) != 0)
772 {
773 TextLog_Print(log, " UrgPtr: 0x%X\n", (uint16_t) ntohs(p->tcph->th_urp));
774 }
775 else
776 {
777 TextLog_NewLine(log);
778 }
779
780 /* dump the TCP options */
781 if(p->tcp_option_count != 0)
782 {
783 LogTcpOptions(log, p);
784 }
785 }
786
787 /*-------------------------------------------------------------------
788 * UDP stuff cloned from log.c
789 *-------------------------------------------------------------------
790 */
791 /*--------------------------------------------------------------------
792 * Function: LogUDPHeader(TextLog* )
793 *
794 * Purpose: Dump the UDP header to the given TextLog
795 *
796 * Arguments: log => pointer to TextLog
797 *
798 * Returns: void function
799 *--------------------------------------------------------------------
800 */
LogUDPHeader(TextLog * log,Packet * p)801 void LogUDPHeader(TextLog* log, Packet* p)
802 {
803
804 if(p->udph == NULL)
805 {
806 TextLog_Print(log, "UDP header truncated\n");
807 return;
808 }
809 /* not much to do here... */
810 TextLog_Print(log, "Len: %d\n", ntohs(p->udph->uh_len) - UDP_HEADER_LEN);
811 }
812
813 /*--------------------------------------------------------------------
814 * ICMP stuff cloned from log.c
815 *--------------------------------------------------------------------
816 */
817 /*--------------------------------------------------------------------
818 * Function: LogEmbeddedICMPHeader(TextLog* , ICMPHdr *)
819 *
820 * Purpose: Prints the 64 bits of the original IP payload in an ICMP packet
821 * that requires it
822 *
823 * Arguments: log => pointer to TextLog
824 * icmph => ICMPHdr struct pointing to original ICMP
825 *
826 * Returns: void function
827 *--------------------------------------------------------------------
828 */
LogEmbeddedICMPHeader(TextLog * log,const ICMPHdr * icmph)829 static void LogEmbeddedICMPHeader(TextLog* log, const ICMPHdr *icmph)
830 {
831 if (log == NULL || icmph == NULL)
832 return;
833
834 TextLog_Print(log, "Type: %d Code: %d Csum: %u",
835 icmph->type, icmph->code, ntohs(icmph->csum));
836
837 switch (icmph->type)
838 {
839 case ICMP_DEST_UNREACH:
840 case ICMP_TIME_EXCEEDED:
841 case ICMP_SOURCE_QUENCH:
842 break;
843
844 case ICMP_PARAMETERPROB:
845 if (icmph->code == 0)
846 TextLog_Print(log, " Ptr: %u", icmph->s_icmp_pptr);
847 break;
848
849 case ICMP_REDIRECT:
850 #ifdef SUP_IP6
851 // XXX-IPv6 "NOT YET IMPLEMENTED - ICMP printing"
852 #else
853 TextLog_Print(log, " New Gwy: %s", inet_ntoa(icmph->s_icmp_gwaddr));
854 #endif
855 break;
856
857 case ICMP_ECHO:
858 case ICMP_ECHOREPLY:
859 case ICMP_TIMESTAMP:
860 case ICMP_TIMESTAMPREPLY:
861 case ICMP_INFO_REQUEST:
862 case ICMP_INFO_REPLY:
863 case ICMP_ADDRESS:
864 case ICMP_ADDRESSREPLY:
865 TextLog_Print(log, " Id: %u SeqNo: %u",
866 ntohs(icmph->s_icmp_id), ntohs(icmph->s_icmp_seq));
867 break;
868
869 case ICMP_ROUTER_ADVERTISE:
870 TextLog_Print(log, " Addrs: %u Size: %u Lifetime: %u",
871 icmph->s_icmp_num_addrs, icmph->s_icmp_wpa,
872 ntohs(icmph->s_icmp_lifetime));
873 break;
874
875 default:
876 break;
877 }
878
879 TextLog_NewLine(log);
880
881 return;
882 }
883
884 /*--------------------------------------------------------------------
885 * Function: LogICMPEmbeddedIP(TextLog* , Packet *)
886 *
887 * Purpose: Prints the original/encapsulated IP header + 64 bits of the
888 * original IP payload in an ICMP packet
889 *
890 * Arguments: log => pointer to TextLog
891 * p => packet struct
892 *
893 * Returns: void function
894 *--------------------------------------------------------------------
895 */
LogICMPEmbeddedIP(TextLog * log,Packet * p)896 static void LogICMPEmbeddedIP(TextLog* log, Packet *p)
897 {
898 Packet op;
899 Packet *orig_p;
900 uint32_t orig_ip_hlen;
901
902 if (log == NULL || p == NULL)
903 return;
904
905 memset((char*)&op, 0, sizeof(op));
906 orig_p = &op;
907
908 orig_p->iph = p->orig_iph;
909 orig_p->tcph = p->orig_tcph;
910 orig_p->udph = p->orig_udph;
911 orig_p->sp = p->orig_sp;
912 orig_p->dp = p->orig_dp;
913 orig_p->icmph = p->orig_icmph;
914 #ifdef SUP_IP6
915 orig_p->iph_api = p->orig_iph_api;
916 orig_p->ip4h = p->orig_ip4h;
917 orig_p->ip6h = p->orig_ip6h;
918 orig_p->family = p->orig_family;
919 #endif
920
921 if(orig_p->iph != NULL)
922 {
923 TextLog_Print(log, "\n** ORIGINAL DATAGRAM DUMP:\n");
924 LogIPHeader(log, orig_p);
925 orig_ip_hlen = IP_HLEN(p->orig_iph) << 2;
926
927 switch(GET_IPH_PROTO(orig_p))
928 {
929 case IPPROTO_TCP:
930 if(orig_p->tcph != NULL)
931 TextLog_Print(log, "Seq: 0x%lX\n",
932 (u_long)ntohl(orig_p->tcph->th_seq));
933 break;
934
935 case IPPROTO_UDP:
936 if(orig_p->udph != NULL)
937 TextLog_Print(log, "Len: %d Csum: %d\n",
938 ntohs(orig_p->udph->uh_len) - UDP_HEADER_LEN,
939 ntohs(orig_p->udph->uh_chk));
940 break;
941
942 case IPPROTO_ICMP:
943 if(orig_p->icmph != NULL)
944 LogEmbeddedICMPHeader(log, orig_p->icmph);
945 break;
946
947 default:
948 TextLog_Print(log, "Protocol: 0x%X (unknown or "
949 "header truncated)", GET_IPH_PROTO(orig_p));
950 break;
951 } /* switch */
952
953 /* if more than 8 bytes of original IP payload sent */
954 if (p->dsize - orig_ip_hlen > 8)
955 {
956 TextLog_Print(log, "(%d more bytes of original packet)\n",
957 p->dsize - orig_ip_hlen - 8);
958 }
959
960 TextLog_Puts(log, "** END OF DUMP");
961 }
962 else
963 {
964 TextLog_Puts(log, "\nORIGINAL DATAGRAM TRUNCATED");
965 }
966 }
967
968 /*--------------------------------------------------------------------
969 * Function: LogICMPHeader(TextLog* )
970 *
971 * Purpose: Print ICMP header
972 *
973 * Arguments: log => pointer to TextLog
974 *
975 * Returns: void function
976 *--------------------------------------------------------------------
977 */
LogICMPHeader(TextLog * log,Packet * p)978 void LogICMPHeader(TextLog* log, Packet * p)
979 {
980 #ifdef SUP_IP6
981 /* 32 digits plus 7 colons and a NULL byte */
982 char buf[8*4 + 7 + 1];
983 #endif
984
985 if(p->icmph == NULL)
986 {
987 TextLog_Puts(log, "ICMP header truncated\n");
988 return;
989 }
990
991 TextLog_Print(log, "Type:%d Code:%d ", p->icmph->type, p->icmph->code);
992
993 switch(p->icmph->type)
994 {
995 case ICMP_ECHOREPLY:
996 TextLog_Print(log, "ID:%d Seq:%d ", ntohs(p->icmph->s_icmp_id),
997 ntohs(p->icmph->s_icmp_seq));
998 TextLog_Puts(log, "ECHO REPLY");
999 break;
1000
1001 case ICMP_DEST_UNREACH:
1002 TextLog_Puts(log, "DESTINATION UNREACHABLE: ");
1003 switch(p->icmph->code)
1004 {
1005 case ICMP_NET_UNREACH:
1006 TextLog_Puts(log, "NET UNREACHABLE");
1007 break;
1008
1009 case ICMP_HOST_UNREACH:
1010 TextLog_Puts(log, "HOST UNREACHABLE");
1011 break;
1012
1013 case ICMP_PROT_UNREACH:
1014 TextLog_Puts(log, "PROTOCOL UNREACHABLE");
1015 break;
1016
1017 case ICMP_PORT_UNREACH:
1018 TextLog_Puts(log, "PORT UNREACHABLE");
1019 break;
1020
1021 case ICMP_FRAG_NEEDED:
1022 TextLog_Print(log, "FRAGMENTATION NEEDED, DF SET\n"
1023 "NEXT LINK MTU: %u",
1024 ntohs(p->icmph->s_icmp_nextmtu));
1025 break;
1026
1027 case ICMP_SR_FAILED:
1028 TextLog_Puts(log, "SOURCE ROUTE FAILED");
1029 break;
1030
1031 case ICMP_NET_UNKNOWN:
1032 TextLog_Puts(log, "NET UNKNOWN");
1033 break;
1034
1035 case ICMP_HOST_UNKNOWN:
1036 TextLog_Puts(log, "HOST UNKNOWN");
1037 break;
1038
1039 case ICMP_HOST_ISOLATED:
1040 TextLog_Puts(log, "HOST ISOLATED");
1041 break;
1042
1043 case ICMP_PKT_FILTERED_NET:
1044 TextLog_Puts(log, "ADMINISTRATIVELY PROHIBITED NETWORK FILTERED");
1045 break;
1046
1047 case ICMP_PKT_FILTERED_HOST:
1048 TextLog_Puts(log, "ADMINISTRATIVELY PROHIBITED HOST FILTERED");
1049 break;
1050
1051 case ICMP_NET_UNR_TOS:
1052 TextLog_Puts(log, "NET UNREACHABLE FOR TOS");
1053 break;
1054
1055 case ICMP_HOST_UNR_TOS:
1056 TextLog_Puts(log, "HOST UNREACHABLE FOR TOS");
1057 break;
1058
1059 case ICMP_PKT_FILTERED:
1060 TextLog_Puts(log, "ADMINISTRATIVELY PROHIBITED,\nPACKET FILTERED");
1061 break;
1062
1063 case ICMP_PREC_VIOLATION:
1064 TextLog_Puts(log, "PREC VIOLATION");
1065 break;
1066
1067 case ICMP_PREC_CUTOFF:
1068 TextLog_Puts(log, "PREC CUTOFF");
1069 break;
1070
1071 default:
1072 TextLog_Puts(log, "UNKNOWN");
1073 break;
1074
1075 }
1076
1077
1078 LogICMPEmbeddedIP(log, p);
1079
1080 break;
1081
1082 case ICMP_SOURCE_QUENCH:
1083 TextLog_Puts(log, "SOURCE QUENCH");
1084
1085 LogICMPEmbeddedIP(log, p);
1086
1087 break;
1088
1089 case ICMP_REDIRECT:
1090 TextLog_Puts(log, "REDIRECT");
1091 switch(p->icmph->code)
1092 {
1093 case ICMP_REDIR_NET:
1094 TextLog_Puts(log, " NET");
1095 break;
1096
1097 case ICMP_REDIR_HOST:
1098 TextLog_Puts(log, " HOST");
1099 break;
1100
1101 case ICMP_REDIR_TOS_NET:
1102 TextLog_Puts(log, " TOS NET");
1103 break;
1104
1105 case ICMP_REDIR_TOS_HOST:
1106 TextLog_Puts(log, " TOS HOST");
1107 break;
1108 }
1109
1110 #ifdef SUP_IP6
1111 /* written this way since inet_ntoa was typedef'ed to use sfip_ntoa
1112 * which requires sfip_t instead of inaddr's. This call to inet_ntoa
1113 * is a rare case that doesn't use sfip_t's. */
1114
1115 // XXX-IPv6 NOT YET IMPLEMENTED - IPV6 addresses technically not supported - need to change ICMP
1116
1117 /* no inet_ntop in Windows */
1118 sfip_raw_ntop(AF_INET, (const void *)(&p->icmph->s_icmp_gwaddr.s_addr),
1119 buf, sizeof(buf));
1120 TextLog_Print(log, " NEW GW: %s", buf);
1121 #else
1122 TextLog_Print(log, " NEW GW: %s", inet_ntoa(p->icmph->s_icmp_gwaddr));
1123 #endif
1124
1125 LogICMPEmbeddedIP(log, p);
1126
1127 break;
1128
1129 case ICMP_ECHO:
1130 TextLog_Print(log, "ID:%d Seq:%d ", ntohs(p->icmph->s_icmp_id),
1131 ntohs(p->icmph->s_icmp_seq));
1132 TextLog_Puts(log, "ECHO");
1133 break;
1134
1135 case ICMP_ROUTER_ADVERTISE:
1136 TextLog_Print(log, "ROUTER ADVERTISMENT: "
1137 "Num addrs: %d Addr entry size: %d Lifetime: %u",
1138 p->icmph->s_icmp_num_addrs, p->icmph->s_icmp_wpa,
1139 ntohs(p->icmph->s_icmp_lifetime));
1140 break;
1141
1142 case ICMP_ROUTER_SOLICIT:
1143 TextLog_Puts(log, "ROUTER SOLICITATION");
1144 break;
1145
1146 case ICMP_TIME_EXCEEDED:
1147 TextLog_Puts(log, "TTL EXCEEDED");
1148 switch(p->icmph->code)
1149 {
1150 case ICMP_TIMEOUT_TRANSIT:
1151 TextLog_Puts(log, " IN TRANSIT");
1152 break;
1153
1154 case ICMP_TIMEOUT_REASSY:
1155 TextLog_Puts(log, " TIME EXCEEDED IN FRAG REASSEMBLY");
1156 break;
1157 }
1158
1159 LogICMPEmbeddedIP(log, p);
1160
1161 break;
1162
1163 case ICMP_PARAMETERPROB:
1164 TextLog_Puts(log, "PARAMETER PROBLEM");
1165 switch(p->icmph->code)
1166 {
1167 case ICMP_PARAM_BADIPHDR:
1168 TextLog_Print(log, ": BAD IP HEADER BYTE %u",
1169 p->icmph->s_icmp_pptr);
1170 break;
1171
1172 case ICMP_PARAM_OPTMISSING:
1173 TextLog_Puts(log, ": OPTION MISSING");
1174 break;
1175
1176 case ICMP_PARAM_BAD_LENGTH:
1177 TextLog_Puts(log, ": BAD LENGTH");
1178 break;
1179 }
1180
1181 LogICMPEmbeddedIP(log, p);
1182
1183 break;
1184
1185 case ICMP_TIMESTAMP:
1186 TextLog_Print(log, "ID: %u Seq: %u TIMESTAMP REQUEST",
1187 ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq));
1188 break;
1189
1190 case ICMP_TIMESTAMPREPLY:
1191 TextLog_Print(log, "ID: %u Seq: %u TIMESTAMP REPLY:\n"
1192 "Orig: %u Rtime: %u Ttime: %u",
1193 ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq),
1194 p->icmph->s_icmp_otime, p->icmph->s_icmp_rtime,
1195 p->icmph->s_icmp_ttime);
1196 break;
1197
1198 case ICMP_INFO_REQUEST:
1199 TextLog_Print(log, "ID: %u Seq: %u INFO REQUEST",
1200 ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq));
1201 break;
1202
1203 case ICMP_INFO_REPLY:
1204 TextLog_Print(log, "ID: %u Seq: %u INFO REPLY",
1205 ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq));
1206 break;
1207
1208 case ICMP_ADDRESS:
1209 TextLog_Print(log, "ID: %u Seq: %u ADDRESS REQUEST",
1210 ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq));
1211 break;
1212
1213 case ICMP_ADDRESSREPLY:
1214 TextLog_Print(log, "ID: %u Seq: %u ADDRESS REPLY: 0x%08X",
1215 ntohs(p->icmph->s_icmp_id), ntohs(p->icmph->s_icmp_seq),
1216 (u_int) ntohl(p->icmph->s_icmp_mask));
1217 break;
1218
1219 default:
1220 TextLog_Puts(log, "UNKNOWN");
1221
1222 break;
1223 }
1224
1225 TextLog_NewLine(log);
1226
1227 }
1228
1229 /*--------------------------------------------------------------------
1230 * reference stuff cloned from signature.c
1231 *--------------------------------------------------------------------
1232 */
1233 /* print a reference node */
LogReference(TextLog * log,ReferenceNode * refNode)1234 static void LogReference(TextLog* log, ReferenceNode *refNode)
1235 {
1236 if(refNode)
1237 {
1238 if(refNode->system)
1239 {
1240 if(refNode->system->url)
1241 TextLog_Print(log, "[Xref => %s%s]", refNode->system->url,
1242 refNode->id);
1243 else
1244 TextLog_Print(log, "[Xref => %s %s]", refNode->system->name,
1245 refNode->id);
1246 }
1247 else
1248 {
1249 TextLog_Print(log, "[Xref => %s]", refNode->id);
1250 }
1251 }
1252 return;
1253 }
1254
1255 /*
1256 * Function: LogXrefs(TextLog* )
1257 *
1258 * Purpose: Prints out cross reference data associated with an alert
1259 *
1260 * Arguments: log => pointer to TextLog to write the data to
1261 * doNewLine => tack a \n to the end of the line or not (bool)
1262 *
1263 * Returns: void function
1264 */
LogXrefs(TextLog * log,SigNode * sn,int doNewLine)1265 void LogXrefs(TextLog* log, SigNode *sn, int doNewLine)
1266 {
1267 ReferenceNode *refNode = NULL;
1268
1269 if(sn != NULL)
1270 {
1271 refNode = sn->refs;
1272
1273 while(refNode != NULL)
1274 {
1275 LogReference(log, refNode);
1276 refNode = refNode->next;
1277
1278 /* on the last loop through, print a newline in
1279 Full mode */
1280 if(doNewLine && (refNode == NULL))
1281 TextLog_NewLine(log);
1282 }
1283 }
1284 }
1285
1286 /*--------------------------------------------------------------------
1287 * payload stuff cloned from log.c
1288 *--------------------------------------------------------------------
1289 */
1290 /*--------------------------------------------------------------------
1291 * Function: LogCharData(TextLog*, char*, int)
1292 *
1293 * Purpose: Dump the printable ASCII data from a packet
1294 *
1295 * Arguments: log => ptr to TextLog to print to
1296 * data => pointer to buffer data
1297 * len => length of data buffer
1298 *
1299 * Returns: void function
1300 *--------------------------------------------------------------------
1301 */
LogCharData(TextLog * log,char * data,int len)1302 static void LogCharData(TextLog* log, char *data, int len)
1303 {
1304 const char* pb = data;
1305 const char* end = data + len;
1306 int lineCount = 0;
1307
1308 if ( !data )
1309 {
1310 return;
1311 }
1312
1313 while ( pb < end )
1314 {
1315 if ( *pb > 0x1F && *pb < 0x7F)
1316 { /* printable */
1317 TextLog_Putc(log, *pb);
1318 }
1319 else
1320 { /* not printable */
1321 TextLog_Putc(log, '.');
1322 }
1323
1324 if ( ++lineCount == 64 )
1325 {
1326 TextLog_Putc(log, ' ');
1327 TextLog_NewLine(log);
1328 lineCount = 0;
1329 }
1330 pb++;
1331 }
1332 /* slam a \n on the back */
1333 TextLog_Putc(log, ' ');
1334 TextLog_NewLine(log);
1335 TextLog_Putc(log, ' ');
1336 }
1337
1338 /*
1339 * Function: LogNetData(TextLog*, u_char *,int)
1340 *
1341 * Purpose: Do a side by side dump of a buffer, hex on
1342 * the left, decoded ASCII on the right.
1343 *
1344 * Arguments: log => ptr to TextLog to print to
1345 * data => pointer to buffer data
1346 * len => length of data buffer
1347 *
1348 * Returns: void function
1349 */
1350 #define BYTES_PER_FRAME 16
1351 /* middle of packet:"41 02 43 04 45 06 47 08 49 0A 4B 0C 4D 0E 4F 0F A.C.E.G.I.K.M.O."*/
1352 /* at end of packet:"41 02 43 04 45 06 47 08 A.C.E.G."*/
1353 static char* pad3 = " ";
1354
LogNetData(TextLog * log,const u_char * data,const int len)1355 static void LogNetData (TextLog* log, const u_char* data, const int len)
1356 {
1357 const u_char* pb = data;
1358 const u_char* end = data + len;
1359
1360 int offset = 0;
1361 char conv[] = "0123456789ABCDEF"; /* xlation lookup table */
1362
1363 if ( !len )
1364 {
1365 TextLog_NewLine(log);
1366 return;
1367 }
1368 if ( !data )
1369 {
1370 TextLog_Print(log, "Got NULL ptr in LogNetData()\n");
1371 return;
1372 }
1373
1374 if ( len > IP_MAXPACKET )
1375 {
1376 if (BcLogVerbose())
1377 {
1378 TextLog_Print(
1379 log, "Got bogus buffer length (%d) for LogNetData, "
1380 "defaulting to %d bytes!\n", len, BYTES_PER_FRAME
1381 );
1382 }
1383 end = data + BYTES_PER_FRAME;
1384 }
1385
1386 /* loop thru the whole buffer */
1387 while ( pb < end )
1388 {
1389 int i = 0;
1390
1391 if (BcVerboseByteDump())
1392 {
1393 TextLog_Print(log, "0x%04X: ", offset);
1394 offset += BYTES_PER_FRAME;
1395 }
1396 /* process one frame */
1397 /* first print the binary as ascii hex */
1398 for (i = 0; i < BYTES_PER_FRAME && pb+i < end; i++)
1399 {
1400 char b = pb[i];
1401 TextLog_Putc(log, conv[(b & 0xFF) >> 4]);
1402 TextLog_Putc(log, conv[(b & 0xFF) & 0x0F]);
1403 TextLog_Putc(log, ' ');
1404 }
1405 /* print ' ' past end of packet and before ascii */
1406 TextLog_Puts(log, pad3+(3*i));
1407
1408 /* then print the actual ascii chars */
1409 /* or a '.' for control chars */
1410 for (i = 0; i < BYTES_PER_FRAME && pb+i < end; i++)
1411 {
1412 char b = pb[i];
1413
1414 if ( b > 0x1F && b < 0x7F)
1415 TextLog_Putc(log, (char)(b & 0xFF));
1416 else
1417 TextLog_Putc(log, '.');
1418 }
1419 pb += BYTES_PER_FRAME;
1420 TextLog_NewLine(log);
1421 }
1422 TextLog_NewLine(log);
1423 }
1424
1425 /*--------------------------------------------------------------------
1426 * Function: LogIPPkt(TextLog*, int, Packet *)
1427 *
1428 * Purpose: Dump the packet to the given TextLog
1429 *
1430 * Arguments: log => pointer to print data to
1431 * type => packet protocol
1432 * p => pointer to decoded packet struct
1433 *
1434 * Returns: void function
1435 *--------------------------------------------------------------------
1436 */
1437
1438 #ifdef SUP_IP6
1439 #define DATA_PTR(p) \
1440 ((u_char*)p->iph + (GET_IPH_HLEN(p) << 2))
1441 #define DATA_LEN(p) \
1442 (p->actual_ip_len - (GET_IPH_HLEN(p) << 2))
1443 #else
1444 #define DATA_PTR(p) \
1445 ((u_char *)p->iph + (IP_HLEN(p->iph) << 2))
1446 #define DATA_LEN(p) \
1447 (p->actual_ip_len - (IP_HLEN(p->iph) << 2))
1448 #endif
1449
1450 #define SEPARATOR \
1451 "=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+"
1452
LogIPPkt(TextLog * log,int type,Packet * p)1453 void LogIPPkt(TextLog* log, int type, Packet * p)
1454 {
1455 DEBUG_WRAP(DebugMessage(DEBUG_LOG, "LogIPPkt type = %d\n", type););
1456
1457 /* dump the timestamp */
1458 LogTimeStamp(log, p);
1459
1460 /* dump the ethernet header if we're doing that sort of thing */
1461 if (BcOutputDataLink())
1462 {
1463 Log2ndHeader(log, p);
1464 }
1465
1466 #ifdef MPLS
1467 if(p->mpls)
1468 {
1469 LogMPLSHeader(log, p);
1470 }
1471 #endif
1472 /* etc */
1473 LogIPHeader(log, p);
1474
1475 /* if this isn't a fragment, print the other header info */
1476 if ( !p->frag_flag )
1477 {
1478 switch (GET_IPH_PROTO(p))
1479 {
1480 case IPPROTO_TCP:
1481 if ( p->tcph != NULL )
1482
1483 {
1484 LogTCPHeader(log, p);
1485 }
1486 else
1487 {
1488 LogNetData(log, DATA_PTR(p), DATA_LEN(p));
1489 }
1490 break;
1491
1492 case IPPROTO_UDP:
1493 if ( p->udph != NULL )
1494 {
1495 LogUDPHeader(log, p);
1496 }
1497 else
1498 {
1499 LogNetData(log, DATA_PTR(p), DATA_LEN(p));
1500 }
1501
1502 break;
1503
1504 case IPPROTO_ICMP:
1505 if ( p->icmph != NULL )
1506 {
1507 LogICMPHeader(log, p);
1508 }
1509 else
1510 {
1511 LogNetData(log, DATA_PTR(p), GET_IP_PAYLEN(p));
1512 }
1513 break;
1514
1515 default:
1516 break;
1517 }
1518 }
1519
1520 /* dump the application layer data */
1521 if (BcOutputAppData() && !BcVerboseByteDump())
1522 {
1523 if (BcOutputCharData())
1524 LogCharData(log, (char*) p->data, p->dsize);
1525 else
1526 LogNetData(log, p->data, p->dsize);
1527 }
1528 else if (BcVerboseByteDump())
1529 {
1530 LogNetData(log, p->pkt, p->pkth->caplen);
1531 }
1532
1533 TextLog_Print(log, "%s\n\n", SEPARATOR);
1534 }
1535
1536 #ifndef NO_NON_ETHER_DECODER
1537 /*--------------------------------------------------------------------
1538 * ARP stuff cloned from log.c
1539 *--------------------------------------------------------------------
1540 */
1541
1542 #ifndef SUP_IP6
1543 static unsigned char ezero[6]; /* crap for ARP */
1544 #endif
1545
LogArpHeader(TextLog * log,Packet * p)1546 void LogArpHeader(TextLog* log, Packet * p)
1547 {
1548 #ifdef SUP_IP6
1549 // XXX-IPv6 "NOT YET IMPLEMENTED - printing ARP header"
1550 #else
1551 struct in_addr ip_addr;
1552 const uint8_t *mac_src = NULL;
1553 const uint8_t *mac_dst = NULL;
1554
1555 memset((struct in_addr *) &ip_addr, 0, sizeof(struct in_addr));
1556
1557 /* determine what to use as MAC src and dst */
1558 if (p->eh != NULL)
1559 {
1560 mac_src = p->eh->ether_src;
1561 mac_dst = p->eh->ether_dst;
1562 } /* per table 4, 802.11 section 7.2.2 */
1563 else if (p->wifih != NULL &&
1564 (p->wifih->frame_control & WLAN_FLAG_FROMDS))
1565 {
1566 mac_src = p->wifih->addr3;
1567 mac_dst = p->wifih->addr2;
1568 }
1569 else if (p->wifih != NULL &&
1570 (p->wifih->frame_control & WLAN_FLAG_TODS))
1571 {
1572 mac_src = p->wifih->addr2;
1573 mac_dst = p->wifih->addr3;
1574 }
1575 else if (p->wifih != NULL)
1576 {
1577 mac_src = p->wifih->addr2;
1578 mac_dst = p->wifih->addr1;
1579 }
1580
1581 /*
1582 * if these are null this function will break, exit until
1583 * someone writes a function for it...
1584 */
1585 if(mac_src == NULL || mac_dst == NULL)
1586 {
1587 return;
1588 }
1589
1590 /* dump the timestamp */
1591 LogTimeStamp(log, p);
1592
1593 if(ntohs(p->ah->ea_hdr.ar_pro) != ETHERNET_TYPE_IP)
1594 {
1595 TextLog_Print(log, "ARP #%d for protocol #%.4X (%d) hardware #%d (%d)\n",
1596 ntohs(p->ah->ea_hdr.ar_op), ntohs(p->ah->ea_hdr.ar_pro),
1597 p->ah->ea_hdr.ar_pln, ntohs(p->ah->ea_hdr.ar_hrd),
1598 p->ah->ea_hdr.ar_hln);
1599
1600 return;
1601 }
1602
1603 switch(ntohs(p->ah->ea_hdr.ar_op))
1604 {
1605 case ARPOP_REQUEST:
1606 /* bcopy() deprecated, replaced with memmove() */
1607 memmove((void *) &ip_addr, (void *)p->ah->arp_tpa, sizeof(ip_addr));
1608 TextLog_Print(log, "ARP who-has %s", inet_ntoa(ip_addr));
1609
1610 if(memcmp((char *) ezero, (char *) p->ah->arp_tha, 6) != 0)
1611 {
1612 TextLog_Print(log, " (%X:%X:%X:%X:%X:%X)", p->ah->arp_tha[0],
1613 p->ah->arp_tha[1], p->ah->arp_tha[2], p->ah->arp_tha[3],
1614 p->ah->arp_tha[4], p->ah->arp_tha[5]);
1615 }
1616 /* bcopy() deprecated, replaced with memmove() */
1617 memmove((void *) &ip_addr, (void *)p->ah->arp_spa, sizeof(ip_addr));
1618 TextLog_Print(log, " tell %s", inet_ntoa(ip_addr));
1619
1620 if(memcmp((char *) mac_src, (char *) p->ah->arp_sha, 6) != 0)
1621 {
1622 TextLog_Print(log, " (%X:%X:%X:%X:%X:%X)", p->ah->arp_sha[0],
1623 p->ah->arp_sha[1], p->ah->arp_sha[2], p->ah->arp_sha[3],
1624 p->ah->arp_sha[4], p->ah->arp_sha[5]);
1625 }
1626 break;
1627
1628 case ARPOP_REPLY:
1629 /* bcopy() deprecated, replaced with memmove() */
1630 memmove((void *) &ip_addr, (void *)p->ah->arp_spa, sizeof(ip_addr));
1631 TextLog_Print(log, "ARP reply %s", inet_ntoa(ip_addr));
1632
1633 /* print out the originating request if we're on a weirder
1634 * wireless protocol */
1635 if(memcmp((char *) mac_src, (char *) p->ah->arp_sha, 6) != 0)
1636 {
1637 TextLog_Print(log, " (%X:%X:%X:%X:%X:%X)", mac_src[0],
1638 mac_src[1], mac_src[2], mac_src[3],
1639 mac_src[4], mac_src[5]);
1640 }
1641 TextLog_Print(log, " is-at %X:%X:%X:%X:%X:%X", p->ah->arp_sha[0],
1642 p->ah->arp_sha[1], p->ah->arp_sha[2], p->ah->arp_sha[3],
1643 p->ah->arp_sha[4], p->ah->arp_sha[5]);
1644
1645 if(memcmp((char *) mac_dst, (char *) p->ah->arp_tha, 6) != 0)
1646 {
1647 TextLog_Print(log, " (%X:%X:%X:%X:%X:%X)", p->ah->arp_tha[0],
1648 p->ah->arp_tha[1], p->ah->arp_tha[2], p->ah->arp_tha[3],
1649 p->ah->arp_tha[4], p->ah->arp_tha[5]);
1650 }
1651 break;
1652
1653 case ARPOP_RREQUEST:
1654 TextLog_Print(log, "RARP who-is %X:%X:%X:%X:%X:%X tell %X:%X:%X:%X:%X:%X",
1655 p->ah->arp_tha[0], p->ah->arp_tha[1], p->ah->arp_tha[2],
1656 p->ah->arp_tha[3], p->ah->arp_tha[4], p->ah->arp_tha[5],
1657 p->ah->arp_sha[0], p->ah->arp_sha[1], p->ah->arp_sha[2],
1658 p->ah->arp_sha[3], p->ah->arp_sha[4], p->ah->arp_sha[5]);
1659
1660 break;
1661
1662 case ARPOP_RREPLY:
1663 /* bcopy() deprecated, replaced with memmove() */
1664 memmove((void *) &ip_addr, (void *)p->ah->arp_tpa, sizeof(ip_addr));
1665 TextLog_Print(log, "RARP reply %X:%X:%X:%X:%X:%X at %s",
1666 p->ah->arp_tha[0], p->ah->arp_tha[1], p->ah->arp_tha[2],
1667 p->ah->arp_tha[3], p->ah->arp_tha[4], p->ah->arp_tha[5],
1668 inet_ntoa(ip_addr));
1669
1670 break;
1671
1672 default:
1673 TextLog_Print(log, "Unknown operation: %d", ntohs(p->ah->ea_hdr.ar_op));
1674 break;
1675 }
1676
1677 TextLog_Puts(log, "\n\n");
1678 #endif
1679 }
1680 #endif // NO_NON_ETHER_DECODER
1681
1682