2 ** This file is a part of PRADS.
4 ** Copyright (C) 2009, Redpill Linpro
5 ** Copyright (C) 2009, Edward Fjellskål <edward.fjellskaal@redpill-linpro.com>
6 ** Copyright (C) 2009, Kacper Wysocki <kacper.wysocki@redpill-linpro.com>
8 ** This program is free software; you can redistribute it and/or modify
9 ** it under the terms of the GNU General Public License as published by
10 ** the Free Software Foundation; either version 2 of the License, or
11 ** (at your option) any later version.
13 ** This program is distributed in the hope that it will be useful,
14 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ** GNU General Public License for more details.
18 ** You should have received a copy of the GNU General Public License
19 ** along with this program; if not, write to the Free Software
20 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 /* I N C L U D E S *********************************************************/
26 #include <sys/malloc.h>
27 #elseif !defined(__FreeBSD__)
37 #include "ipfp/ipfp.h"
38 #include "servicefp/servicefp.h"
44 //#include "output-plugins/log_init.h"
45 #include "output-plugins/log.h"
48 #define CONFDIR "/etc/prads/"
51 #define ARGS "C:c:b:d:Dg:hi:p:r:u:va:l:L:f:qtxs:OXFRMSAKUTIZtHPB"
53 /* G L O B A L S *** (or candidates for refactoring, as we say)***********/
55 extern int optind
, opterr
, optopt
; // getopt()
58 servicelist
*services
[MAX_PORTS
];
59 int inpacket
, gameover
, intr_flag
;
62 fmask network
[MAX_NETS
];
64 // static strings for comparison
65 // - this is lame and should be a flag!
66 struct tagbstring tUNKNOWN
= bsStatic("unknown");
67 bstring UNKNOWN
= & tUNKNOWN
;
69 /* I N T E R N A L P R O T O T Y P E S ***********************************/
71 void check_vlan (packetinfo
*pi
);
72 void prepare_eth (packetinfo
*pi
);
73 void prepare_ip4 (packetinfo
*pi
);
74 void prepare_ip4ip (packetinfo
*pi
);
75 void prepare_ip6 (packetinfo
*pi
);
76 void prepare_ip6ip (packetinfo
*pi
);
77 void prepare_tcp (packetinfo
*pi
);
78 void prepare_udp (packetinfo
*pi
);
79 void prepare_icmp (packetinfo
*pi
);
80 void prepare_gre (packetinfo
*pi
);
81 void prepare_greip (packetinfo
*pi
);
82 void prepare_other (packetinfo
*pi
);
83 void parse_eth (packetinfo
*pi
);
84 void parse_ip4 (packetinfo
*pi
);
85 void parse_ip6 (packetinfo
*pi
);
86 void parse_tcp (packetinfo
*pi
);
87 void parse_udp (packetinfo
*pi
);
88 void parse_icmp (packetinfo
*pi
);
89 void parse_gre (packetinfo
*pi
);
90 void parse_other (packetinfo
*pi
);
91 void parse_arp (packetinfo
*pi
);
92 int parse_network (char *net_s
, struct in6_addr
*network
);
93 int parse_netmask (char *f
, int type
, struct in6_addr
*netmask
);
94 void parse_nets(const char *s_net
, fmask
*network
);
96 void udp_guess_direction(packetinfo
*pi
);
97 void set_pkt_end_ptr (packetinfo
*pi
);
98 inline int filter_packet(const int af
, void *ip
);
100 /* F U N C T I O N S ********************************************************/
102 void got_packet(u_char
* useless
, const struct pcap_pkthdr
*pheader
,
103 const u_char
* packet
)
105 config
.pr_s
.got_packets
++;
106 packetinfo pstruct
= {0};
107 packetinfo
*pi
= &pstruct
;
110 pi
->pheader
= pheader
;
111 set_pkt_end_ptr (pi
);
112 tstamp
= pi
->pheader
->ts
.tv_sec
; // Global
113 if (intr_flag
!= 0) {
121 if (pi
->eth_type
== ETHERNET_TYPE_IP
) {
125 } else if (pi
->eth_type
== ETHERNET_TYPE_IPV6
) {
129 } else if (pi
->eth_type
== ETHERNET_TYPE_ARP
) {
133 config
.pr_s
.otherl_recv
++;
134 vlog(0x3, "[*] ETHERNET TYPE : %x\n",pi
->eth_hdr
->eth_ip_type
);
137 if (!pi
->our
) vlog(0x3, "Not our network packet. Tracked, but not logged.\n");
143 /* does this ip belong to our network? do we care about the packet?
145 * unfortunately pcap sends us packets in host order
146 * Return value: boolean
148 inline int filter_packet(const int af
, void *ipptr
)
149 //const struct in6_addr *ip_s)
155 char output
[INET_ADDRSTRLEN
+ 1];
159 struct in6_addr
*ip
= (struct in6_addr
*) ipptr
;
160 for (i
= 0; i
< MAX_NETS
&& i
< nets
; i
++) {
161 if (network
[i
].type
!= AF_INET
)
164 u_ntop(network
[i
].addr
, af
, output
);
165 dlog("Filter: %s\n", output
);
166 u_ntop(network
[i
].mask
, af
, output
);
167 dlog("mask: %s\n", output
);
168 u_ntop(*ip
, af
, output
);
169 dlog("ip: %s\n", output
);
171 if((IP4ADDR(ip
) & IP4ADDR(&network
[i
].mask
))
172 == (IP4ADDR(&network
[i
].addr
) & IP4ADDR(&network
[i
].mask
)) ){
178 dlog("%8x %8x %8x\n", IP4ADDR(ip
) & IP4ADDR(&network
[i
].mask
), IP4ADDR(&network
[i
].addr
) & IP4ADDR(&network
[i
].mask
), IP4ADDR(&network
[i
].mask
));
186 /* 32-bit comparison of ipv6 nets.
187 * can do better here by using 64-bit or SIMD instructions
188 * this code needs more thought and work
191 * PS: use same code for ipv4 - 0 bytes and SIMD doesnt care*/
193 // copy the in6_addr pointed to by ipptr into the vector. grr!
194 memcpy(&ip_vec
.ip6
,ipptr
, sizeof(struct in6_addr
));
195 for (i
= 0; i
< MAX_NETS
&& i
< nets
; i
++) {
196 if(network
[i
].type
!= AF_INET6
)
199 u_ntop(network
[i
].addr
, af
, output
);
200 dlog("net: %s\n", output
);
201 u_ntop(network
[i
].mask
, af
, output
);
202 dlog("mask: %s\n", output
);
203 u_ntop(ip_vec
.ip6
, af
, output
);
204 dlog("ip: %s\n", output
);
206 if (network
[i
].type
== AF_INET6
) {
208 /* apologies for the uglyness */
210 #define compare128(x,y) __builtin_ia32_pcmpeqd128((x), (y))
211 // the builtin is only available on sse2!
212 t
.v
= __builtin_ia32_pcmpeqd128(
213 ip_vec
.v
& network
[i
].mask_v
,
217 #define compare128(x,y) memcmp(&(x),&(y),16)
218 t
.v
= ip_vec
.v
& network
[i
].mask_v
;
219 // xor(a,b) == 0 iff a==b
220 if (!( (t
.i
[0] ^ network
[i
].addr64
[0]) &
221 (t
.i
[1] ^ network
[i
].addr64
[1]) ))
229 if ((ip_s
.__u6_addr
.__u6_addr32
[0] & network
[i
].mask
.__u6_addr
.__u6_addr32
[0])
230 == network
[i
].addr
.__u6_addr
.__u6_addr32
[0]
231 && (ip_s
.__u6_addr
.__u6_addr32
[1] & network
[i
].mask
.__u6_addr
.__u6_addr32
[1])
232 == network
[i
].addr
.__u6_addr
.__u6_addr32
[1]
233 && (ip_s
.__u6_addr
.__u6_addr32
[2] & network
[i
].mask
.__u6_addr
.__u6_addr32
[2])
234 == network
[i
].addr
.__u6_addr
.__u6_addr32
[2]
235 && (ip_s
.__u6_addr
.__u6_addr32
[3] & network
[i
].mask
.__u6_addr
.__u6_addr32
[3])
236 == network
[i
].addr
.__u6_addr
.__u6_addr32
[3]) {
247 "non-ip packets of type %d aren't filtered by netmask yet\n", af
);
252 inet_ntop(af
, (struct in6addr
*) ipptr
, output
, MAX_NETS
);
254 inet_ntop(af
, (uint32_t*)ipptr
, output
, MAX_NETS
);
257 vlog(0x2, "Address %s is in our network.\n", output
);
259 vlog(0x2, "Address %s is not our network.\n", output
);
265 void prepare_eth (packetinfo
*pi
)
267 if (pi
->packet
+ ETHERNET_HEADER_LEN
> pi
->end_ptr
) return;
268 config
.pr_s
.eth_recv
++;
269 pi
->eth_hdr
= (ether_header
*) (pi
->packet
);
270 pi
->eth_type
= ntohs(pi
->eth_hdr
->eth_ip_type
);
271 pi
->eth_hlen
= ETHERNET_HEADER_LEN
;
275 void parse_eth (packetinfo
*pi
)
277 if (!IS_CSSET(&config
,CS_MAC
)) return;
278 /* update_asset_arp(pi->eth_hdr->ether_src, pi);
280 uint8_t *mac = pi->eth_hdr->ether_src;
282 * XXX: how is mac matching supposed to work?
283 * answer: lookup macs on pertinent frames
284 * and hash into mac asset database
285 * mac assets are like regular assets,
286 * and contain references to other assets they involve
287 if(! pi->asset->mace)
288 mac_entry *match = match_mac(config.sig_mac, mac, 48);
292 olog("mac matched: %s\n", match->vendor);
294 // call update_asset_mac or smth?
296 //config.pr_s.eth_recv++;
302 void check_vlan (packetinfo
*pi
)
304 if (pi
->eth_type
== ETHERNET_TYPE_8021Q
) {
305 vlog(0x3, "[*] ETHERNET TYPE 8021Q\n");
306 config
.pr_s
.vlan_recv
++;
307 pi
->vlan
= pi
->eth_hdr
->eth_8_vid
;
308 pi
->eth_type
= ntohs(pi
->eth_hdr
->eth_8_ip_type
);
311 /* This is b0rked - kwy and ebf fix */
312 } else if (pi
->eth_type
==
313 (ETHERNET_TYPE_802Q1MT
| ETHERNET_TYPE_802Q1MT2
|
314 ETHERNET_TYPE_802Q1MT3
| ETHERNET_TYPE_8021AD
)) {
315 vlog(0x3, "[*] ETHERNET TYPE 802Q1MT\n");
316 pi
->mvlan
= pi
->eth_hdr
->eth_82_mvid
;
317 pi
->eth_type
= ntohs(pi
->eth_hdr
->eth_82_ip_type
);
323 void prepare_ip4 (packetinfo
*pi
)
325 config
.pr_s
.ip4_recv
++;
327 pi
->ip4
= (ip4_header
*) (pi
->packet
+ pi
->eth_hlen
);
328 pi
->packet_bytes
= (ntohs(pi
->ip4
->ip_len
) - (IP_HL(pi
->ip4
) * 4));
330 pi
->our
= filter_packet(pi
->af
, &PI_IP4SRC(pi
));
331 vlog(0x3, "Got %s IPv4 Packet...\n", (pi
->our
?"our":"foregin"));
335 void parse_ip4 (packetinfo
*pi
)
337 switch (pi
->ip4
->ip_p
) {
376 void prepare_gre (packetinfo
*pi
)
378 config
.pr_s
.gre_recv
++;
379 if((pi
->pheader
->caplen
- pi
->eth_hlen
) < GRE_HDR_LEN
) {
382 if (pi
->af
== AF_INET
) {
383 vlog(0x3, "[*] IPv4 PROTOCOL TYPE GRE:\n");
384 pi
->greh
= (gre_header
*) (pi
->packet
+ pi
->eth_hlen
+ (IP_HL(pi
->ip4
) * 4));
385 } else if (pi
->af
== AF_INET6
) {
386 vlog(0x3, "[*] IPv6 PROTOCOL TYPE GRE:\n");
387 pi
->greh
= (gre_header
*) (pi
->packet
+ pi
->eth_hlen
+ IP6_HEADER_LEN
);
389 pi
->proto
= IP_PROTO_GRE
;
393 void parse_gre (packetinfo
*pi
)
395 uint16_t gre_header_len
= GRE_HDR_LEN
;
396 gre_sre_header
*gsre
= NULL
;
397 uint16_t len
= (pi
->pheader
->caplen
- pi
->eth_hlen
);
401 switch (GRE_GET_VERSION(pi
->greh
))
404 /* Adjust header length based on content */
405 if (GRE_FLAG_ISSET_KY(pi
->greh
))
406 gre_header_len
+= GRE_KEY_LEN
;
407 if (GRE_FLAG_ISSET_SQ(pi
->greh
))
408 gre_header_len
+= GRE_SEQ_LEN
;
409 if (GRE_FLAG_ISSET_CHKSUM(pi
->greh
) || GRE_FLAG_ISSET_ROUTE(pi
->greh
))
410 gre_header_len
+= GRE_CHKSUM_LEN
+ GRE_OFFSET_LEN
;
411 if (gre_header_len
> len
) {
414 if (GRE_FLAG_ISSET_ROUTE(pi
->greh
))
416 gsre
= (gre_sre_header
*)(pi
->greh
+ gre_header_len
);
417 if (gsre
== NULL
) return;
420 if ((gre_header_len
+GRE_SRE_HDR_LEN
) > len
) {
423 gre_header_len
+= GRE_SRE_HDR_LEN
;
425 if (gsre
!= NULL
&& (ntohs(gsre
->af
) == 0) && (gsre
->sre_length
== 0))
428 gre_header_len
+= gsre
->sre_length
;
429 gsre
= (gre_sre_header
*)(pi
->greh
+ gre_header_len
);
437 /* GRE version 1 doenst support the fields below RFC 1701 */
438 if (GRE_FLAG_ISSET_CHKSUM(pi
->greh
)) {
441 if (GRE_FLAG_ISSET_ROUTE(pi
->greh
)) {
444 if (GRE_FLAG_ISSET_SSR(pi
->greh
)) {
447 if (GRE_FLAG_ISSET_RECUR(pi
->greh
)) {
450 if (GREV1_FLAG_ISSET_FLAGS(pi
->greh
)) {
453 if (GRE_GET_PROTO(pi
->greh
) != GRE_PROTO_PPP
) {
456 if (!(GRE_FLAG_ISSET_KY(pi
->greh
))) {
460 gre_header_len
+= GRE_KEY_LEN
;
462 /* Adjust header length based on content */
463 if (GRE_FLAG_ISSET_SQ(pi
->greh
))
464 gre_header_len
+= GRE_SEQ_LEN
;
465 if (GREV1_FLAG_ISSET_ACK(pi
->greh
))
466 gre_header_len
+= GREV1_ACK_LEN
;
467 if (gre_header_len
> len
) {
481 void prepare_ip6ip (packetinfo
*pi
)
484 memset(&pipi
, 0, sizeof(packetinfo
));
485 config
.pr_s
.ip6ip_recv
++;
486 pipi
.pheader
= pi
->pheader
;
487 pipi
.packet
= (pi
->packet
+ pi
->eth_hlen
+ IP6_HEADER_LEN
);
488 pipi
.end_ptr
= pi
->end_ptr
;
489 if (pi
->ip6
->next
== IP_PROTO_IP4
) {
500 void prepare_greip (packetinfo
*pi
)
503 memset(&pipi
, 0, sizeof(packetinfo
));
504 pipi
.pheader
= pi
->pheader
;
505 pipi
.packet
= (pi
->packet
+ pi
->eth_hlen
+ pi
->gre_hlen
);
506 pipi
.end_ptr
= pi
->end_ptr
;
507 if (GRE_GET_PROTO(pi
->greh
) == IP_PROTO_IP4
) {
511 } else if (GRE_GET_PROTO(pi
->greh
) == IP_PROTO_IP6
) {
516 /* Not more implemented atm */
517 vlog(0x3, "[*] - NOT CHECKING GRE PACKAGE TYPE Other\n");
522 void prepare_ip4ip (packetinfo
*pi
)
525 memset(&pipi
, 0, sizeof(packetinfo
));
526 config
.pr_s
.ip4ip_recv
++;
527 pipi
.pheader
= pi
->pheader
;
528 pipi
.packet
= (pi
->packet
+ pi
->eth_hlen
+ (IP_HL(pi
->ip4
) * 4));
529 pipi
.end_ptr
= pi
->end_ptr
;
530 if (pi
->ip4
->ip_p
== IP_PROTO_IP4
) {
541 void prepare_ip6 (packetinfo
*pi
)
543 config
.pr_s
.ip6_recv
++;
545 pi
->ip6
= (ip6_header
*) (pi
->packet
+ pi
->eth_hlen
);
546 pi
->packet_bytes
= ntohs(pi
->ip6
->len
);
547 // may be dropped due to macros plus
548 //pi->ip_src = PI_IP6SRC(pi);
549 //pi->ip_dst = PI_IP6DST(pi);
550 pi
->our
= filter_packet(pi
->af
, &PI_IP6SRC(pi
));
551 vlog(0x3, "Got %s IPv6 Packet...\n", (pi
->our
?"our":"foregin"));
555 void parse_ip6 (packetinfo
*pi
)
557 switch (pi
->ip6
->next
) {
587 * olog("[*] - CHECKING OTHER PACKAGE\n");
588 * update_asset(AF_INET6,ip6->ip_src);
589 * service_other(*pi->ip4,*tcph)
590 * fp_other(ip, ttl, ipopts, len, id, ipflags, df);
592 * olog("[*] - NOT CHECKING OTHER PACKAGE\n");
600 void parse_arp (packetinfo
*pi
)
602 vlog(0x3, "[*] Got ARP packet...\n");
603 config
.pr_s
.arp_recv
++;
604 if (!IS_CSSET(&config
,CS_ARP
)) return;
606 pi
->arph
= (ether_arp
*) (pi
->packet
+ pi
->eth_hlen
);
608 if (ntohs(pi
->arph
->ea_hdr
.ar_op
) == ARPOP_REPLY
) {
609 if (filter_packet(pi
->af
, &pi
->arph
->arp_spa
)) {
610 update_asset_arp(pi
->arph
->arp_sha
, pi
);
612 /* arp_check(eth_hdr,pi->pheader->ts.tv_sec); */
614 vlog(0x3, "[*] ARP TYPE: %d\n",ntohs(pi
->arph
->ea_hdr
.ar_op
));
618 void set_pkt_end_ptr (packetinfo
*pi
)
621 if (pi
->pheader
->len
<= SNAPLENGTH
) {
622 pi
->end_ptr
= (pi
->packet
+ pi
->pheader
->len
);
624 pi
->end_ptr
= (pi
->packet
+ SNAPLENGTH
);
629 void prepare_tcp (packetinfo
*pi
)
631 config
.pr_s
.tcp_recv
++;
632 if (pi
->af
==AF_INET
) {
633 vlog(0x3, "[*] IPv4 PROTOCOL TYPE TCP:\n");
634 pi
->tcph
= (tcp_header
*) (pi
->packet
+ pi
->eth_hlen
+ (IP_HL(pi
->ip4
) * 4));
635 pi
->plen
= (pi
->pheader
->caplen
- (TCP_OFFSET(pi
->tcph
)) * 4 - (IP_HL(pi
->ip4
) * 4) - pi
->eth_hlen
);
636 pi
->payload
= (pi
->packet
+ pi
->eth_hlen
+ (IP_HL(pi
->ip4
) * 4) + (TCP_OFFSET(pi
->tcph
) * 4));
637 } else if (pi
->af
==AF_INET6
) {
638 vlog(0x3, "[*] IPv6 PROTOCOL TYPE TCP:\n");
639 pi
->tcph
= (tcp_header
*) (pi
->packet
+ pi
->eth_hlen
+ IP6_HEADER_LEN
);
640 pi
->plen
= (pi
->pheader
->caplen
- (TCP_OFFSET(pi
->tcph
)) * 4 - IP6_HEADER_LEN
- pi
->eth_hlen
);
641 pi
->payload
= (pi
->packet
+ pi
->eth_hlen
+ IP6_HEADER_LEN
+ (TCP_OFFSET(pi
->tcph
)*4));
643 pi
->proto
= IP_PROTO_TCP
;
644 pi
->s_port
= pi
->tcph
->src_port
;
645 pi
->d_port
= pi
->tcph
->dst_port
;
646 connection_tracking(pi
);
647 //cx_track_simd_ipv4(pi);
649 dump_payload(pi
->payload
, (config
.payload
< pi
->plen
)?config
.payload
:pi
->plen
);
653 void parse_tcp (packetinfo
*pi
)
657 if (TCP_ISFLAGSET(pi
->tcph
, (TF_SYN
))) {
658 if (!TCP_ISFLAGSET(pi
->tcph
, (TF_ACK
))) {
659 if (IS_COSET(&config
,CO_SYN
)) {
660 vlog(0x3, "[*] - Got a SYN from a CLIENT: dst_port:%d\n",ntohs(pi
->tcph
->dst_port
));
665 if (IS_COSET(&config
,CO_SYNACK
)) {
666 vlog(0x3, "[*] Got a SYNACK from a SERVER: src_port:%d\n", ntohs(pi
->tcph
->src_port
));
667 fp_tcp(pi
, CO_SYNACK
);
668 if (pi
->sc
!= SC_SERVER
)
675 // Check payload for known magic bytes that defines files!
677 if (pi
->sc
== SC_CLIENT
&& !ISSET_CXT_DONT_CHECK_CLIENT(pi
)) {
678 if (IS_CSSET(&config
,CS_TCP_CLIENT
)
679 && !ISSET_DONT_CHECK_CLIENT(pi
)) {
680 if (pi
->af
== AF_INET
)
681 client_tcp4(pi
, config
.sig_client_tcp
);
683 client_tcp6(pi
, config
.sig_client_tcp
);
687 } else if (pi
->sc
== SC_SERVER
&& !ISSET_CXT_DONT_CHECK_SERVER(pi
)) {
688 if (IS_CSSET(&config
,CS_TCP_SERVER
)
689 && !ISSET_DONT_CHECK_SERVICE(pi
)) {
690 if (pi
->af
== AF_INET
)
691 service_tcp4(pi
, config
.sig_serv_tcp
);
693 service_tcp6(pi
, config
.sig_serv_tcp
);
697 vlog(0x3, "[*] - NOT CHECKING TCP PACKAGE\n");
701 if (IS_COSET(&config
,CO_ACK
)
702 && TCP_ISFLAGSET(pi
->tcph
, (TF_ACK
))
703 && !TCP_ISFLAGSET(pi
->tcph
, (TF_SYN
))
704 && !TCP_ISFLAGSET(pi
->tcph
, (TF_RST
))
705 && !TCP_ISFLAGSET(pi
->tcph
, (TF_FIN
))) {
706 vlog(0x3, "[*] Got a STRAY-ACK: src_port:%d\n",ntohs(pi
->tcph
->src_port
));
709 } else if (IS_COSET(&config
,CO_FIN
) && TCP_ISFLAGSET(pi
->tcph
, (TF_FIN
))) {
710 vlog(0x3, "[*] Got a FIN: src_port:%d\n",ntohs(pi
->tcph
->src_port
));
713 } else if (IS_COSET(&config
,CO_RST
) && TCP_ISFLAGSET(pi
->tcph
, (TF_RST
))) {
714 vlog(0x3, "[*] Got a RST: src_port:%d\n",ntohs(pi
->tcph
->src_port
));
720 void prepare_udp (packetinfo
*pi
)
722 config
.pr_s
.udp_recv
++;
723 if (pi
->af
==AF_INET
) {
724 vlog(0x3, "[*] IPv4 PROTOCOL TYPE UDP:\n");
725 pi
->udph
= (udp_header
*) (pi
->packet
+ pi
->eth_hlen
+ (IP_HL(pi
->ip4
) * 4));
726 pi
->plen
= pi
->pheader
->caplen
- UDP_HEADER_LEN
-
727 (IP_HL(pi
->ip4
) * 4) - pi
->eth_hlen
;
728 pi
->payload
= (pi
->packet
+ pi
->eth_hlen
+
729 (IP_HL(pi
->ip4
) * 4) + UDP_HEADER_LEN
);
731 } else if (pi
->af
==AF_INET6
) {
732 vlog(0x3, "[*] IPv6 PROTOCOL TYPE UDP:\n");
733 pi
->udph
= (udp_header
*) (pi
->packet
+ pi
->eth_hlen
+ + IP6_HEADER_LEN
);
734 pi
->plen
= pi
->pheader
->caplen
- UDP_HEADER_LEN
-
735 IP6_HEADER_LEN
- pi
->eth_hlen
;
736 pi
->payload
= (pi
->packet
+ pi
->eth_hlen
+
737 IP6_HEADER_LEN
+ UDP_HEADER_LEN
);
739 pi
->proto
= IP_PROTO_UDP
;
740 pi
->s_port
= pi
->udph
->src_port
;
741 pi
->d_port
= pi
->udph
->dst_port
;
742 connection_tracking(pi
);
743 //cx_track_simd_ipv4(pi);
745 dump_payload(pi
->payload
, (config
.payload
< pi
->plen
)?config
.payload
:pi
->plen
);
749 void parse_udp (packetinfo
*pi
)
752 //if (is_set_guess_upd_direction(config)) {
753 udp_guess_direction(pi
); // fix DNS server transfers?
754 // Check for Passive DNS
755 if ( ntohs(pi
->s_port
) == 53 || ntohs(pi
->s_port
) == 5353 ) {
756 // For now - Proof of Concept! - Fix output way
757 if(config
.cflags
& CONFIG_PDNS
) {
758 static char ip_addr_s
[INET6_ADDRSTRLEN
];
759 u_ntop_src(pi
, ip_addr_s
);
760 dump_dns(pi
->payload
, pi
->plen
, stdout
, "\n", ip_addr_s
, pi
->pheader
->ts
.tv_sec
);
763 if (IS_COSET(&config
, CO_DHCP
) && ntohs(pi
->s_port
) == 68 && ntohs(pi
->d_port
) == 67) {
764 dhcp_fingerprint(pi
); /* basic DHCP parsing*/
766 // if (IS_COSET(&config,CO_DNS) && (pi->sc == SC_SERVER && ntohs(pi->s_port) == 53)) passive_dns (pi);
768 if (IS_CSSET(&config
,CS_UDP_SERVICES
)) {
769 if (pi
->af
== AF_INET
) {
771 if (!ISSET_DONT_CHECK_SERVICE(pi
)||!ISSET_DONT_CHECK_CLIENT(pi
)) {
772 // Check for UDP SERVICE
773 service_udp4(pi
, config
.sig_serv_udp
);
775 // UPD Fingerprinting
776 if (IS_COSET(&config
,CO_UDP
)) fp_udp4(pi
, pi
->ip4
, pi
->udph
, pi
->end_ptr
);
777 } else if (pi
->af
== AF_INET6
) {
778 if (!ISSET_DONT_CHECK_SERVICE(pi
)||!ISSET_DONT_CHECK_CLIENT(pi
)) {
779 service_udp6(pi
, config
.sig_client_udp
);
781 /* fp_udp(ip6, ttl, ipopts, len, id, ipflags, df); */
785 vlog(0x3, "[*] - NOT CHECKING UDP PACKAGE\n");
790 void prepare_icmp (packetinfo
*pi
)
792 config
.pr_s
.icmp_recv
++;
793 if (pi
->af
==AF_INET
) {
794 vlog(0x3, "[*] IPv4 PROTOCOL TYPE ICMP:\n");
795 pi
->icmph
= (icmp_header
*) (pi
->packet
+ pi
->eth_hlen
+ (IP_HL(pi
->ip4
) * 4));
796 pi
->proto
= IP_PROTO_ICMP
;
798 } else if (pi
->af
==AF_INET6
) {
799 vlog(0x3, "[*] IPv6 PROTOCOL TYPE ICMP:\n");
800 pi
->icmp6h
= (icmp6_header
*) (pi
->packet
+ pi
->eth_hlen
+ IP6_HEADER_LEN
);
801 pi
->proto
= IP6_PROTO_ICMP
;
806 * DO change ip6->hop_lmt to 0 or something
808 connection_tracking(pi
);
812 void parse_icmp (packetinfo
*pi
)
816 if (IS_COSET(&config
,CO_ICMP
)) {
817 if (pi
->cxt
->check
== 0x00) {
818 pi
->cxt
->check
= 0x10; //for now - stop icmp fp quick
819 if (pi
->af
==AF_INET
) {
820 fp_icmp4(pi
, pi
->ip4
, pi
->icmph
, pi
->end_ptr
);
821 // could look for icmp spesific data in package abcde...
822 // service_icmp(*pi->ip4,*tcph
823 } else if (pi
->af
==AF_INET6
) {
825 fp_icmp6(pi
, pi
->ip6
, pi
->icmp6h
, pi
->end_ptr
);
828 vlog(0x3, "[*] - NOT CHECKING ICMP PACKAGE\n");
833 void prepare_other (packetinfo
*pi
)
835 config
.pr_s
.othert_recv
++;
836 if (pi
->af
==AF_INET
) {
837 vlog(0x3, "[*] IPv4 PROTOCOL TYPE OTHER: %d\n",pi
->ip4
->ip_p
);
839 } else if (pi
->af
==AF_INET6
) {
840 vlog(0x3, "[*] IPv6 PROTOCOL TYPE OTHER: %d\n",pi
->ip6
->next
);
845 connection_tracking(pi
);
849 void parse_other (packetinfo
*pi
)
853 if (pi
->cxt
->check
== 0x00) {
854 if (IS_COSET(&config
,CO_OTHER
)) {
855 pi
->cxt
->check
= 0x01; // no more checks
856 // service_other(*pi->ip4,*transporth);
857 // fp_other(pi->ipX, ttl, ipopts, len, id, ipflags, df);
859 vlog(0x3, "[*] - NOT CHECKING *OTHER* PACKAGE\n");
864 void udp_guess_direction(packetinfo
*pi
)
866 /* Stupid hack :( for DNS/port 53 */
867 if (ntohs(pi
->d_port
) == 53) {
868 if (pi
->sc
== SC_CLIENT
) return;
869 else pi
->sc
= SC_CLIENT
;
871 } else if (ntohs(pi
->s_port
) == 53) {
872 if (pi
->sc
== SC_SERVER
) return;
873 else pi
->sc
= SC_SERVER
;
877 int parse_network (char *net_s
, struct in6_addr
*network
)
881 if (NULL
!= (t
= strchr(net_s
, ':'))) {
883 if (!inet_pton(type
, net_s
, network
)) {
884 perror("parse_nets6");
887 dlog("Network6 %-36s \t -> %08x:%08x:%08x:%08x\n",
893 if (!inet_pton(type
, net_s
, &IP4ADDR(network
))) {
894 perror("parse_nets");
897 dlog("Network4 %16s \t-> 0x%08x\n", net_s
, IP4ADDR(network
));
902 int parse_netmask (char *f
, int type
, struct in6_addr
*netmask
)
906 char output
[MAX_NETS
];
907 // parse netmask into host order
908 if (type
== AF_INET
&& (t
= strchr(f
, '.')) > f
&& t
-f
< 4) {
909 // full ipv4 netmask : dotted quads
910 inet_pton(type
, f
, &IP4ADDR(netmask
));
911 dlog("mask 4 %s \t-> 0x%08x\n", f
, IP4ADDR(netmask
));
912 } else if (type
== AF_INET6
&& NULL
!= (t
= strchr(f
, ':'))) {
913 // full ipv6 netmasÄž
914 dlog("mask 6 %s\n", f
);
915 inet_pton(type
, f
, netmask
);
918 sscanf(f
, "%u", &mask
);
919 dlog("cidr %u \t-> ", mask
);
920 if (type
== AF_INET
) {
921 uint32_t shift
= 32 - mask
;
923 IP4ADDR(netmask
) = ntohl( ((unsigned int)-1 >> shift
)<< shift
);
925 IP4ADDR(netmask
) = 0;
927 dlog("0x%08x\n", IP4ADDR(netmask
));
928 } else if (type
== AF_INET6
) {
931 memset(netmask
, 0, sizeof(struct in6_addr
));
934 netmask
->s6_addr
[j
++] = 0xff;
938 netmask
->s6_addr
[j
] = -1 << (8 - mask
);
941 inet_ntop(type
, &IP4ADDR(netmask
), output
, MAX_NETS
);
942 dlog("mask: %s\n", output
);
944 // pcap packets are in host order.
945 IP6ADDR0(netmask
) = ntohl(IP6ADDR0(netmask
));
946 IP6ADDR1(netmask
) = ntohl(IP6ADDR1(netmask
));
947 IP6ADDR2(netmask
) = ntohl(IP6ADDR2(netmask
));
948 IP6ADDR3(netmask
) = ntohl(IP6ADDR3(netmask
));
955 /* parse strings of the form ip/cidr or ip/mask like:
956 * "10.10.10.10/255.255.255.128,10.10.10.10/25" and
957 * "dead:be:eef2:1aa::b5ff:fe96:37a2/64,..."
959 * an IPv6 address is 8 x 4 hex digits. missing digits are padded with zeroes.
961 void parse_nets(const char *s_net
, fmask
*network
)
963 /* f -> for processing
967 int type
, len
, i
= 0;
968 struct in6_addr network6
, netmask6
;
970 // snet is a mutable copy of the args,freed @ nets_end
972 //snet = calloc(1, len);
973 snet
= calloc(1, (len
+ 1)); /* to have \0 too :-) */
974 strncpy(snet
, s_net
, len
);
976 while (f
&& 0 != (p
= strchr(f
, '/'))) {
977 // convert network address
979 type
= parse_network(f
, &network6
);
980 if (type
!= AF_INET
&& type
!= AF_INET6
) {
981 perror("parse_network");
990 parse_netmask(f
, type
, &netmask6
);
992 // poke in the gathered information
996 network
[i
].addr
= network6
;
997 network
[i
].mask
= netmask6
;
998 network
[i
].type
= type
;
1002 fprintf(stderr
, "parse_nets: invalid address family!\n");
1009 elog("Max networks reached, stopped parsing at %d nets.\n", i
-1);
1014 // continue parsing at p, which might point to another network range
1026 if (inpacket
== 0) {
1027 end_sessions(); /* Need to have correct human output when reading -r pcap */
1030 del_known_services();
1031 del_signature_lists();
1034 if(!ISSET_CONFIG_QUIET(config
)){
1035 print_prads_stats();
1036 if(!config
.pcap_file
)
1039 if (config
.handle
!= NULL
) pcap_close(config
.handle
);
1040 if (ISSET_CONFIG_SYSLOG(config
)) closelog();
1042 olog("[*] prads ended.\n");
1051 olog("Reparsing config file...");
1052 parse_config_file(config
.file
);
1060 void check_interrupt()
1063 if (intr_flag
== 1) {
1065 } else if (intr_flag
== 2) {
1066 update_asset_list();
1067 } else if (intr_flag
== 3) {
1069 } else if (intr_flag
== 4) {
1076 void set_end_sessions()
1080 if (inpacket
== 0) {
1081 tstamp
= time(NULL
);
1083 /* if no cxtracking is turned on - dont log to disk */
1084 /* if (log_cxt == 1) log_expired_cxt(); */
1085 /* if no asset detection is turned on - dont log to disk! */
1086 /* if (log_assets == 1) update_asset_list(); */
1087 update_asset_list();
1091 // install self again
1092 signal(SIGUSR1
, set_end_sessions
);
1095 void print_prads_stats()
1097 extern uint64_t cxtrackerid
; // cxt.c
1098 olog("-- prads:\n");
1099 olog("-- Total packets received from libpcap :%12u\n",config
.pr_s
.got_packets
);
1100 olog("-- Total Ethernet packets received :%12u\n",config
.pr_s
.eth_recv
);
1101 olog("-- Total VLAN packets received :%12u\n",config
.pr_s
.vlan_recv
);
1102 olog("-- Total ARP packets received :%12u\n",config
.pr_s
.arp_recv
);
1103 olog("-- Total IPv4 packets received :%12u\n",config
.pr_s
.ip4_recv
);
1104 olog("-- Total IPv6 packets received :%12u\n",config
.pr_s
.ip6_recv
);
1105 olog("-- Total Other link packets received :%12u\n",config
.pr_s
.otherl_recv
);
1106 olog("-- Total IPinIPv4 packets received :%12u\n",config
.pr_s
.ip4ip_recv
);
1107 olog("-- Total IPinIPv6 packets received :%12u\n",config
.pr_s
.ip6ip_recv
);
1108 olog("-- Total GRE packets received :%12u\n",config
.pr_s
.gre_recv
);
1109 olog("-- Total TCP packets received :%12u\n",config
.pr_s
.tcp_recv
);
1110 olog("-- Total UDP packets received :%12u\n",config
.pr_s
.udp_recv
);
1111 olog("-- Total ICMP packets received :%12u\n",config
.pr_s
.icmp_recv
);
1112 olog("-- Total Other transport packets received :%12u\n",config
.pr_s
.othert_recv
);
1114 olog("-- Total sessions tracked :%12lu\n", cxtrackerid
);
1115 olog("-- Total assets detected :%12u\n",config
.pr_s
.assets
);
1116 olog("-- Total TCP OS fingerprints detected :%12u\n",config
.pr_s
.tcp_os_assets
);
1117 olog("-- Total UDP OS fingerprints detected :%12u\n",config
.pr_s
.udp_os_assets
);
1118 olog("-- Total ICMP OS fingerprints detected :%12u\n",config
.pr_s
.icmp_os_assets
);
1119 olog("-- Total DHCP OS fingerprints detected :%12u\n",config
.pr_s
.dhcp_os_assets
);
1120 olog("-- Total TCP service assets detected :%12u\n",config
.pr_s
.tcp_services
);
1121 olog("-- Total TCP client assets detected :%12u\n",config
.pr_s
.tcp_clients
);
1122 olog("-- Total UDP service assets detected :%12u\n",config
.pr_s
.udp_services
);
1123 olog("-- Total UDP client assets detected :%12u\n",config
.pr_s
.udp_clients
);
1130 olog(" $ prads [options]\n");
1132 olog(" OPTIONS:\n");
1134 olog(" -i <iface> Network device <iface> (default: eth0).\n");
1135 olog(" -r <file> Read pcap <file>.\n");
1136 olog(" -c <file> Read config from <file>\n");
1137 olog(" -b <filter> Apply Berkeley packet filter <filter>.\n");
1138 olog(" -u <user> Run as user <user> (Default: uid 1)\n");
1139 olog(" -g <group> Run as group <group> (Default: gid 1)\n");
1140 olog(" -d Do not drop privileges.\n");
1141 olog(" -a <nets> Specify home nets (eg: '192.168.0.0/25,10.0.0.0/255.0.0.0').\n");
1142 olog(" -D Daemonize.\n");
1143 //olog(" -d to logdir\n");
1144 olog(" -p <pidfile> Name of pidfile - inside chroot\n");
1145 olog(" -l <file> Log assets to <file> (default: '%s')\n", config
.assetlog
);
1146 olog(" -f <FIFO> Log assets to <FIFO>\n");
1147 olog(" -B Log connections to ringbuffer\n");
1148 olog(" -C <dir> Chroot into <dir> before dropping privs.\n");
1149 olog(" -XFRMSAK Flag picker: X - clear flags, F:FIN, R:RST, M:MAC, S:SYN, A:ACK, K:SYNACK\n");
1150 olog(" -UTtI Service checks: U:UDP, T:TCP-server, I:ICMP, t:TCP-cLient\n");
1151 olog(" -P DHCP fingerprinting.\n");
1152 olog(" -s <snaplen> Dump <snaplen> bytes of each payload.\n");
1153 olog(" -v Verbose output - repeat for more verbosity.\n");
1154 olog(" -q Quiet - try harder not to produce output.\n");
1155 olog(" -L <dir> log cxtracker type output to <dir>.\n");
1156 olog(" -O Connection tracking [O]utput - per-packet!\n");
1157 olog(" -x Conne[x]ion tracking output - New, expired and ended.\n");
1158 olog(" -Z Passive DNS (Experimental).\n");
1159 olog(" -H DHCP fingerprinting (Expermiental).\n");
1160 olog(" -h This help message.\n");
1163 int load_bpf(globalconfig
* conf
, const char* file
)
1168 struct stat statbuf
;
1169 fs
= fopen(file
, "r");
1174 if(fstat(fileno(fs
), &statbuf
)){
1175 perror("oh god my eyes!");
1179 sz
= statbuf
.st_size
;
1180 if(conf
->bpff
) free(conf
->bpff
);
1181 if(!(conf
->bpff
= calloc(sz
, 1))){
1182 perror("mem alloc");
1186 lineptr
= conf
->bpff
;
1187 // read file but ignore comments and newlines
1188 while(fgets(lineptr
, sz
-(conf
->bpff
-lineptr
), fs
)) {
1191 if(lineptr
[i
] != ' ')
1193 // scan ahead and kill comments
1194 for(i
=0;lineptr
[i
];i
++)
1196 case '#': // comment on the line
1197 lineptr
[i
] = '\n'; // end line here
1198 lineptr
[i
+1] = '\0'; // ends outer loop & string
1199 case '\n': // end-of-line
1200 case '\0': // end-of-string
1203 if(i
<=1) continue; // empty line
1204 lineptr
= lineptr
+strlen(lineptr
);
1207 olog("[*] BPF file\t\t %s (%d bytes read)\n", conf
->bpf_file
, sz
);
1208 if(config
.verbose
) olog("BPF: { %s}\n", conf
->bpff
);
1213 int prads_initialize(globalconfig
*conf
)
1215 if (conf
->bpf_file
) {
1216 if(load_bpf(conf
, conf
->bpf_file
)){
1217 elog("[!] Failed to load bpf from file.\n");
1220 if (conf
->pcap_file
) {
1222 if(stat(conf
->pcap_file
, &sb
) || !sb
.st_size
) {
1223 elog("[!] '%s' not a pcap. Bailing.\n", conf
->pcap_file
);
1227 /* Read from PCAP file specified by '-r' switch. */
1228 olog("[*] Reading from file %s\n", conf
->pcap_file
);
1229 if (!(conf
->handle
= pcap_open_offline(conf
->pcap_file
, conf
->errbuf
))) {
1230 olog("[*] Unable to open %s. (%s)\n", conf
->pcap_file
, conf
->errbuf
);
1235 if(conf
->drop_privs_flag
) {
1237 conf
->drop_privs_flag
= 0;
1238 elog("[!] Can't drop privileges, not root.\n");
1240 /* getting numerical ids before chroot call */
1241 gid
= get_gid(conf
->group_name
);
1242 uid
= get_uid(conf
->user_name
, &gid
);
1244 elog("[!] Problem finding user %s group %s\n", conf
->user_name
, conf
->group_name
);
1247 if (gid
&& getuid() == 0 && initgroups(conf
->user_name
, gid
) < 0) {
1248 elog("[!] Unable to init group names (%s/%u)\n", conf
->user_name
, gid
);
1253 /* * look up an available device if non specified */
1254 if (conf
->dev
== 0x0)
1255 conf
->dev
= pcap_lookupdev(conf
->errbuf
);
1259 elog("[*] Error looking up device: '%s', try setting device with -i flag.\n", conf
->errbuf
);
1263 olog("[*] Device: %s\n", conf
->dev
);
1265 if ((conf
->handle
= pcap_open_live(conf
->dev
, SNAPLENGTH
, 1, 500, conf
->errbuf
)) == NULL
) {
1266 elog("[!] Error pcap_open_live: %s \n", conf
->errbuf
);
1269 /* * B0rk if we see an error... */
1270 if (strlen(conf
->errbuf
) > 0) {
1271 elog("[*] Error errbuf: %s \n", conf
->errbuf
);
1275 if(conf
->chroot_dir
){
1277 olog("[*] Chrooting to dir '%s'..\n", conf
->chroot_dir
);
1279 elog("[!] failed to chroot\n");
1283 /* gotta create/chown pidfile before dropping privs */
1285 touch_pid_file(conf
->pidfile
, uid
, gid
);
1287 if (conf
->drop_privs_flag
&& ( uid
|| gid
)) {
1288 olog("[*] Dropping privileges to %s:%s...\n",
1289 conf
->user_name
?conf
->user_name
:"", conf
->group_name
?conf
->group_name
:"");
1290 drop_privs(uid
, gid
);
1294 if (!is_valid_path(conf
->pidfile
)){
1295 elog("[!] Pidfile '%s' is not writable.\n", conf
->pidfile
);
1299 if (conf
->daemon_flag
) {
1300 olog("[*] Daemonizing...\n");
1303 if (conf
->pidfile
) {
1305 if((rc
=create_pid_file(conf
->pidfile
))) {
1306 elog("[!] pidfile error, wrong permissions or prads already running? %s: %s\n", conf
->pidfile
, strerror(rc
));
1314 void prads_version(void)
1316 olog("[*] prads %s\n", VERSION
);
1317 olog(" Using %s\n", pcap_lib_version());
1318 olog(" Using PCRE version %s\n", pcre_version());
1322 int main(int argc
, char *argv
[])
1325 int ch
= 0, verbose_already
= 0;
1327 vlog(2, "%08x =? %08x, endianness: %s\n\n", 0xdeadbeef, ntohl(0xdeadbeef), (0xdead == ntohs(0xdead)?"big":"little") );
1329 memset(&config
, 0, sizeof(globalconfig
));
1330 set_default_config_options(&config
);
1332 inpacket
= gameover
= intr_flag
= 0;
1334 signal(SIGTERM
, game_over
);
1335 signal(SIGINT
, game_over
);
1336 signal(SIGQUIT
, game_over
);
1337 signal(SIGALRM
, set_end_sessions
);
1338 signal(SIGHUP
, reparse_conf
);
1339 signal(SIGUSR1
, set_end_sessions
);
1341 signal(SIGUSR1
, cxt_log_buckets
);
1344 // do first-pass args parse for commandline-passed config file
1346 while ((ch
= getopt(argc
, argv
, ARGS
)) != -1)
1349 config
.file
= optarg
;
1355 config
.cflags
|= CONFIG_QUIET
;
1365 verbose_already
= 1;
1367 parse_config_file(config
.file
);
1369 // reset verbosity before 2nd coming, but only if set on cli
1375 if(parse_args(&config
, argc
, argv
, ARGS
) != 0){
1380 // we're done parsing configs - now initialize prads
1382 if(ISSET_CONFIG_SYSLOG(config
)) {
1383 openlog("prads", LOG_PID
| LOG_CONS
, LOG_DAEMON
);
1386 if(config
.cxtlogdir
){
1387 static char log_prefix
[PATH_MAX
];
1388 snprintf(log_prefix
, PATH_MAX
, "%sstats.%s",
1389 config
.cxtlogdir
, config
.dev
? config
.dev
: "pcap");
1390 rc
= init_logging(LOG_SGUIL
, log_prefix
, 0);
1392 perror("Logging to sguil output failed!");
1395 if (config
.ringbuffer
) {
1396 rc
= init_logging(LOG_RINGBUFFER
, NULL
, config
.cflags
);
1398 perror("Logging to ringbuffer failed!");
1401 if (config
.cflags
& (CONFIG_VERBOSE
| CONFIG_CXWRITE
| CONFIG_CONNECT
)) {
1402 rc
= init_logging(LOG_STDOUT
, NULL
, config
.cflags
);
1403 if(rc
) perror("Logging to standard out failed!");
1406 if(config
.assetlog
) {
1407 olog("logging to file '%s'\n", config
.assetlog
);
1408 rc
= init_logging(LOG_FILE
, config
.assetlog
, config
.cflags
);
1409 if(rc
) perror("Logging to file failed!");
1412 olog("logging to FIFO '%s'\n", config
.fifo
);
1413 rc
= init_logging(LOG_FIFO
, config
.fifo
, config
.cflags
);
1414 if(rc
) perror("Logging to fifo failed!");
1417 parse_nets(config
.s_net
, network
);
1419 olog("[*] Loading fingerprints:\n");
1420 /* helper macro to avoid duplicate code */
1421 #define load_foo(func, conf, flag, file, hash, len, dump) \
1422 if(config. conf & flag) { \
1424 olog(" %-11s %s\n", # flag, (config. file)); \
1425 _rc = func (config. file, & config. hash, config. len); \
1426 if(_rc) perror( #flag " load failed!"); \
1427 else if(config.verbose > 1) { \
1428 printf("[*] Dumping " #flag " signatures:\n"); \
1429 dump (config. hash, config. len); \
1430 printf("[*] " #flag " signature dump ends.\n"); \
1434 load_foo(load_mac
, cof
, CS_MAC
, sig_file_mac
, sig_mac
, mac_hashsize
, dump_macs
);
1435 load_foo(load_sigs
, ctf
, CO_SYN
, sig_file_syn
, sig_syn
, sig_hashsize
, dump_sigs
);
1436 load_foo(load_sigs
, ctf
, CO_SYNACK
, sig_file_synack
, sig_synack
, sig_hashsize
, dump_sigs
);
1437 load_foo(load_sigs
, ctf
, CO_ACK
, sig_file_ack
, sig_ack
, sig_hashsize
, dump_sigs
);
1438 load_foo(load_sigs
, ctf
, CO_FIN
, sig_file_fin
, sig_fin
, sig_hashsize
, dump_sigs
);
1439 load_foo(load_sigs
, ctf
, CO_RST
, sig_file_rst
, sig_rst
, sig_hashsize
, dump_sigs
);
1440 load_foo(load_dhcp_sigs
, ctf
, CO_DHCP
, sig_file_dhcp
, sig_dhcp
, sig_hashsize
, dump_dhcp_sigs
);
1441 load_foo(load_servicefp_file
, cof
, CS_TCP_SERVER
, sig_file_serv_tcp
, sig_serv_tcp
, sig_hashsize
, dump_sig_service
);
1442 load_foo(load_servicefp_file
, cof
, CS_UDP_SERVICES
, sig_file_serv_udp
, sig_serv_udp
, sig_hashsize
, dump_sig_service
);
1443 load_foo(load_servicefp_file
, cof
, CS_TCP_CLIENT
, sig_file_cli_tcp
, sig_client_tcp
, sig_hashsize
, dump_sig_service
);
1446 display_config(&config
);
1448 prads_initialize(&config
);
1452 /** segfaults on empty pcap! */
1453 struct bpf_program cfilter
; /**/
1454 if ((pcap_compile(config
.handle
, &cfilter
, config
.bpff
, 1, config
.net_mask
)) == -1) {
1455 olog("[*] Error pcap_compile user_filter: %s\n", pcap_geterr(config
.handle
));
1459 if (pcap_setfilter(config
.handle
, &cfilter
)) {
1460 olog("[*] Unable to set pcap filter! %s", pcap_geterr(config
.handle
));
1462 pcap_freecode(&cfilter
);
1465 olog("[*] Sniffing...\n");
1466 pcap_loop(config
.handle
, -1, got_packet
, NULL
);