From: Alan T. DeKok Date: Sat, 7 Aug 2010 21:04:19 +0000 (+0200) Subject: Added ability to write to pcap file X-Git-Tag: release_3_0_0_beta0~1303 X-Git-Url: http://www.project-moonshot.org/gitweb/?p=freeradius.git;a=commitdiff_plain;h=3bc0f9ff9f506cffafb593530a0f17871b7d0945 Added ability to write to pcap file --- diff --git a/src/main/radsniff.c b/src/main/radsniff.c index b7bb8fa..d5c4256 100644 --- a/src/main/radsniff.c +++ b/src/main/radsniff.c @@ -42,6 +42,8 @@ static int minimal = 0; static int do_sort = 0; struct timeval start_pcap = {0, 0}; static rbtree_t *filter_tree = NULL; +static pcap_dumper_t *pcap_dumper = NULL; + typedef int (*rbcmp)(const void *, const void *); static int filter_packet(RADIUS_PACKET *packet) @@ -200,10 +202,17 @@ static void got_packet(uint8_t *args, const struct pcap_pkthdr *header, const ui args = args; /* -Wunused */ /* Define our packet's attributes */ - ethernet = (const struct ethernet_header*)(data); - ip = (const struct ip_header*)(data + size_ethernet); - udp = (const struct udp_header*)(data + size_ethernet + size_ip); - payload = (const uint8_t *)(data + size_ethernet + size_ip + size_udp); + + if ((data[0] == 2) && (data[1] == 0) && + (data[2] == 0) && (data[3] == 0)) { + ip = (const struct ip_header*) (data + 4); + + } else { + ethernet = (const struct ethernet_header*)(data); + ip = (const struct ip_header*)(data + size_ethernet); + } + udp = (const struct udp_header*)(((const uint8_t *) ip) + size_ip); + payload = (const uint8_t *)(((const uint8_t *) udp) + size_udp); packet = malloc(sizeof(*packet)); if (!packet) { @@ -220,14 +229,14 @@ static void got_packet(uint8_t *args, const struct pcap_pkthdr *header, const ui packet->dst_port = ntohs(udp->udp_dport); packet->data = payload; - packet->data_len = header->len - size_ethernet - size_ip - size_udp; + packet->data_len = header->len - (payload - data); if (!rad_packet_ok(packet, 0)) { - fr_perror("Packet"); + printf("Packet: %s\n", fr_strerror()); - fprintf(stderr, "\tFrom: %s:%d\n", inet_ntoa(ip->ip_src), ntohs(udp->udp_sport)); - fprintf(stderr, "\tTo: %s:%d\n", inet_ntoa(ip->ip_dst), ntohs(udp->udp_dport)); - fprintf(stderr, "\tType: %s\n", fr_packet_codes[packet->code]); + printf("\tFrom: %s:%d\n", inet_ntoa(ip->ip_src), ntohs(udp->udp_sport)); + printf("\tTo: %s:%d\n", inet_ntoa(ip->ip_dst), ntohs(udp->udp_dport)); + printf("\tType: %s\n", fr_packet_codes[packet->code]); free(packet); return; @@ -247,6 +256,12 @@ static void got_packet(uint8_t *args, const struct pcap_pkthdr *header, const ui DEBUG("Packet number %d doesn't match\n", count++); return; } + + if (pcap_dumper) { + pcap_dump((void *) pcap_dumper, header, data); + goto check_filter; + } + printf("%s Id %d\t", fr_packet_codes[packet->code], packet->id); /* Print the RADIUS packet */ @@ -272,6 +287,7 @@ static void got_packet(uint8_t *args, const struct pcap_pkthdr *header, const ui printf("\n"); fflush(stdout); + check_filter: /* * If we're doing filtering, Access-Requests are cached * in the filter tree. @@ -315,6 +331,7 @@ int main(int argc, char *argv[]) char *pcap_filter = NULL; char *radius_filter = NULL; char *filename = NULL; + char *dump_file = NULL; int packet_count = -1; /* how many packets to sniff */ int opt; FR_TOKEN parsecode; @@ -325,7 +342,7 @@ int main(int argc, char *argv[]) dev = pcap_lookupdev(errbuf); /* Get options */ - while ((opt = getopt(argc, argv, "c:d:f:hi:I:mp:r:s:SxX")) != EOF) { + while ((opt = getopt(argc, argv, "c:d:f:hi:I:mp:r:s:Sw:xX")) != EOF) { switch (opt) { case 'c': @@ -365,6 +382,9 @@ int main(int argc, char *argv[]) case 'S': do_sort = 1; break; + case 'w': + dump_file = optarg; + break; case 'x': case 'X': /* for backwards compatibility */ fr_debug_flag++; @@ -425,12 +445,13 @@ int main(int argc, char *argv[]) /* Open the device so we can spy */ if (filename) { descr = pcap_open_offline(filename, errbuf); + } else if (!dev) { fprintf(stderr, "radsniff: No filename or device was specified.\n"); exit(1); } else { - descr = pcap_open_live(dev, SNAPLEN, 1, 0, errbuf); + descr = pcap_open_live(dev, 65536, 1, 0, errbuf); } if (descr == NULL) { @@ -438,6 +459,14 @@ int main(int argc, char *argv[]) exit(1); } + if (dump_file) { + pcap_dumper = pcap_dump_open(descr, dump_file); + if (!pcap_dumper) { + fprintf(stderr, "radsniff: Failed opening output file (%s)\n", pcap_geterr(descr)); + exit(1); + } + } + /* Apply the rules */ if( pcap_compile(descr, &fp, pcap_filter, 0, netp) == -1) { @@ -446,7 +475,7 @@ int main(int argc, char *argv[]) } if (pcap_setfilter(descr, &fp) == -1) { - printf("radsniff: pcap_setfilter failed\n"); + fprintf(stderr, "radsniff: pcap_setfilter failed\n"); exit(1); }