1 /*
2 * Copyright (c) 2014-2020, Peter Haag
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * * Neither the name of the author nor the names of its contributors may be
14 * used to endorse or promote products derived from this software without
15 * specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 *
29 */
30
31 #ifdef HAVE_CONFIG_H
32 #include "config.h"
33 #endif
34
35 #ifdef HAVE_FEATURES_H
36 #include <features.h>
37 #endif
38
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <stdarg.h>
42 #include <string.h>
43 #include <errno.h>
44 #include <sys/types.h>
45 #include <unistd.h>
46 #include <assert.h>
47 #include <pthread.h>
48
49 #ifdef HAVE_STDINT_H
50 #include <stdint.h>
51 #endif
52
53 #include <sys/socket.h>
54 #include <netinet/in.h>
55 #include <netinet/in_systm.h>
56 #include <netinet/ip.h>
57 #include <netinet/ip6.h>
58 #include <netinet/tcp.h>
59 #include <netinet/udp.h>
60 #include <netinet/ip_icmp.h>
61 #include <netinet/icmp6.h>
62 #include <arpa/inet.h>
63
64 #include <pcap.h>
65
66 #include "util.h"
67 #include "nfdump.h"
68 #include "nffile.h"
69 #include "bookkeeper.h"
70 #include "collector.h"
71 #include "flowtree.h"
72 #include "ipfrag.h"
73 #include "pcaproc.h"
74 #include "content_dns.h"
75 #include "netflow_pcap.h"
76
77 struct pcap_timeval {
78 int32_t tv_sec; /* seconds */
79 int32_t tv_usec; /* microseconds */
80 };
81
82 struct pcap_sf_pkthdr {
83 struct pcap_timeval ts; /* time stamp */
84 uint32_t caplen; /* length of portion present */
85 uint32_t len; /* length this packet (off wire) */
86 };
87
88 typedef struct vlan_hdr_s {
89 uint16_t vlan_id;
90 uint16_t type;
91 } vlan_hdr_t;
92
93 typedef struct gre_hdr_s {
94 uint16_t flags;
95 uint16_t type;
96 } gre_hdr_t;
97
98 static inline void ProcessTCPFlow(FlowSource_t *fs, struct FlowNode *NewNode );
99
100 static inline void ProcessUDPFlow(FlowSource_t *fs, struct FlowNode *NewNode );
101
102 static inline void ProcessICMPFlow(FlowSource_t *fs, struct FlowNode *NewNode );
103
104 static inline void ProcessOtherFlow(FlowSource_t *fs, struct FlowNode *NewNode );
105
OpenNewPcapFile(pcap_t * p,char * filename,pcapfile_t * pcapfile)106 pcapfile_t *OpenNewPcapFile(pcap_t *p, char *filename, pcapfile_t *pcapfile) {
107
108 if ( !pcapfile ) {
109 // Create struct
110 pcapfile = calloc(1, sizeof(pcapfile_t));
111 if ( !pcapfile ) {
112 LogError("malloc() error in %s line %d: %s", __FILE__, __LINE__, strerror(errno) );
113 return NULL;
114 }
115 pthread_mutex_init(&pcapfile->m_pbuff, NULL);
116 pthread_cond_init(&pcapfile->c_pbuff, NULL);
117
118 pcapfile->data_buffer = malloc(BUFFSIZE);
119 if ( !pcapfile->data_buffer ) {
120 free(pcapfile);
121 LogError("malloc() error in %s line %d: %s", __FILE__, __LINE__, strerror(errno) );
122 return NULL;
123 }
124 pcapfile->alternate_buffer = malloc(BUFFSIZE);
125 if ( !pcapfile->data_buffer ) {
126 free(pcapfile->data_buffer);
127 free(pcapfile);
128 LogError("malloc() error in %s line %d: %s", __FILE__, __LINE__, strerror(errno) );
129 return NULL;
130 }
131 pcapfile->data_ptr = pcapfile->data_buffer;
132 pcapfile->data_size = 0;
133 pcapfile->alternate_size = 0;
134 pcapfile->p = p;
135 }
136
137 if ( filename ) {
138 FILE* pFile = fopen(filename, "wb");
139 if ( !pFile ) {
140 LogError("fopen() error in %s line %d: %s", __FILE__, __LINE__, strerror(errno) );
141 return NULL;
142 }
143 pcapfile->pd = pcap_dump_fopen(p, pFile);
144 if ( !pcapfile->pd ) {
145 LogError("Fatal: pcap_dump_open() failed for file '%s': %s", filename, pcap_geterr(p));
146 return NULL;
147 } else {
148 fflush(pFile);
149 pcapfile->pfd = fileno((FILE *)pFile);
150 return pcapfile;
151 }
152 } else
153 return pcapfile;
154
155 } // End of OpenNewPcapFile
156
ClosePcapFile(pcapfile_t * pcapfile)157 int ClosePcapFile(pcapfile_t *pcapfile) {
158 int err = 0;
159
160 pcap_dump_close(pcapfile->pd);
161 pcapfile->pfd = -1;
162
163 return err;
164
165 } // End of ClosePcapFile
166
RotateFile(pcapfile_t * pcapfile,time_t t_CloseRename,int live)167 void RotateFile(pcapfile_t *pcapfile, time_t t_CloseRename, int live) {
168 struct pcap_stat p_stat;
169 void *_b;
170
171 dbg_printf("RotateFile() time: %s\n", UNIX2ISO(t_CloseRename));
172 // make sure, alternate buffer is already flushed
173 pthread_mutex_lock(&pcapfile->m_pbuff);
174 while ( pcapfile->alternate_size ) {
175 pthread_cond_wait(&pcapfile->c_pbuff, &pcapfile->m_pbuff);
176 }
177
178 // swap buffers
179 _b = pcapfile->data_buffer;
180 pcapfile->data_buffer = pcapfile->alternate_buffer;
181 pcapfile->data_ptr = pcapfile->data_buffer;
182 pcapfile->alternate_buffer = _b;
183 pcapfile->alternate_size = pcapfile->data_size;
184 pcapfile->t_CloseRename = t_CloseRename;
185
186 // release mutex and signal thread
187 pthread_mutex_unlock(&pcapfile->m_pbuff);
188 pthread_cond_signal(&pcapfile->c_pbuff);
189
190 pcapfile->data_size = 0;
191
192 if ( live ) {
193 // not a capture file
194 if( pcap_stats(pcapfile->p, &p_stat) < 0) {
195 LogError("pcap_stats() failed: %s", pcap_geterr(pcapfile->p));
196 } else {
197 LogInfo("Packets received: %u, dropped: %u, dropped by interface: %u ",
198 p_stat.ps_recv, p_stat.ps_drop, p_stat.ps_ifdrop );
199 }
200 }
201
202 } // End of RotateFile
203
PcapDump(pcapfile_t * pcapfile,struct pcap_pkthdr * h,const u_char * sp)204 void PcapDump(pcapfile_t *pcapfile, struct pcap_pkthdr *h, const u_char *sp) {
205 struct pcap_sf_pkthdr sf_hdr;
206 size_t size = sizeof(struct pcap_sf_pkthdr) + h->caplen;
207
208 /*
209 if ( pcapfile->pd)
210 pcap_dump((u_char *)pcapfile->pd, h, sp);
211 else
212 printf("NULL handle\n");
213 return;
214 */
215 if ( (pcapfile->data_size + size ) > BUFFSIZE ) {
216 void *_b;
217 // no space left in buffer - rotate buffers
218 dbg_printf("PcapDump() cycle buffers: size: %u\n", pcapfile->data_size);
219 // make sure, alternate buffer is flushed
220 pthread_mutex_lock(&pcapfile->m_pbuff);
221 while ( pcapfile->alternate_size ) {
222 pthread_cond_wait(&pcapfile->c_pbuff, &pcapfile->m_pbuff);
223 }
224
225 // swap buffers
226 _b = pcapfile->data_buffer;
227 pcapfile->data_buffer = pcapfile->alternate_buffer;
228 pcapfile->data_ptr = pcapfile->data_buffer;
229 pcapfile->alternate_buffer = _b;
230 pcapfile->alternate_size = pcapfile->data_size;
231 pcapfile->t_CloseRename = 0;
232
233 // release mutex and signal thread
234 pthread_mutex_unlock(&pcapfile->m_pbuff);
235 pthread_cond_signal(&pcapfile->c_pbuff);
236
237 pcapfile->data_size = 0;
238 }
239
240 sf_hdr.ts.tv_sec = h->ts.tv_sec;
241 sf_hdr.ts.tv_usec = h->ts.tv_usec;
242 sf_hdr.caplen = h->caplen;
243 sf_hdr.len = h->len;
244
245 memcpy(pcapfile->data_ptr, (void *)&sf_hdr, sizeof(sf_hdr));
246 pcapfile->data_ptr += sizeof(struct pcap_sf_pkthdr);
247 memcpy(pcapfile->data_ptr, (void *)sp, h->caplen);
248 pcapfile->data_ptr += h->caplen;
249 pcapfile->data_size += (sizeof(struct pcap_sf_pkthdr) + h->caplen);
250
251 } // End of PcapDump
252
ProcessTCPFlow(FlowSource_t * fs,struct FlowNode * NewNode)253 static inline void ProcessTCPFlow(FlowSource_t *fs, struct FlowNode *NewNode ) {
254 struct FlowNode *Node;
255
256 assert(NewNode->memflag == NODE_IN_USE);
257 Node = Insert_Node(NewNode);
258 // Return existing Node if flow exists already, otherwise insert es new
259 if ( Node == NULL ) {
260 // Insert as new
261 dbg_printf("New TCP flow: Packets: %u, Bytes: %u\n", NewNode->packets, NewNode->bytes);
262
263 // in case it's a FIN/RST only packet - immediately flush it
264 if ( NewNode->fin == FIN_NODE ) {
265 // flush node
266 if ( StorePcapFlow(fs, NewNode) ) {
267 Remove_Node(NewNode);
268 }
269 }
270
271 if ( Link_RevNode(NewNode)) {
272 // if we could link this new node, it is the server answer
273 // -> calculate server latency
274 SetServer_latency(NewNode);
275 }
276 return;
277 }
278
279 assert(Node->memflag == NODE_IN_USE);
280
281 // check for first client ACK for client latency
282 if ( Node->latency.flag == 1 ) {
283 SetClient_latency(Node, &(NewNode->t_first));
284 } else if ( Node->latency.flag == 2 ) {
285 SetApplication_latency(Node, &(NewNode->t_first));
286 }
287 // update existing flow
288 Node->flags |= NewNode->flags;
289 Node->packets++;
290 Node->bytes += NewNode->bytes;
291 Node->t_last = NewNode->t_last;
292 dbg_printf("Existing TCP flow: Packets: %u, Bytes: %u\n", Node->packets, Node->bytes);
293
294 if ( NewNode->fin == FIN_NODE) {
295 // flush node
296 Node->fin = FIN_NODE;
297 if ( StorePcapFlow(fs, Node) ) {
298 Remove_Node(Node);
299 }
300 } else {
301 Free_Node(NewNode);
302 }
303
304
305 } // End of ProcessTCPFlow
306
ProcessUDPFlow(FlowSource_t * fs,struct FlowNode * NewNode)307 static inline void ProcessUDPFlow(FlowSource_t *fs, struct FlowNode *NewNode ) {
308 struct FlowNode *Node;
309
310 assert(NewNode->memflag == NODE_IN_USE);
311 // Flush DNS queries directly
312 if ( NewNode->src_port == 53 || NewNode->dst_port == 53 ) {
313 StorePcapFlow(fs, NewNode);
314 Free_Node(NewNode);
315 return;
316 }
317
318 // insert other UDP traffic
319 Node = Insert_Node(NewNode);
320 // if insert fails, the existing node is returned -> flow exists already
321 if ( Node == NULL ) {
322 dbg_printf("New UDP flow: Packets: %u, Bytes: %u\n", NewNode->packets, NewNode->bytes);
323 return;
324 }
325 assert(Node->memflag == NODE_IN_USE);
326
327 // update existing flow
328 Node->packets++;
329 Node->bytes += NewNode->bytes;
330 Node->t_last = NewNode->t_last;
331 dbg_printf("Existing UDP flow: Packets: %u, Bytes: %u\n", Node->packets, Node->bytes);
332
333 Free_Node(NewNode);
334
335 } // End of ProcessUDPFlow
336
ProcessICMPFlow(FlowSource_t * fs,struct FlowNode * NewNode)337 static inline void ProcessICMPFlow(FlowSource_t *fs, struct FlowNode *NewNode ) {
338
339 // Flush ICMP directly
340 StorePcapFlow(fs, NewNode);
341 dbg_printf("Flush ICMP flow: Packets: %u, Bytes: %u\n", NewNode->packets, NewNode->bytes);
342
343 Free_Node(NewNode);
344
345 } // End of ProcessICMPFlow
346
ProcessOtherFlow(FlowSource_t * fs,struct FlowNode * NewNode)347 static inline void ProcessOtherFlow(FlowSource_t *fs, struct FlowNode *NewNode ) {
348
349 // Flush Other packets directly
350 StorePcapFlow(fs, NewNode);
351 dbg_printf("Flush Other flow: Proto: %u, Packets: %u, Bytes: %u\n", NewNode->proto, NewNode->packets, NewNode->bytes);
352
353 Free_Node(NewNode);
354
355
356 } // End of ProcessOtherFlow
357
ProcessFlowNode(FlowSource_t * fs,struct FlowNode * node)358 void ProcessFlowNode(FlowSource_t *fs, struct FlowNode *node) {
359
360 switch (node->proto) {
361 case IPPROTO_TCP:
362 ProcessTCPFlow(fs, node);
363 break;
364 case IPPROTO_UDP:
365 ProcessUDPFlow(fs, node);
366 break;
367 case IPPROTO_ICMP:
368 case IPPROTO_ICMPV6:
369 ProcessICMPFlow(fs, node);
370 break;
371 default:
372 ProcessOtherFlow(fs, node);
373 }
374
375 } // End of ProcessFlowNode
376
ProcessPacket(NodeList_t * NodeList,pcap_dev_t * pcap_dev,const struct pcap_pkthdr * hdr,const u_char * data)377 void ProcessPacket(NodeList_t *NodeList, pcap_dev_t *pcap_dev, const struct pcap_pkthdr *hdr, const u_char *data) {
378 struct FlowNode *Node;
379 struct ip *ip;
380 void *payload, *defragmented;
381 uint32_t size_ip, offset, data_len, payload_len, bytes;
382 uint16_t version, ethertype, proto;
383 char s1[64];
384 char s2[64];
385 static unsigned pkg_cnt = 0;
386
387 pkg_cnt++;
388 dbg_printf("\nNext Packet: %u\n", pkg_cnt);
389
390 pcap_dev->proc_stat.packets++;
391 offset = pcap_dev->linkoffset;
392 defragmented = NULL;
393
394 Node = New_Node();
395 if ( !Node ) {
396 pcap_dev->proc_stat.skipped++;
397 LogError("Node allocation error - skip packet");
398 return;
399 }
400
401 if ( pcap_dev->linktype == DLT_EN10MB ) {
402 ethertype = data[12] << 0x08 | data[13];
403 int IEEE802 = ethertype <= 1500;
404 if ( IEEE802 ) {
405 pcap_dev->proc_stat.skipped++;
406 Free_Node(Node);
407 return;
408 }
409 REDO_LINK:
410 switch (ethertype) {
411 case 0x800: // IPv4
412 case 0x86DD: // IPv6
413 break;
414 case 0x8100: { // VLAN
415 do {
416 vlan_hdr_t *vlan_hdr = (vlan_hdr_t *)(data + offset); // offset points to end of link layer
417 dbg_printf("VLAN ID: %u, type: 0x%x\n",
418 ntohs(vlan_hdr->vlan_id), ntohs(vlan_hdr->type) );
419 ethertype = ntohs(vlan_hdr->type);
420 /*
421 pkt->vlans[pkt->vlan_count].pcp = (p[0] >> 5) & 7;
422 pkt->vlans[pkt->vlan_count].cfi = (p[0] >> 4) & 1;
423 pkt->vlans[pkt->vlan_count].vid = uint_16_be(p) & 0xfff;
424 */
425 offset += 4;
426 } while ( ethertype == 0x8100 );
427
428 // redo ethertype evaluation
429 goto REDO_LINK;
430 } break;
431 case 0x26: // ?? multicast router termination ??
432 case 0x32:
433 case 0x806: // skip ARP
434 case 0x4305: // B.A.T.M.A.N. BATADV
435 case 0x886f: // MS NLB heartbeat
436 case 0x88a2: // ATA over ethernet
437 case 0x88cc: // CISCO LLDP
438 case 0x9000: // Loop
439 case 0x9003:
440 case 0x880b: // PPP - rfc 7042
441 case 0x6558: // Ethernet Bridge
442 pcap_dev->proc_stat.skipped++;
443 Free_Node(Node);
444 goto END_FUNC;
445 break;
446 default:
447 pcap_dev->proc_stat.unknown++;
448 LogInfo("Unsupported ether type: 0x%x, packet: %u", ethertype, pkg_cnt);
449 Free_Node(Node);
450 goto END_FUNC;
451 }
452 } else {
453 LogInfo("Unsupported link type: 0x%x, packet: %u", pcap_dev->linktype, pkg_cnt);
454 Free_Node(Node);
455 return;
456 }
457
458 if (hdr->caplen < offset) {
459 pcap_dev->proc_stat.short_snap++;
460 LogInfo("Short packet: %u/%u", hdr->caplen, offset);
461 Free_Node(Node);
462 goto END_FUNC;
463 }
464
465 Node->t_first.tv_sec = hdr->ts.tv_sec;
466 Node->t_first.tv_usec = hdr->ts.tv_usec;
467 Node->t_last.tv_sec = hdr->ts.tv_sec;
468 Node->t_last.tv_usec = hdr->ts.tv_usec;
469
470 data = data + offset;
471 data_len = hdr->caplen - offset;
472 offset = 0;
473
474 // IP decoding
475 REDO_IPPROTO:
476 // IP decoding
477 if ( defragmented ) {
478 // data is sitting on a defragmented IPv4 packet memory region
479 // REDO loop could result in a memory leak, if again IP is fragmented
480 // XXX memory leak to be fixed
481 LogError("Fragmentation memory leak triggered!");
482 }
483
484 ip = (struct ip *)(data + offset); // offset points to end of link layer
485 version = ip->ip_v; // ip version
486
487 if ( version == 6 ) {
488 uint64_t *addr;
489 struct ip6_hdr *ip6 = (struct ip6_hdr *) (data + offset);
490 size_ip = sizeof(struct ip6_hdr);
491 offset = size_ip; // offset point to end of IP header
492
493 if ( data_len < size_ip ) {
494 LogInfo("Packet: %u Length error: data_len: %u < size IPV6: %u, captured: %u, hdr len: %u",
495 pkg_cnt, data_len, size_ip, hdr->caplen, hdr->len);
496 pcap_dev->proc_stat.short_snap++;
497 Free_Node(Node);
498 goto END_FUNC;
499 }
500
501 // XXX Extension headers not processed
502 proto = ip6->ip6_ctlun.ip6_un1.ip6_un1_nxt;
503 payload_len = bytes = ntohs(ip6->ip6_ctlun.ip6_un1.ip6_un1_plen);
504
505 if (data_len < (payload_len + size_ip) ) {
506 // capture len was limited - so adapt payload_len
507 payload_len = data_len - size_ip;
508 }
509
510 dbg_printf("Packet IPv6, SRC %s, DST %s, ",
511 inet_ntop(AF_INET6, &ip6->ip6_src, s1, sizeof(s1)),
512 inet_ntop(AF_INET6, &ip6->ip6_dst, s2, sizeof(s2)));
513
514 payload = (void *)ip + size_ip;
515
516 addr = (uint64_t *)&ip6->ip6_src;
517 Node->src_addr.v6[0] = ntohll(addr[0]);
518 Node->src_addr.v6[1] = ntohll(addr[1]);
519
520 addr = (uint64_t *)&ip6->ip6_dst;
521 Node->dst_addr.v6[0] = ntohll(addr[0]);
522 Node->dst_addr.v6[1] = ntohll(addr[1]);
523 Node->version = AF_INET6;
524
525 } else if ( version == 4 ) {
526 uint16_t ip_off = ntohs(ip->ip_off);
527 uint32_t frag_offset = (ip_off & IP_OFFMASK) << 3;
528 size_ip = (ip->ip_hl << 2);
529 offset = size_ip; // offset point to end of IP header
530
531 if ( data_len < size_ip ) {
532 LogInfo("Packet: %u Length error: data_len: %u < size IPV4: %u, captured: %u, hdr len: %u",
533 pkg_cnt, data_len, size_ip, hdr->caplen, hdr->len);
534 pcap_dev->proc_stat.short_snap++;
535 Free_Node(Node);
536 goto END_FUNC;
537 }
538
539 payload_len = ntohs(ip->ip_len);
540 dbg_printf("size IP hader: %u, len: %u\n", size_ip, payload_len);
541
542 payload_len -= size_ip; // ajust length compatibel IPv6
543 payload = (void *)ip + size_ip;
544 proto = ip->ip_p;
545
546 if (data_len < (payload_len + size_ip) ) {
547 // capture len was limited - so adapt payload_len
548 payload_len = data_len - size_ip;
549 pcap_dev->proc_stat.short_snap++;
550 }
551
552 dbg_printf("Packet IPv4 SRC %s, DST %s, ",
553 inet_ntop(AF_INET, &ip->ip_src, s1, sizeof(s1)),
554 inet_ntop(AF_INET, &ip->ip_dst, s2, sizeof(s2)));
555
556 // IPv4 defragmentation
557 if ( (ip_off & IP_MF) || frag_offset ) {
558 uint16_t ip_id = ntohs(ip->ip_id);
559 #ifdef DEVEL
560 if ( frag_offset == 0 )
561 printf("Fragmented packet: first segement: ip_off: %u, frag_offset: %u\n",
562 ip_off, frag_offset);
563 if (( ip_off & IP_MF ) && frag_offset )
564 printf("Fragmented packet: middle segement: ip_off: %u, frag_offset: %u\n",
565 ip_off, frag_offset);
566 if (( ip_off & IP_MF ) == 0 )
567 printf("Fragmented packet: last segement: ip_off: %u, frag_offset: %u\n",
568 ip_off, frag_offset);
569 #endif
570 // fragmented packet
571 defragmented = IPFrag_tree_Update(hdr->ts.tv_sec, ip->ip_src.s_addr, ip->ip_dst.s_addr,
572 ip_id, &payload_len, ip_off, payload);
573 if ( defragmented == NULL ) {
574 // not yet complete
575 dbg_printf("Fragmentation not yet completed. Size %u bytes\n", payload_len);
576 Free_Node(Node);
577 goto END_FUNC;
578 }
579 dbg_printf("Fragmentation complete\n");
580 // packet defragmented - set payload to defragmented data
581 payload = defragmented;
582 }
583 bytes = payload_len;
584
585 Node->src_addr.v6[0] = 0;
586 Node->src_addr.v6[1] = 0;
587 Node->src_addr.v4 = ntohl(ip->ip_src.s_addr);
588
589 Node->dst_addr.v6[0] = 0;
590 Node->dst_addr.v6[1] = 0;
591 Node->dst_addr.v4 = ntohl(ip->ip_dst.s_addr);
592 Node->version = AF_INET;
593 } else {
594 LogInfo("ProcessPacket() Unsupported protocol version: %i", version);
595 pcap_dev->proc_stat.unknown++;
596 Free_Node(Node);
597 goto END_FUNC;
598 }
599
600 Node->packets = 1;
601 Node->bytes = bytes;
602 Node->proto = proto;
603 dbg_printf("Payload: %u bytes, Full packet: %u bytes\n", payload_len, bytes);
604
605 // TCP/UDP decoding
606 switch (proto) {
607 case IPPROTO_UDP: {
608 struct udphdr *udp = (struct udphdr *)payload;
609 uint16_t UDPlen = ntohs(udp->uh_ulen);
610 if ( UDPlen < 8 ) {
611 LogInfo("UDP payload length error: %u bytes < 8, SRC %s, DST %s",
612 UDPlen, inet_ntop(AF_INET, &ip->ip_src, s1, sizeof(s1)),
613 inet_ntop(AF_INET, &ip->ip_dst, s2, sizeof(s2)));
614
615 Free_Node(Node);
616 break;
617 }
618 uint32_t size_udp_payload = ntohs(udp->uh_ulen) - 8;
619
620 if ( (bytes == payload_len ) && (payload_len - sizeof(struct udphdr)) < size_udp_payload ) {
621 LogInfo("UDP payload length error: Expected %u, have %u bytes, SRC %s, DST %s",
622 size_udp_payload, (payload_len - (unsigned)sizeof(struct udphdr)),
623 inet_ntop(AF_INET, &ip->ip_src, s1, sizeof(s1)),
624 inet_ntop(AF_INET, &ip->ip_dst, s2, sizeof(s2)));
625 Free_Node(Node);
626 break;
627 }
628 payload = payload + sizeof(struct udphdr);
629 payload_len -= sizeof(struct udphdr);
630 dbg_printf("UDP: size: %u, SRC: %i, DST: %i\n",
631 size_udp_payload, ntohs(udp->uh_sport), ntohs(udp->uh_dport));
632
633 Node->bytes = payload_len;
634 Node->flags = 0;
635 Node->src_port = ntohs(udp->uh_sport);
636 Node->dst_port = ntohs(udp->uh_dport);
637
638 if ( hdr->caplen == hdr->len ) {
639 // process payload of full packets
640 if ( (bytes == payload_len) && (Node->src_port == 53 || Node->dst_port == 53) )
641 content_decode_dns(Node, payload, payload_len);
642 }
643 Push_Node(NodeList, Node);
644 } break;
645 case IPPROTO_TCP: {
646 struct tcphdr *tcp = (struct tcphdr *)payload;
647 uint32_t size_tcp;
648 size_tcp = tcp->th_off << 2;
649
650 if ( payload_len < size_tcp ) {
651 LogInfo("TCP header length error: len: %u < size TCP header: %u, SRC %s, DST %s",
652 payload_len, size_tcp,
653 inet_ntop(AF_INET, &ip->ip_src, s1, sizeof(s1)),
654 inet_ntop(AF_INET, &ip->ip_dst, s2, sizeof(s2)));
655 pcap_dev->proc_stat.short_snap++;
656
657 pcap_dev->proc_stat.short_snap++;
658 Free_Node(Node);
659 break;
660 }
661
662 payload = payload + size_tcp;
663 payload_len -= size_tcp;
664 dbg_printf("Size TCP header: %u, size TCP payload: %u ", size_tcp, payload_len);
665 dbg_printf("src %i, DST %i, flags %i : ",
666 ntohs(tcp->th_sport), ntohs(tcp->th_dport), tcp->th_flags);
667
668 #ifdef DEVEL
669 if ( tcp->th_flags & TH_SYN ) printf("SYN ");
670 if ( tcp->th_flags & TH_ACK ) printf("ACK ");
671 if ( tcp->th_flags & TH_URG ) printf("URG ");
672 if ( tcp->th_flags & TH_PUSH ) printf("PUSH ");
673 if ( tcp->th_flags & TH_FIN ) printf("FIN ");
674 if ( tcp->th_flags & TH_RST ) printf("RST ");
675 printf("\n");
676 #endif
677
678 Node->flags = tcp->th_flags;
679 Node->src_port = ntohs(tcp->th_sport);
680 Node->dst_port = ntohs(tcp->th_dport);
681 Push_Node(NodeList, Node);
682
683 } break;
684 case IPPROTO_ICMP: {
685 struct icmp *icmp = (struct icmp *)payload;
686
687 Node->dst_port = (icmp->icmp_type << 8 ) + icmp->icmp_code;
688 dbg_printf("IPv%d ICMP proto: %u, type: %u, code: %u\n",
689 version, ip->ip_p, icmp->icmp_type, icmp->icmp_code);
690 Node->bytes -= sizeof(struct udphdr);
691 Push_Node(NodeList, Node);
692 } break;
693 case IPPROTO_ICMPV6: {
694 struct icmp6_hdr *icmp6 = (struct icmp6_hdr *)payload;
695
696 Node->dst_port = (icmp6->icmp6_type << 8 ) + icmp6->icmp6_code;
697 dbg_printf("IPv%d ICMP proto: %u, type: %u, code: %u\n",
698 version, ip->ip_p, icmp6->icmp6_type, icmp6->icmp6_code);
699 Push_Node(NodeList, Node);
700 } break;
701 case IPPROTO_IPV6: {
702 uint32_t size_inner_ip = sizeof(struct ip6_hdr);
703
704 if ( payload_len < size_inner_ip ) {
705 LogInfo("IPIPv6 tunnel header length error: len: %u < size inner IP: %u",
706 payload_len, size_inner_ip);
707 pcap_dev->proc_stat.short_snap++;
708 Free_Node(Node);
709 goto END_FUNC;
710 }
711 offset = 0;
712 data = payload;
713 data_len = payload_len;
714
715 // // move IP to tun IP
716 Node->tun_src_addr = Node->src_addr;
717 Node->tun_dst_addr = Node->dst_addr;
718 Node->tun_proto = IPPROTO_IPIP;
719
720 dbg_printf("IPIPv6 tunnel - inner IPv6:\n");
721
722 // redo proto evaluation
723 goto REDO_IPPROTO;
724 } break;
725 case IPPROTO_IPIP: {
726 struct ip *inner_ip = (struct ip *)payload;
727 uint32_t size_inner_ip = (inner_ip->ip_hl << 2);
728
729 if ( payload_len < size_inner_ip ) {
730 LogInfo("IPIP tunnel header length error: len: %u < size inner IP: %u",
731 payload_len, size_inner_ip);
732 pcap_dev->proc_stat.short_snap++;
733 Free_Node(Node);
734 break;
735 }
736 offset = 0;
737 data = payload;
738 data_len = payload_len;
739
740 // move IP to tun IP
741 Node->tun_src_addr = Node->src_addr;
742 Node->tun_dst_addr = Node->dst_addr;
743 Node->tun_proto = IPPROTO_IPIP;
744
745 dbg_printf("IPIP tunnel - inner IP:\n");
746
747 // redo proto evaluation
748 goto REDO_IPPROTO;
749
750 } break;
751 case IPPROTO_GRE: {
752 gre_hdr_t *gre_hdr = (gre_hdr_t *)payload;
753 uint32_t gre_hdr_size = sizeof(gre_hdr_t); // offset points to end of inner IP
754
755 if ( payload_len < gre_hdr_size ) {
756 LogError("GRE tunnel header length error: len: %u < size GRE hdr: %u",
757 payload_len, gre_hdr_size);
758 pcap_dev->proc_stat.short_snap++;
759 Free_Node(Node);
760 break;
761 }
762
763 dbg_printf("GRE proto encapsulation: type: 0x%x\n", ethertype);
764 ethertype = ntohs(gre_hdr->type);
765 offset = gre_hdr_size;
766 data = payload;
767 data_len = payload_len;
768
769 // move IP to tun IP
770 Node->tun_src_addr = Node->src_addr;
771 Node->tun_dst_addr = Node->dst_addr;
772 Node->tun_proto = IPPROTO_GRE;
773
774 // redo IP proto evaluation
775 goto REDO_LINK;
776
777 } break;
778 default:
779 // not handled protocol
780 Free_Node(Node);
781 pcap_dev->proc_stat.unknown++;
782 break;
783 }
784
785 END_FUNC:
786 if ( defragmented ) {
787 free(defragmented);
788 defragmented = NULL;
789 dbg_printf("Defragmented buffer freed for proto %u", proto);
790 }
791
792
793 } // End of ProcessPacket
794