From 6f9c2bdcd68e1e5f40d999ce98d5f775da736617 Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Sun, 17 Jan 2010 11:15:32 +0000 Subject: [PATCH] Added automatic device selection if user runs only "netsniff-ng" without params. Line width for indent switched to 120. 80 makes code look ugly... git-svn-id: http://netsniff-ng.googlecode.com/svn/trunk@173 21e0ff64-9a0b-11de-825e-994487f65616 --- src/include/netsniff-ng/bucket_hash.h | 5 +- src/include/netsniff-ng/misc.h | 4 +- src/include/netsniff-ng/pcap.h | 3 +- src/include/netsniff-ng/print.h | 3 +- src/include/netsniff-ng/rx_ring.h | 7 +- src/include/netsniff-ng/types.h | 3 +- src/lib/bucket_hash.c | 2 - src/lib/misc.c | 22 ++-- src/lib/pcap.c | 6 +- src/lib/print.c | 24 ++-- src/lib/rx_ring.c | 60 +++------- src/lib/system.c | 6 +- src/netsniff-ng.c | 215 ++++++++++++++++++---------------- 13 files changed, 160 insertions(+), 200 deletions(-) diff --git a/src/include/netsniff-ng/bucket_hash.h b/src/include/netsniff-ng/bucket_hash.h index a88fdee5..e31b2323 100644 --- a/src/include/netsniff-ng/bucket_hash.h +++ b/src/include/netsniff-ng/bucket_hash.h @@ -35,12 +35,9 @@ * Bucket hash related stuff */ - #ifndef _NET_HASH_H_ #define _NET_HASH_H_ #include - - -#endif /* _NET_HASH_H_ */ +#endif /* _NET_HASH_H_ */ diff --git a/src/include/netsniff-ng/misc.h b/src/include/netsniff-ng/misc.h index 6545e8eb..aaad142e 100644 --- a/src/include/netsniff-ng/misc.h +++ b/src/include/netsniff-ng/misc.h @@ -55,9 +55,7 @@ extern void header(void); * @after: second timespec * @before: first timespec */ -static inline int timespec_subtract(struct timespec *result, - struct timespec *after, - struct timespec *before) +static inline int timespec_subtract(struct timespec *result, struct timespec *after, struct timespec *before) { result->tv_nsec = after->tv_nsec - before->tv_nsec; diff --git a/src/include/netsniff-ng/pcap.h b/src/include/netsniff-ng/pcap.h index 12527ab1..9fe147a9 100644 --- a/src/include/netsniff-ng/pcap.h +++ b/src/include/netsniff-ng/pcap.h @@ -104,7 +104,6 @@ struct pcap_sf_pkthdr { }; extern int sf_write_header(FILE * fp, int linktype, int thiszone, int snaplen); -extern void -pcap_dump(FILE * f, struct tpacket_hdr *tp_h, const struct ethhdr const *sp); +extern void pcap_dump(FILE * f, struct tpacket_hdr *tp_h, const struct ethhdr const *sp); #endif /* _PCAP_H */ diff --git a/src/include/netsniff-ng/print.h b/src/include/netsniff-ng/print.h index bff2e5e3..72152b26 100644 --- a/src/include/netsniff-ng/print.h +++ b/src/include/netsniff-ng/print.h @@ -44,7 +44,6 @@ /* Function signatures */ -extern void print_packet_buffer_mode_1(ring_buff_bytes_t * rbb, - const struct tpacket_hdr *tp); +extern void print_packet_buffer_mode_1(ring_buff_bytes_t * rbb, const struct tpacket_hdr *tp); #endif /* _NET_PRINT_H_ */ diff --git a/src/include/netsniff-ng/rx_ring.h b/src/include/netsniff-ng/rx_ring.h index 5a547cda..3d2d5749 100644 --- a/src/include/netsniff-ng/rx_ring.h +++ b/src/include/netsniff-ng/rx_ring.h @@ -73,9 +73,7 @@ static inline void alloc_frame_buffer(ring_buff_t * rb) assert(rb); - rb->frames = - (struct iovec *)malloc(rb->layout.tp_frame_nr * - sizeof(*rb->frames)); + rb->frames = (struct iovec *)malloc(rb->layout.tp_frame_nr * sizeof(*rb->frames)); if (!rb->frames) { err("No mem left!\n"); exit(EXIT_FAILURE); @@ -84,8 +82,7 @@ static inline void alloc_frame_buffer(ring_buff_t * rb) memset(rb->frames, 0, rb->layout.tp_frame_nr * sizeof(*rb->frames)); for (i = 0; i < rb->layout.tp_frame_nr; ++i) { - rb->frames[i].iov_base = - (void *)((long)rb->buffer) + (i * rb->layout.tp_frame_size); + rb->frames[i].iov_base = (void *)((long)rb->buffer) + (i * rb->layout.tp_frame_size); rb->frames[i].iov_len = rb->layout.tp_frame_size; } } diff --git a/src/include/netsniff-ng/types.h b/src/include/netsniff-ng/types.h index 67702774..cc3570d1 100644 --- a/src/include/netsniff-ng/types.h +++ b/src/include/netsniff-ng/types.h @@ -66,8 +66,7 @@ typedef struct frame_map { struct sockaddr_ll s_ll __attribute__ ((aligned(TPACKET_ALIGNMENT))); } frame_map_t; -typedef void (*print_packet_buff_t) (ring_buff_bytes_t *, - const struct tpacket_hdr *); +typedef void (*print_packet_buff_t) (ring_buff_bytes_t *, const struct tpacket_hdr *); typedef struct system_data { /* Some more or less boolean conf values */ diff --git a/src/lib/bucket_hash.c b/src/lib/bucket_hash.c index 3e00e43e..21b388cf 100644 --- a/src/lib/bucket_hash.c +++ b/src/lib/bucket_hash.c @@ -38,5 +38,3 @@ #include #include - - diff --git a/src/lib/misc.c b/src/lib/misc.c index 587a5112..083fbd24 100644 --- a/src/lib/misc.c +++ b/src/lib/misc.c @@ -49,13 +49,13 @@ void help(void) { printf("%s %s\n\n", PROGNAME_STRING, VERSION_STRING); - printf("%s is a high performance network sniffer for packet\n", - PROGNAME_STRING); + printf("%s is a high performance network sniffer for packet\n", PROGNAME_STRING); printf("inspection that acts as a raw socket sniffer with kernelspace\n"); printf("bpf and a \"zero-copy\" mode receive/transmit ring.\n"); printf("\n"); - printf("Options, mandatory:\n"); + printf("Options for net dev:\n"); printf(" -d|--dev use device for capturing packets, e.g. `eth0`\n"); + printf(" -m|--mtu temporarily adjust MTU of NIC\n"); printf("\n"); printf("Options for packet dumping/replaying:\n"); printf(" -p|--dump dump all matching packets in a pcap file\n"); @@ -90,7 +90,6 @@ void help(void) printf(" -S|--sockfile use file as uds inode (required if -D)\n"); printf("\n"); printf("Options, misc:\n"); - printf(" -m|--mtu temporarily adjust MTU of NIC\n"); printf(" -v|--version prints out version\n"); printf(" -h|--help prints out this help\n"); printf("\n"); @@ -114,8 +113,7 @@ void help(void) void version(void) { printf("%s %s\n\n", PROGNAME_STRING, VERSION_STRING); - printf("%s is a high performance network sniffer for packet\n", - PROGNAME_STRING); + printf("%s is a high performance network sniffer for packet\n", PROGNAME_STRING); printf("inspection that acts as a raw socket sniffer with kernelspace\n"); printf("bpf and a \"zero-copy\" mode receive/transmit ring.\n\n"); printf("%s", MOOH); /* ;) */ @@ -123,8 +121,7 @@ void version(void) printf("%s can be used for protocol analysis and\n" "reverse engineering, network debugging, measurement of\n" "performance throughput or network statistics creation of\n" - "incoming packets on central network nodes like routers\n" - "or firewalls.\n", PROGNAME_STRING); + "incoming packets on central network nodes like routers\n" "or firewalls.\n", PROGNAME_STRING); printf("\n"); printf("Please report bugs to \n"); printf("Copyright (C) 2009, 2010 Daniel Borkmann and Emmanuel Roullit\n"); @@ -160,16 +157,13 @@ void header(void) exit(EXIT_FAILURE); } - info("%s %s -- pid (%d)\n\n", PROGNAME_STRING, VERSION_STRING, - (int)getpid()); + info("%s %s -- pid (%d)\n\n", PROGNAME_STRING, VERSION_STRING, (int)getpid()); info("nice (%d), scheduler (%d prio %d)\n", - getpriority(PRIO_PROCESS, getpid()), - sched_getscheduler(getpid()), sp.sched_priority); + getpriority(PRIO_PROCESS, getpid()), sched_getscheduler(getpid()), sp.sched_priority); info("%ld of %ld CPUs online, affinity bitstring (%s)\n\n", - sysconf(_SC_NPROCESSORS_ONLN), - sysconf(_SC_NPROCESSORS_CONF), get_cpu_affinity(cpu_string, len)); + sysconf(_SC_NPROCESSORS_ONLN), sysconf(_SC_NPROCESSORS_CONF), get_cpu_affinity(cpu_string, len)); free(cpu_string); } diff --git a/src/lib/pcap.c b/src/lib/pcap.c index a3151313..2e468c0e 100644 --- a/src/lib/pcap.c +++ b/src/lib/pcap.c @@ -58,8 +58,7 @@ int sf_write_header(FILE * fp, int linktype, int thiszone, int snaplen) return (0); } -void -pcap_dump(FILE * f, struct tpacket_hdr *tp_h, const struct ethhdr const *sp) +void pcap_dump(FILE * f, struct tpacket_hdr *tp_h, const struct ethhdr const *sp) { struct pcap_sf_pkthdr sf_hdr; @@ -103,8 +102,7 @@ FILE *pcap_validate(FILE * pcap) if (hdr.magic != TCPDUMP_MAGIC || hdr.version_major != PCAP_VERSION_MAJOR - || hdr.version_minor != PCAP_VERSION_MINOR - || hdr.linktype != LINKTYPE_EN10MB) { + || hdr.version_minor != PCAP_VERSION_MINOR || hdr.linktype != LINKTYPE_EN10MB) { errno = EINVAL; perr("This file is certainly not a valid pcap :"); return (NULL); diff --git a/src/lib/print.c b/src/lib/print.c index 8a73c0d8..eaeb971b 100644 --- a/src/lib/print.c +++ b/src/lib/print.c @@ -81,8 +81,7 @@ * @tty_len: width of terminal * @tty_off: current offset of tty_len */ -static void inline dump_hex(ring_buff_bytes_t * buff, int len, size_t tty_len, - size_t tty_off) +static void inline dump_hex(ring_buff_bytes_t * buff, int len, size_t tty_len, size_t tty_off) { for (; len-- > 0; tty_off += 3, buff++) { if (unlikely(tty_off >= tty_len - 3)) { @@ -100,8 +99,7 @@ static void inline dump_hex(ring_buff_bytes_t * buff, int len, size_t tty_len, * @tty_len: width of terminal * @tty_off: current offset of tty_len */ -static void inline dump_printable(ring_buff_bytes_t * buff, int len, - size_t tty_len, size_t tty_off) +static void inline dump_printable(ring_buff_bytes_t * buff, int len, size_t tty_len, size_t tty_off) { for (; len-- > 0; tty_off += 2, buff++) { if (unlikely(tty_off >= tty_len - 3)) { @@ -130,8 +128,7 @@ static void inline dump_ethhdr_all(struct ethhdr *eth) ((uint8_t *) eth->h_dest)[2], ((uint8_t *) eth->h_dest)[3], ((uint8_t *) eth->h_dest)[4], ((uint8_t *) eth->h_dest)[5]); - info("Proto (0x%.2x%.2x)", - ((uint8_t *) & eth->h_proto)[0], ((uint8_t *) & eth->h_proto)[1]); + info("Proto (0x%.2x%.2x)", ((uint8_t *) & eth->h_proto)[0], ((uint8_t *) & eth->h_proto)[1]); info(" ] "); } @@ -234,8 +231,7 @@ static void inline dump_tcphdr_all(struct tcphdr *tcp) * @len: len * @tty_len: width of terminal */ -static void inline dump_payload_hex_all(ring_buff_bytes_t * rbb, int len, - int tty_len) +static void inline dump_payload_hex_all(ring_buff_bytes_t * rbb, int len, int tty_len) { info(" [ Payload hex ("); dump_hex(rbb, len, tty_len, 14); @@ -248,8 +244,7 @@ static void inline dump_payload_hex_all(ring_buff_bytes_t * rbb, int len, * @len: len * @tty_len: width of terminal */ -static void inline dump_payload_char_all(ring_buff_bytes_t * rbb, int len, - int tty_len) +static void inline dump_payload_char_all(ring_buff_bytes_t * rbb, int len, int tty_len) { info(" [ Payload char ("); dump_printable(rbb, len, tty_len, 14); @@ -261,14 +256,12 @@ static void inline dump_payload_char_all(ring_buff_bytes_t * rbb, int len, * @rbb: payload * @tp: kernel packet header */ -void print_packet_buffer_mode_1(ring_buff_bytes_t * rbb, - const struct tpacket_hdr *tp) +void print_packet_buffer_mode_1(ring_buff_bytes_t * rbb, const struct tpacket_hdr *tp) { size_t off_n, off_o; int tty_len = get_tty_length(); - info("%d Byte, Timestamp (%u.%u s) \n", tp->tp_len, tp->tp_sec, - tp->tp_usec); + info("%d Byte, Timestamp (%u.%u s) \n", tp->tp_len, tp->tp_sec, tp->tp_usec); dump_ethhdr_all((struct ethhdr *)rbb); info("\n"); @@ -287,8 +280,7 @@ void print_packet_buffer_mode_1(ring_buff_bytes_t * rbb, info("\n"); off_o = off_n; off_n += sizeof(struct tcphdr); - } else if (((struct iphdr *)(rbb + off_o))->protocol == - IPPROTO_UDP) { + } else if (((struct iphdr *)(rbb + off_o))->protocol == IPPROTO_UDP) { dump_udphdr_all((struct udphdr *)(rbb + off_n)); info("\n"); off_o = off_n; diff --git a/src/lib/rx_ring.c b/src/lib/rx_ring.c index 6e0301de..a8a5611e 100644 --- a/src/lib/rx_ring.c +++ b/src/lib/rx_ring.c @@ -101,8 +101,7 @@ void destroy_virt_ring(int sock, ring_buff_t * rb) assert(rb); memset(&(rb->layout), 0, sizeof(rb->layout)); - setsockopt(sock, SOL_PACKET, PACKET_RX_RING, (void *)&(rb->layout), - sizeof(rb->layout)); + setsockopt(sock, SOL_PACKET, PACKET_RX_RING, (void *)&(rb->layout), sizeof(rb->layout)); if (rb->buffer) { munmap(rb, rb->len); @@ -132,19 +131,14 @@ void create_virt_ring(int sock, ring_buff_t * rb) /* max: 15 for i386 */ rb->layout.tp_block_nr = 1 << 13; - rb->layout.tp_frame_nr = - rb->layout.tp_block_size / rb->layout.tp_frame_size * - rb->layout.tp_block_nr; + rb->layout.tp_frame_nr = rb->layout.tp_block_size / rb->layout.tp_frame_size * rb->layout.tp_block_nr; __retry_sso: - ret = setsockopt(sock, SOL_PACKET, PACKET_RX_RING, - (void *)&(rb->layout), sizeof(rb->layout)); + ret = setsockopt(sock, SOL_PACKET, PACKET_RX_RING, (void *)&(rb->layout), sizeof(rb->layout)); if (errno == ENOMEM && rb->layout.tp_block_nr > 1) { rb->layout.tp_block_nr >>= 1; - rb->layout.tp_frame_nr = - rb->layout.tp_block_size / rb->layout.tp_frame_size * - rb->layout.tp_block_nr; + rb->layout.tp_frame_nr = rb->layout.tp_block_size / rb->layout.tp_frame_size * rb->layout.tp_block_nr; goto __retry_sso; } @@ -159,12 +153,9 @@ void create_virt_ring(int sock, ring_buff_t * rb) rb->len = rb->layout.tp_block_size * rb->layout.tp_block_nr; info("%.2f MB allocated for rx ring \n", 1.f * rb->len / (1024 * 1024)); - info(" [ %d blocks, %d frames ] \n", rb->layout.tp_block_nr, - rb->layout.tp_frame_nr); - info(" [ %d frames per block ]\n", - rb->layout.tp_block_size / rb->layout.tp_frame_size); - info(" [ framesize: %d bytes, blocksize: %d bytes ]\n\n", - rb->layout.tp_frame_size, rb->layout.tp_block_size); + info(" [ %d blocks, %d frames ] \n", rb->layout.tp_block_nr, rb->layout.tp_frame_nr); + info(" [ %d frames per block ]\n", rb->layout.tp_block_size / rb->layout.tp_frame_size); + info(" [ framesize: %d bytes, blocksize: %d bytes ]\n\n", rb->layout.tp_frame_size, rb->layout.tp_block_size); } /** @@ -177,8 +168,7 @@ void mmap_virt_ring(int sock, ring_buff_t * rb) { assert(rb); - rb->buffer = mmap(0, rb->len, PROT_READ | PROT_WRITE, MAP_SHARED, sock, - 0); + rb->buffer = mmap(0, rb->len, PROT_READ | PROT_WRITE, MAP_SHARED, sock, 0); if (rb->buffer == MAP_FAILED) { perr("mmap: cannot mmap the rx ring: %d - ", errno); @@ -210,8 +200,7 @@ void bind_dev_to_ring(int sock, int ifindex, ring_buff_t * rb) rb->params.sll_halen = 0; rb->params.sll_pkttype = 0; - ret = bind(sock, (struct sockaddr *)&(rb->params), - sizeof(struct sockaddr_ll)); + ret = bind(sock, (struct sockaddr *)&(rb->params), sizeof(struct sockaddr_ll)); if (ret < 0) { perr("bind: cannot bind device: %d - ", errno); @@ -241,11 +230,9 @@ void put_dev_into_promisc_mode(int sock, int ifindex) will not work with ioctl(). There, you have to manage things manually ... */ - ret = setsockopt(sock, SOL_PACKET, PACKET_ADD_MEMBERSHIP, - &mr, sizeof(mr)); + ret = setsockopt(sock, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr, sizeof(mr)); if (ret < 0) { - perr("setsockopt: cannot set dev %d to promisc mode: %d - ", - ifindex, errno); + perr("setsockopt: cannot set dev %d to promisc mode: %d - ", ifindex, errno); close(sock); exit(EXIT_FAILURE); @@ -271,8 +258,7 @@ void inject_kernel_bpf(int sock, struct sock_filter *bpf, int len) filter.len = len / sizeof(*bpf); filter.filter = bpf; - ret = setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, - &filter, sizeof(filter)); + ret = setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter)); if (ret < 0) { perr("setsockopt: filter cannot be injected: %d - ", errno); @@ -290,8 +276,7 @@ void reset_kernel_bpf(int sock) int ret; int foo = 0; - ret = setsockopt(sock, SOL_SOCKET, SO_DETACH_FILTER, - &foo, sizeof(foo)); + ret = setsockopt(sock, SOL_SOCKET, SO_DETACH_FILTER, &foo, sizeof(foo)); if (ret < 0) { perr("setsockopt: cannot reset filter: %d - ", errno); @@ -317,8 +302,7 @@ int ethdev_to_ifindex(int sock, char *dev) ret = ioctl(sock, SIOCGIFINDEX, ðreq); if (ret < 0) { - perr("ioctl: cannot determine dev number for %s: %d - ", - ethreq.ifr_name, errno); + perr("ioctl: cannot determine dev number for %s: %d - ", ethreq.ifr_name, errno); close(sock); exit(EXIT_FAILURE); @@ -342,10 +326,8 @@ void net_stat(int sock) ret = getsockopt(sock, SOL_PACKET, PACKET_STATISTICS, &kstats, &slen); if (ret > -1) { info("%d frames incoming\n", kstats.tp_packets); - info("%d frames passed filter\n", - kstats.tp_packets - kstats.tp_drops); - info("%d frames failed filter (due to out of space)\n", - kstats.tp_drops); + info("%d frames passed filter\n", kstats.tp_packets - kstats.tp_drops); + info("%d frames failed filter (due to out of space)\n", kstats.tp_drops); } } @@ -398,8 +380,7 @@ void parse_rules(char *rulefile, struct sock_filter **bpf, int *len) ret = sscanf(buff, "{ 0x%x, %d, %d, 0x%08x },", (unsigned int *)((void *)&(sf_single.code)), - (int *)((void *)&(sf_single.jt)), - (int *)((void *)&(sf_single.jf)), &(sf_single.k)); + (int *)((void *)&(sf_single.jt)), (int *)((void *)&(sf_single.jf)), &(sf_single.k)); if (ret != 4) { /* No valid bpf opcode format, might be a comment or a syntax error */ @@ -407,15 +388,12 @@ void parse_rules(char *rulefile, struct sock_filter **bpf, int *len) } *len += 1; - *bpf = (struct sock_filter *)realloc(*bpf, - *len * sizeof(sf_single)); + *bpf = (struct sock_filter *)realloc(*bpf, *len * sizeof(sf_single)); memcpy(&((*bpf)[*len - 1]), &sf_single, sizeof(sf_single)); info(" line %d: { 0x%x, %d, %d, 0x%08x }\n", count++, - (*bpf)[*len - 1].code, - (*bpf)[*len - 1].jt, - (*bpf)[*len - 1].jf, (*bpf)[*len - 1].k); + (*bpf)[*len - 1].code, (*bpf)[*len - 1].jt, (*bpf)[*len - 1].jf, (*bpf)[*len - 1].k); } info("\n"); diff --git a/src/lib/system.c b/src/lib/system.c index f92a3806..4a7db080 100644 --- a/src/lib/system.c +++ b/src/lib/system.c @@ -333,8 +333,7 @@ int undaemonize(const char *pidfile) * @logfile: path to logfile * @sockfile: path to unix domain socket inode */ -int daemonize(const char *pidfile, const char *logfile, - const char *sockfile, void *(*start_server) (void *sock)) +int daemonize(const char *pidfile, const char *logfile, const char *sockfile, void *(*start_server) (void *sock)) { int fd; int ret; @@ -354,8 +353,7 @@ int daemonize(const char *pidfile, const char *logfile, fd = open(pidfile, O_RDONLY); if (fd > 0) { - err("daemon already started." - "kill daemon and delete pid file %s\n", pidfile); + err("daemon already started." "kill daemon and delete pid file %s\n", pidfile); close(fd); exit(EXIT_FAILURE); diff --git a/src/netsniff-ng.c b/src/netsniff-ng.c index 66f8ebab..4c0c920a 100644 --- a/src/netsniff-ng.c +++ b/src/netsniff-ng.c @@ -47,6 +47,11 @@ #include #include +#include +#include +#include + +#include #include #include #include @@ -90,25 +95,16 @@ static inline void refresh_counters(void) if (unlikely(netstat.t_elapsed % 60 == 0)) { netstat.s_per_min.frames = - curr_weight * netstat.per_min.frames + (1.f - - curr_weight) * - netstat.s_per_min.frames; + curr_weight * netstat.per_min.frames + (1.f - curr_weight) * netstat.s_per_min.frames; netstat.s_per_min.bytes = - curr_weight * netstat.per_min.bytes + (1.f - - curr_weight) * - netstat.s_per_min.bytes; + curr_weight * netstat.per_min.bytes + (1.f - curr_weight) * netstat.s_per_min.bytes; netstat.per_min.frames = netstat.per_min.bytes = 0; } netstat.s_per_sec.frames = - curr_weight * netstat.per_sec.frames + (1.f - - curr_weight) * - netstat.s_per_sec.frames; - netstat.s_per_sec.bytes = - curr_weight * netstat.per_sec.bytes + (1.f - - curr_weight) * - netstat.s_per_sec.bytes; + curr_weight * netstat.per_sec.frames + (1.f - curr_weight) * netstat.s_per_sec.frames; + netstat.s_per_sec.bytes = curr_weight * netstat.per_sec.bytes + (1.f - curr_weight) * netstat.s_per_sec.bytes; netstat.per_sec.frames = netstat.per_sec.bytes = 0; } @@ -141,30 +137,21 @@ static inline void print_counters(void) */ info("stats summary:\n"); info("--------------------------------------------------------------------------------------------\n"); - info("elapsed time: %llu d, %llu h, %llu min, %llu s, %llu ns\n", - d_day, d_h, d_min, d_sec, d_nsec); + info("elapsed time: %llu d, %llu h, %llu min, %llu s, %llu ns\n", d_day, d_h, d_min, d_sec, d_nsec); info("-----------+--------------------------+--------------------------+--------------------------\n"); info(" | per sec | per min | total \n"); info("-----------+--------------------------+--------------------------+--------------------------\n"); info(" frames | %24llu | %24llu | %24llu \n", - netstat.s_per_sec.frames, netstat.s_per_min.frames, - netstat.total.frames); + netstat.s_per_sec.frames, netstat.s_per_min.frames, netstat.total.frames); info("-----------+--------------------------+--------------------------+--------------------------\n"); info(" in B | %24llu | %24llu | %24llu \n", - netstat.s_per_sec.bytes, netstat.s_per_min.bytes, - netstat.total.bytes); + netstat.s_per_sec.bytes, netstat.s_per_min.bytes, netstat.total.bytes); info(" in KB | %24llu | %24llu | %24llu \n", - DIV_KBYTES(netstat.s_per_sec.bytes), - DIV_KBYTES(netstat.s_per_min.bytes), - DIV_KBYTES(netstat.total.bytes)); + DIV_KBYTES(netstat.s_per_sec.bytes), DIV_KBYTES(netstat.s_per_min.bytes), DIV_KBYTES(netstat.total.bytes)); info(" in MB | %24llu | %24llu | %24llu \n", - DIV_MBYTES(netstat.s_per_sec.bytes), - DIV_MBYTES(netstat.s_per_min.bytes), - DIV_MBYTES(netstat.total.bytes)); + DIV_MBYTES(netstat.s_per_sec.bytes), DIV_MBYTES(netstat.s_per_min.bytes), DIV_MBYTES(netstat.total.bytes)); info(" in GB | %24llu | %24llu | %24llu \n", - DIV_GBYTES(netstat.s_per_sec.bytes), - DIV_GBYTES(netstat.s_per_min.bytes), - DIV_GBYTES(netstat.total.bytes)); + DIV_GBYTES(netstat.s_per_sec.bytes), DIV_GBYTES(netstat.s_per_min.bytes), DIV_GBYTES(netstat.total.bytes)); info("-----------+--------------------------+--------------------------+--------------------------\n"); } @@ -249,8 +236,7 @@ void *start_uds_server(void *psockfile) size_t t = sizeof(remote); info("unix domain socket server: waiting for a connection\n"); - sock2 = - accept(sock, (struct sockaddr *)&remote, (socklen_t *) & t); + sock2 = accept(sock, (struct sockaddr *)&remote, (socklen_t *) & t); if (sock2 < 0) { perr("cannot do accept on uds socket %d - ", errno); pthread_exit(0); @@ -295,8 +281,7 @@ void softirq_handler(int number) switch (++sigusr2 % 2) { case 0: { - print_packet_buffer = - print_packet_buffer_mode_1; + print_packet_buffer = print_packet_buffer_mode_1; break; } case 1: @@ -306,8 +291,7 @@ void softirq_handler(int number) } default: { - print_packet_buffer = - print_packet_buffer_mode_1; + print_packet_buffer = print_packet_buffer_mode_1; break; } } @@ -336,8 +320,7 @@ void softirq_handler(int number) * @rb: ring buffer * @pfd: file descriptor for polling */ -void fetch_packets(ring_buff_t * rb, struct pollfd *pfd, int timeout, - FILE * pcap, int packet_type, int sock) +void fetch_packets(ring_buff_t * rb, struct pollfd *pfd, int timeout, FILE * pcap, int packet_type, int sock) { int ret, foo, i = 0; @@ -349,13 +332,12 @@ void fetch_packets(ring_buff_t * rb, struct pollfd *pfd, int timeout, while (mem_notify_user(rb->frames[i]) && likely(!sigint)) { struct frame_map *fm = rb->frames[i].iov_base; ring_buff_bytes_t *rbb = - (ring_buff_bytes_t *) (rb->frames[i].iov_base + - sizeof(*fm) + sizeof(short)); + (ring_buff_bytes_t *) (rb->frames[i].iov_base + sizeof(*fm) + sizeof(short)); /* Check if the user wants to have a specific packet type */ - if(packet_type != PACKET_DONT_CARE) { - if(fm->s_ll.sll_pkttype != packet_type) { + if (packet_type != PACKET_DONT_CARE) { + if (fm->s_ll.sll_pkttype != packet_type) { goto __out_notify_kernel; } } @@ -367,8 +349,7 @@ void fetch_packets(ring_buff_t * rb, struct pollfd *pfd, int timeout, } if (pcap != NULL) { - pcap_dump(pcap, &fm->tp_h, - (struct ethhdr *)rbb); + pcap_dump(pcap, &fm->tp_h, (struct ethhdr *)rbb); } /* Pending singals will be delivered after netstat @@ -388,62 +369,61 @@ void fetch_packets(ring_buff_t * rb, struct pollfd *pfd, int timeout, /* Next frame */ i = (i + 1) % rb->layout.tp_frame_nr; -__out_notify_kernel: + __out_notify_kernel: /* This is very important, otherwise kernel starts to drop packages */ mem_notify_kernel(&(fm->tp_h)); } - while((ret = poll(pfd, 1, timeout)) <= 0) - /* NOP */; + while ((ret = poll(pfd, 1, timeout)) <= 0) + /* NOP */ ; if (ret > 0 && (pfd->revents & (POLLHUP | POLLRDHUP | POLLERR | POLLNVAL))) { - if(pfd->revents & (POLLHUP | POLLRDHUP)) { - err("Hangup on socket occured.\n"); + if (pfd->revents & (POLLHUP | POLLRDHUP)) { + err("Hangup on socket occured.\n\n"); return; - } else if(pfd->revents & POLLERR) { - err("Error occured on socket: "); + } else if (pfd->revents & POLLERR) { /* recv is more specififc on the error */ errno = 0; if (recv(sock, &foo, sizeof(foo), MSG_PEEK) != -1) - goto __out_grab_frame; /* Hmm... no error */ + goto __out_grab_frame; /* Hmm... no error */ if (errno == ENETDOWN) { - err("Interface went down\n"); + err("Interface went down\n\n"); } else { - err("%s\n", strerror(errno)); + err("%s\n\n", strerror(errno)); } return; - } else if(pfd->revents & POLLNVAL) { - err("Invalid polling request on socket.\n"); + } else if (pfd->revents & POLLNVAL) { + err("Invalid polling request on socket.\n\n"); return; } } -__out_grab_frame: + __out_grab_frame: /* Look-ahead if current frame is status kernel, otherwise we have have incoming frames and poll spins / hangs all the time :( */ - for(; ((struct tpacket_hdr *) rb->frames[i].iov_base)->tp_status - != TP_STATUS_USER; i = (i + 1) % rb->layout.tp_frame_nr) + for (; ((struct tpacket_hdr *)rb->frames[i].iov_base)->tp_status + != TP_STATUS_USER; i = (i + 1) % rb->layout.tp_frame_nr) /* NOP */ ; /* Why this should be okay: - 1) Current frame[i] is TP_STATUS_USER: - This is our original case that occurs without - the for loop. - 2) Current frame[i] is not TP_STATUS_USER: - poll returns correctly with return value 1 (number of - file descriptors), so an event has occured which has - to be POLLIN since all error conditions have been - caught previously. Furthermore, during ring traversal - a frame that has been set to TP_STATUS_USER will be - given back to kernel on finish with TP_STATUS_KERNEL. - So, if we look ahead all skipped frames are not ready - for user access. Since the kernel decides to put - frames, which are 'behind' our pointer, into - TP_STATUS_USER we do one loop and return at the - correct position after passing the for loop again. If - we grab frame which are 'in front of' our pointer - we'll fetch them within the first for loop. - */ + 1) Current frame[i] is TP_STATUS_USER: + This is our original case that occurs without + the for loop. + 2) Current frame[i] is not TP_STATUS_USER: + poll returns correctly with return value 1 (number of + file descriptors), so an event has occured which has + to be POLLIN since all error conditions have been + caught previously. Furthermore, during ring traversal + a frame that has been set to TP_STATUS_USER will be + given back to kernel on finish with TP_STATUS_KERNEL. + So, if we look ahead all skipped frames are not ready + for user access. Since the kernel decides to put + frames, which are 'behind' our pointer, into + TP_STATUS_USER we do one loop and return at the + correct position after passing the for loop again. If + we grab frame which are 'in front of' our pointer + we'll fetch them within the first for loop. + */ } } @@ -454,12 +434,15 @@ __out_grab_frame: * @rb: ring buffer * @pfd: file descriptor for polling */ -static int init_system(system_data_t * sd, int *sock, ring_buff_t ** rb, - struct pollfd *pfd) +static int init_system(system_data_t * sd, int *sock, ring_buff_t ** rb, struct pollfd *pfd) { - int ret, bpf_len = 0; + int stmp, i, ret, bpf_len = 0; + char dev_buff[1024]; struct sock_filter *bpf = NULL; + struct ifconf ifc; + struct ifreq *ifr = NULL; + struct ifreq *ifr_elem = NULL; struct itimerval val_r; assert(sd); @@ -483,9 +466,7 @@ static int init_system(system_data_t * sd, int *sock, ring_buff_t ** rb, register_softirq(SIGHUP, &softirq_handler); if (sd->sysdaemon) { - ret = - daemonize(sd->pidfile, sd->logfile, sd->sockfile, - start_uds_server); + ret = daemonize(sd->pidfile, sd->logfile, sd->sockfile, start_uds_server); if (ret != 0) { err("daemonize failed"); exit(EXIT_FAILURE); @@ -503,6 +484,46 @@ static int init_system(system_data_t * sd, int *sock, ring_buff_t ** rb, memset((*rb), 0, sizeof(**rb)); + /* User didn't specify a device, so we switch to the default running + dev. This is the first running dev found (except lo). If we find + nothing, we switch to lo. */ + if (!sd->dev) { + sd->dev = strdup("lo"); + + stmp = socket(AF_INET, SOCK_DGRAM, 0); + if (stmp < 0) { + perror("socket"); + exit(EXIT_FAILURE); + } + + ifc.ifc_len = sizeof(dev_buff); + ifc.ifc_buf = dev_buff; + + if (ioctl(stmp, SIOCGIFCONF, &ifc) < 0) { + perror("ioctl(SIOCGIFCONF)"); + exit(EXIT_FAILURE); + } + + ifr = ifc.ifc_req; + + for (i = 0; i < ifc.ifc_len / sizeof(struct ifreq); ++i) { + ifr_elem = &ifr[i]; + + if (ioctl(stmp, SIOCGIFFLAGS, ifr_elem) < 0) { + perror("ioctl(SIOCGIFFLAGS)"); + return 1; + } + + if ((ifr_elem->ifr_flags & IFF_UP) && + (ifr_elem->ifr_flags & IFF_RUNNING) && strncmp(ifr_elem->ifr_name, "lo", IFNAMSIZ)) { + sd->dev = strdup(ifr_elem->ifr_name); + break; + } + } + + info("No device specified, using `%s`.\n\n", sd->dev); + } + (*sock) = alloc_pf_sock(); put_dev_into_promisc_mode((*sock), ethdev_to_ifindex((*sock), sd->dev)); @@ -578,8 +599,9 @@ static void cleanup_system(system_data_t * sd, int *sock, ring_buff_t ** rb) "captured bytes: %llu [%llu KiB, %llu MiB, %llu GiB]\n", netstat.total.frames, netstat.total.bytes, netstat.total.bytes / 1024, - netstat.total.bytes / (1024 * 1024), - netstat.total.bytes / (1024 * 1024 * 1024)); + netstat.total.bytes / (1024 * 1024), netstat.total.bytes / (1024 * 1024 * 1024)); + + free(sd->dev); if (sd->sysdaemon) { undaemonize(sd->pidfile); @@ -638,9 +660,7 @@ int main(int argc, char **argv) sd->bypass_bpf = BPF_BYPASS; sd->packet_type = PACKET_DONT_CARE; - while ((c = - getopt_long(argc, argv, "vhd:p:P:L:Df:sS:b:B:Hnt:", long_options, - &opt_idx)) != EOF) { + while ((c = getopt_long(argc, argv, "vhd:p:P:L:Df:sS:b:B:Hnt:", long_options, &opt_idx)) != EOF) { switch (c) { case 'h': { @@ -654,7 +674,7 @@ int main(int argc, char **argv) } case 'd': { - sd->dev = optarg; + sd->dev = strdup(optarg); break; } case 'n': @@ -669,15 +689,15 @@ int main(int argc, char **argv) } case 't': { - if(!strncmp(optarg, "host", strlen("host"))) { + if (!strncmp(optarg, "host", strlen("host"))) { sd->packet_type = PACKET_HOST; - } else if(!strncmp(optarg, "broadcast", strlen("broadcast"))) { + } else if (!strncmp(optarg, "broadcast", strlen("broadcast"))) { sd->packet_type = PACKET_BROADCAST; - } else if(!strncmp(optarg, "multicast", strlen("multicast"))) { + } else if (!strncmp(optarg, "multicast", strlen("multicast"))) { sd->packet_type = PACKET_MULTICAST; - } else if(!strncmp(optarg, "others", strlen("others"))) { + } else if (!strncmp(optarg, "others", strlen("others"))) { sd->packet_type = PACKET_OTHERHOST; - } else if(!strncmp(optarg, "outgoing", strlen("outgoing"))) { + } else if (!strncmp(optarg, "outgoing", strlen("outgoing"))) { sd->packet_type = PACKET_OUTGOING; } else { sd->packet_type = PACKET_DONT_CARE; @@ -733,8 +753,7 @@ int main(int argc, char **argv) exit(EXIT_FAILURE); } - sf_write_header(dump_pcap, LINKTYPE_EN10MB, 0, - PCAP_DEFAULT_SNAPSHOT_LEN); + sf_write_header(dump_pcap, LINKTYPE_EN10MB, 0, PCAP_DEFAULT_SNAPSHOT_LEN); break; } @@ -756,8 +775,7 @@ int main(int argc, char **argv) default: { if (isprint(optopt)) { - fprintf(stderr, "Unknown option character `0x%X\'!\n", - optopt); + fprintf(stderr, "Unknown option character `0x%X\'!\n", optopt); } break; } @@ -772,11 +790,6 @@ int main(int argc, char **argv) } } - if (argc < 2 || !sd->dev) { - help(); - exit(EXIT_FAILURE); - } - if (sd->sysdaemon && (!sd->pidfile || !sd->logfile || !sd->sockfile)) { help(); exit(EXIT_FAILURE); -- 2.11.4.GIT