version 1.1, 2012/02/21 16:57:34
|
version 1.1.1.2, 2016/10/18 14:04:50
|
Line 5
|
Line 5
|
|
|
#include "integers.h" |
#include "integers.h" |
|
|
#if defined(HAVE_PCAP_H) |
|
# include <pcap.h> |
|
#elif defined(HAVE_PCAP_PCAP_H) |
|
# include <pcap/pcap.h> |
|
#else |
|
# error No pcap.h |
|
#endif |
|
#include <stdio.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <stdlib.h> |
#include <time.h> |
#include <time.h> |
Line 19
|
Line 12
|
#include <sys/ioctl.h> |
#include <sys/ioctl.h> |
#include <sys/socket.h> |
#include <sys/socket.h> |
#include <net/if.h> |
#include <net/if.h> |
|
/* include <net/bpf.h> -- this was added by the PFLOG patch but seems |
|
* superfluous and breaks on Slackware */ |
|
#if defined(HAVE_PCAP_H) |
|
# include <pcap.h> |
|
#elif defined(HAVE_PCAP_PCAP_H) |
|
# include <pcap/pcap.h> |
|
#else |
|
# error No pcap.h |
|
#endif |
|
|
#include <pthread.h> |
#include <pthread.h> |
#include <curses.h> |
#include <curses.h> |
#include <signal.h> |
#include <signal.h> |
#include <string.h> |
#include <string.h> |
#include <unistd.h> |
#include <unistd.h> |
|
#include <locale.h> |
|
|
#include "iftop.h" |
#include "iftop.h" |
#include "addr_hash.h" |
#include "addr_hash.h" |
#include "resolver.h" |
#include "resolver.h" |
|
#include "ui_common.h" |
#include "ui.h" |
#include "ui.h" |
|
#include "tui.h" |
#include "options.h" |
#include "options.h" |
#ifdef DLT_LINUX_SLL |
#ifdef DLT_LINUX_SLL |
#include "sll.h" |
#include "sll.h" |
Line 44
|
Line 49
|
#include "ethertype.h" |
#include "ethertype.h" |
#include "cfgfile.h" |
#include "cfgfile.h" |
#include "ppp.h" |
#include "ppp.h" |
|
#include "addrs_ioctl.h" |
|
|
|
#include <netinet/ip6.h> |
|
|
/* ethernet address of interface. */ |
/* ethernet address of interface. */ |
int have_hw_addr = 0; |
int have_hw_addr = 0; |
unsigned char if_hw_addr[6]; | char if_hw_addr[6]; |
|
|
/* IP address of interface */ |
/* IP address of interface */ |
int have_ip_addr = 0; |
int have_ip_addr = 0; |
|
int have_ip6_addr = 0; |
struct in_addr if_ip_addr; |
struct in_addr if_ip_addr; |
|
struct in6_addr if_ip6_addr; |
|
|
extern options_t options; |
extern options_t options; |
|
|
hash_type* history; |
hash_type* history; |
history_type history_totals; |
history_type history_totals; |
time_t last_timestamp; |
time_t last_timestamp; |
|
time_t first_timestamp; |
int history_pos = 0; |
int history_pos = 0; |
int history_len = 1; |
int history_len = 1; |
pthread_mutex_t tick_mutex; |
pthread_mutex_t tick_mutex; |
Line 76 static void finish(int sig) {
|
Line 86 static void finish(int sig) {
|
|
|
|
|
|
|
/* Only need ethernet (plus optional 4 byte VLAN) and IP headers (48) + first 2 bytes of tcp/udp header */ | /* Only need ethernet (plus optional 4 byte VLAN) and IP headers (48) + first 2 |
#define CAPTURE_LENGTH 72 | * bytes of tcp/udp header */ |
| /* Increase with a further 20 to account for IPv6 header length. */ |
| /* IEEE 802.11 radiotap throws in a variable length header plus 8 (radiotap |
| * header header) plus 34 (802.11 MAC) plus 40 (IPv6) = 78, plus whatever's in |
| * the radiotap payload */ |
| /*#define CAPTURE_LENGTH 92 */ |
| #define CAPTURE_LENGTH 256 |
|
|
void init_history() { |
void init_history() { |
history = addr_hash_create(); |
history = addr_hash_create(); |
Line 128 void tick(int print) {
|
Line 144 void tick(int print) {
|
|
|
t = time(NULL); |
t = time(NULL); |
if(t - last_timestamp >= RESOLUTION) { |
if(t - last_timestamp >= RESOLUTION) { |
//printf("TICKING\n"); |
|
analyse_data(); |
analyse_data(); |
ui_print(); | if (options.no_curses) { |
| if (!options.timed_output || (options.timed_output && t - first_timestamp >= options.timed_output)) { |
| tui_print(); |
| if (options.timed_output) { |
| finish(SIGINT); |
| } |
| } |
| } |
| else { |
| ui_print(); |
| } |
history_rotate(); |
history_rotate(); |
last_timestamp = t; |
last_timestamp = t; |
} |
} |
else { |
else { |
ui_tick(print); | if (options.no_curses) { |
| tui_tick(print); |
| } |
| else { |
| ui_tick(print); |
| } |
} |
} |
|
|
pthread_mutex_unlock(&tick_mutex); |
pthread_mutex_unlock(&tick_mutex); |
Line 147 int in_filter_net(struct in_addr addr) {
|
Line 177 int in_filter_net(struct in_addr addr) {
|
return ret; |
return ret; |
} |
} |
|
|
int ip_addr_match(struct in_addr addr) { | static int __inline__ ip_addr_match(struct in_addr addr) { |
return addr.s_addr == if_ip_addr.s_addr; |
return addr.s_addr == if_ip_addr.s_addr; |
} |
} |
|
|
|
static int __inline__ ip6_addr_match(struct in6_addr *addr) { |
|
return IN6_ARE_ADDR_EQUAL(addr, &if_ip6_addr); |
|
} |
|
|
/** |
/** |
* Creates an addr_pair from an ip (and tcp/udp) header, swapping src and dst |
* Creates an addr_pair from an ip (and tcp/udp) header, swapping src and dst |
* if required |
* if required |
Line 159 void assign_addr_pair(addr_pair* ap, struct ip* iptr,
|
Line 193 void assign_addr_pair(addr_pair* ap, struct ip* iptr,
|
unsigned short int src_port = 0; |
unsigned short int src_port = 0; |
unsigned short int dst_port = 0; |
unsigned short int dst_port = 0; |
|
|
|
/* Arrange for predictable values. */ |
|
memset(ap, '\0', sizeof(*ap)); |
|
|
|
if(IP_V(iptr) == 4) { |
|
ap->af = AF_INET; |
/* Does this protocol use ports? */ |
/* Does this protocol use ports? */ |
if(iptr->ip_p == IPPROTO_TCP || iptr->ip_p == IPPROTO_UDP) { |
if(iptr->ip_p == IPPROTO_TCP || iptr->ip_p == IPPROTO_UDP) { |
/* We take a slight liberty here by treating UDP the same as TCP */ |
/* We take a slight liberty here by treating UDP the same as TCP */ |
Line 181 void assign_addr_pair(addr_pair* ap, struct ip* iptr,
|
Line 220 void assign_addr_pair(addr_pair* ap, struct ip* iptr,
|
ap->dst = iptr->ip_src; |
ap->dst = iptr->ip_src; |
ap->dst_port = src_port; |
ap->dst_port = src_port; |
} |
} |
|
} /* IPv4 */ |
|
else if (IP_V(iptr) == 6) { |
|
/* IPv6 packet seen. */ |
|
struct ip6_hdr *ip6tr = (struct ip6_hdr *) iptr; |
|
|
|
ap->af = AF_INET6; |
|
|
|
if( (ip6tr->ip6_nxt == IPPROTO_TCP) || (ip6tr->ip6_nxt == IPPROTO_UDP) ) { |
|
struct tcphdr *thdr = ((void *) ip6tr) + 40; |
|
|
|
src_port = ntohs(thdr->th_sport); |
|
dst_port = ntohs(thdr->th_dport); |
|
} |
|
|
|
if(flip == 0) { |
|
memcpy(&ap->src6, &ip6tr->ip6_src, sizeof(ap->src6)); |
|
ap->src_port = src_port; |
|
memcpy(&ap->dst6, &ip6tr->ip6_dst, sizeof(ap->dst6)); |
|
ap->dst_port = dst_port; |
|
} |
|
else { |
|
memcpy(&ap->src6, &ip6tr->ip6_dst, sizeof(ap->src6)); |
|
ap->src_port = dst_port; |
|
memcpy(&ap->dst6, &ip6tr->ip6_src, sizeof(ap->dst6)); |
|
ap->dst_port = src_port; |
|
} |
|
} |
} |
} |
|
|
static void handle_ip_packet(struct ip* iptr, int hw_dir) |
static void handle_ip_packet(struct ip* iptr, int hw_dir) |
Line 189 static void handle_ip_packet(struct ip* iptr, int hw_d
|
Line 254 static void handle_ip_packet(struct ip* iptr, int hw_d
|
int direction = 0; /* incoming */ |
int direction = 0; /* incoming */ |
history_type* ht; |
history_type* ht; |
union { |
union { |
history_type **ht_pp; | history_type **ht_pp; |
void **void_pp; | void **void_pp; |
} u_ht = { &ht }; |
} u_ht = { &ht }; |
addr_pair ap; |
addr_pair ap; |
int len; | unsigned int len = 0; |
| struct in6_addr scribdst; /* Scratch pad. */ |
| struct in6_addr scribsrc; /* Scratch pad. */ |
| /* Reinterpret packet type. */ |
| struct ip6_hdr* ip6tr = (struct ip6_hdr *) iptr; |
|
|
if(options.netfilter == 0) { | memset(&ap, '\0', sizeof(ap)); |
| |
| tick(0); |
| |
| if( (IP_V(iptr) ==4 && options.netfilter == 0) |
| || (IP_V(iptr) == 6 && options.netfilter6 == 0) ) { |
/* |
/* |
* Net filter is off, so assign direction based on MAC address |
* Net filter is off, so assign direction based on MAC address |
*/ |
*/ |
Line 212 static void handle_ip_packet(struct ip* iptr, int hw_d
|
Line 286 static void handle_ip_packet(struct ip* iptr, int hw_d
|
/* Packet direction is not given away by h/ware layer. Try IP |
/* Packet direction is not given away by h/ware layer. Try IP |
* layer |
* layer |
*/ |
*/ |
else if(have_ip_addr && ip_addr_match(iptr->ip_src)) { | else if((IP_V(iptr) == 4) && have_ip_addr && ip_addr_match(iptr->ip_src)) { |
/* outgoing */ |
/* outgoing */ |
assign_addr_pair(&ap, iptr, 0); |
assign_addr_pair(&ap, iptr, 0); |
direction = 1; |
direction = 1; |
} |
} |
else if(have_ip_addr && ip_addr_match(iptr->ip_dst)) { | else if((IP_V(iptr) == 4) && have_ip_addr && ip_addr_match(iptr->ip_dst)) { |
/* incoming */ |
/* incoming */ |
assign_addr_pair(&ap, iptr, 1); |
assign_addr_pair(&ap, iptr, 1); |
direction = 0; |
direction = 0; |
} |
} |
|
else if((IP_V(iptr) == 6) && have_ip6_addr && ip6_addr_match(&ip6tr->ip6_src)) { |
|
/* outgoing */ |
|
assign_addr_pair(&ap, iptr, 0); |
|
direction = 1; |
|
} |
|
else if((IP_V(iptr) == 6) && have_ip6_addr && ip6_addr_match(&ip6tr->ip6_dst)) { |
|
/* incoming */ |
|
assign_addr_pair(&ap, iptr, 1); |
|
direction = 0; |
|
} |
|
else if (IP_V(iptr) == 4 && IN_MULTICAST(iptr->ip_dst.s_addr)) { |
|
assign_addr_pair(&ap, iptr, 1); |
|
direction = 0; |
|
} |
|
else if (IP_V(iptr) == 6 && IN6_IS_ADDR_MULTICAST(&ip6tr->ip6_dst)) { |
|
assign_addr_pair(&ap, iptr, 1); |
|
direction = 0; |
|
} |
/* |
/* |
* Cannot determine direction from hardware or IP levels. Therefore |
* Cannot determine direction from hardware or IP levels. Therefore |
* assume that it was a packet between two other machines, assign |
* assume that it was a packet between two other machines, assign |
Line 231 static void handle_ip_packet(struct ip* iptr, int hw_d
|
Line 323 static void handle_ip_packet(struct ip* iptr, int hw_d
|
else if (options.promiscuous_but_choosy) { |
else if (options.promiscuous_but_choosy) { |
return; /* junk it */ |
return; /* junk it */ |
} |
} |
else if(iptr->ip_src.s_addr < iptr->ip_dst.s_addr) { | else if((IP_V(iptr) == 4) && (iptr->ip_src.s_addr < iptr->ip_dst.s_addr)) { |
assign_addr_pair(&ap, iptr, 1); |
assign_addr_pair(&ap, iptr, 1); |
direction = 0; |
direction = 0; |
} |
} |
else { | else if(IP_V(iptr) == 4) { |
assign_addr_pair(&ap, iptr, 0); |
assign_addr_pair(&ap, iptr, 0); |
direction = 0; |
direction = 0; |
} |
} |
|
/* Drop other uncertain packages. */ |
|
else |
|
return; |
} |
} |
else { | |
| if(IP_V(iptr) == 4 && options.netfilter != 0) { |
/* |
/* |
* Net filter on, assign direction according to netmask |
* Net filter on, assign direction according to netmask |
*/ |
*/ |
Line 260 static void handle_ip_packet(struct ip* iptr, int hw_d
|
Line 356 static void handle_ip_packet(struct ip* iptr, int hw_d
|
} |
} |
} |
} |
|
|
ap.protocol = iptr->ip_p; | if(IP_V(iptr) == 6 && options.netfilter6 != 0) { |
| /* |
| * Net filter IPv6 active. |
| */ |
| int j; |
| //else if((IP_V(iptr) == 6) && have_ip6_addr && ip6_addr_match(&ip6tr->ip6_dst)) { |
| /* First reduce the participating addresses using the netfilter prefix. |
| * We need scratch pads to do this. |
| */ |
| for (j=0; j < 16; ++j) { |
| scribdst.s6_addr[j] = ip6tr->ip6_dst.s6_addr[j] |
| & options.netfilter6mask.s6_addr[j]; |
| scribsrc.s6_addr[j] = ip6tr->ip6_src.s6_addr[j] |
| & options.netfilter6mask.s6_addr[j]; |
| } |
|
|
/* Add the addresses to be resolved */ | /* Now look for any hits. */ |
resolve(&iptr->ip_dst, NULL, 0); | //if(in_filter_net(iptr->ip_src) && !in_filter_net(iptr->ip_dst)) { |
resolve(&iptr->ip_src, NULL, 0); | if (IN6_ARE_ADDR_EQUAL(&scribsrc, &options.netfilter6net) |
| && ! IN6_ARE_ADDR_EQUAL(&scribdst, &options.netfilter6net)) { |
| /* out of network */ |
| assign_addr_pair(&ap, iptr, 0); |
| direction = 1; |
| } |
| //else if(in_filter_net(iptr->ip_dst) && !in_filter_net(iptr->ip_src)) { |
| else if (! IN6_ARE_ADDR_EQUAL(&scribsrc, &options.netfilter6net) |
| && IN6_ARE_ADDR_EQUAL(&scribdst, &options.netfilter6net)) { |
| /* into network */ |
| assign_addr_pair(&ap, iptr, 1); |
| direction = 0; |
| } |
| else { |
| /* drop packet */ |
| return ; |
| } |
| } |
|
|
|
#if 1 |
|
/* Test if link-local IPv6 packets should be dropped. */ |
|
if( IP_V(iptr) == 6 && !options.link_local |
|
&& (IN6_IS_ADDR_LINKLOCAL(&ip6tr->ip6_dst) |
|
|| IN6_IS_ADDR_LINKLOCAL(&ip6tr->ip6_src)) ) |
|
return; |
|
#endif |
|
|
|
/* Do address resolving. */ |
|
switch (IP_V(iptr)) { |
|
case 4: |
|
ap.protocol = iptr->ip_p; |
|
/* Add the addresses to be resolved */ |
|
/* The IPv4 address is embedded in a in6_addr structure, |
|
* so it need be copied, and delivered to resolve(). */ |
|
memset(&scribdst, '\0', sizeof(scribdst)); |
|
memcpy(&scribdst, &iptr->ip_dst, sizeof(struct in_addr)); |
|
resolve(ap.af, &scribdst, NULL, 0); |
|
memset(&scribsrc, '\0', sizeof(scribsrc)); |
|
memcpy(&scribsrc, &iptr->ip_src, sizeof(struct in_addr)); |
|
resolve(ap.af, &scribsrc, NULL, 0); |
|
break; |
|
case 6: |
|
ap.protocol = ip6tr->ip6_nxt; |
|
/* Add the addresses to be resolved */ |
|
resolve(ap.af, &ip6tr->ip6_dst, NULL, 0); |
|
resolve(ap.af, &ip6tr->ip6_src, NULL, 0); |
|
default: |
|
break; |
|
} |
|
|
|
|
if(hash_find(history, &ap, u_ht.void_pp) == HASH_STATUS_KEY_NOT_FOUND) { |
if(hash_find(history, &ap, u_ht.void_pp) == HASH_STATUS_KEY_NOT_FOUND) { |
ht = history_create(); |
ht = history_create(); |
hash_insert(history, &ap, ht); |
hash_insert(history, &ap, ht); |
} |
} |
|
|
len = ntohs(iptr->ip_len); | /* Do accounting. */ |
| switch (IP_V(iptr)) { |
| case 4: |
| len = ntohs(iptr->ip_len); |
| break; |
| case 6: |
| len = ntohs(ip6tr->ip6_plen) + 40; |
| default: |
| break; |
| } |
|
|
/* Update record */ |
/* Update record */ |
ht->last_write = history_pos; |
ht->last_write = history_pos; |
if(iptr->ip_src.s_addr == ap.src.s_addr) { | if( ((IP_V(iptr) == 4) && (iptr->ip_src.s_addr == ap.src.s_addr)) |
| || ((IP_V(iptr) == 6) && !memcmp(&ip6tr->ip6_src, &ap.src6, sizeof(ap.src6))) ) |
| { |
ht->sent[history_pos] += len; |
ht->sent[history_pos] += len; |
ht->total_sent += len; |
ht->total_sent += len; |
} |
} |
Line 301 static void handle_raw_packet(unsigned char* args, con
|
Line 471 static void handle_raw_packet(unsigned char* args, con
|
handle_ip_packet((struct ip*)packet, -1); |
handle_ip_packet((struct ip*)packet, -1); |
} |
} |
|
|
|
#ifdef DLT_PFLOG |
|
static void handle_pflog_packet(unsigned char* args, const struct pcap_pkthdr* pkthdr, const unsigned char* packet) |
|
{ |
|
register u_int length = pkthdr->len; |
|
u_int hdrlen; |
|
const struct pfloghdr *hdr; |
|
|
|
hdr = (struct pfloghdr *)packet; |
|
hdrlen = BPF_WORDALIGN(hdr->length); |
|
length -= hdrlen; |
|
packet += hdrlen; |
|
handle_ip_packet((struct ip*)packet, -1); |
|
} |
|
#endif |
|
|
|
static void handle_null_packet(unsigned char* args, const struct pcap_pkthdr* pkthdr, const unsigned char* packet) |
|
{ |
|
handle_ip_packet((struct ip*)(packet + 4), -1); |
|
} |
|
|
static void handle_llc_packet(const struct llc* llc, int dir) { |
static void handle_llc_packet(const struct llc* llc, int dir) { |
|
|
struct ip* ip = (struct ip*)((void*)llc + sizeof(struct llc)); |
struct ip* ip = (struct ip*)((void*)llc + sizeof(struct llc)); |
Line 309 static void handle_llc_packet(const struct llc* llc, i
|
Line 499 static void handle_llc_packet(const struct llc* llc, i
|
if(llc->ssap == LLCSAP_SNAP && llc->dsap == LLCSAP_SNAP |
if(llc->ssap == LLCSAP_SNAP && llc->dsap == LLCSAP_SNAP |
&& llc->llcui == LLC_UI) { |
&& llc->llcui == LLC_UI) { |
u_int32_t orgcode; |
u_int32_t orgcode; |
register u_short et; | u_int16_t et; |
orgcode = EXTRACT_24BITS(&llc->llc_orgcode[0]); |
orgcode = EXTRACT_24BITS(&llc->llc_orgcode[0]); |
et = EXTRACT_16BITS(&llc->llc_ethertype[0]); | et = (llc->llc_ethertype[0] << 8) + llc->llc_ethertype[1]; |
switch(orgcode) { |
switch(orgcode) { |
case OUI_ENCAP_ETHER: |
case OUI_ENCAP_ETHER: |
case OUI_CISCO_90: |
case OUI_CISCO_90: |
Line 374 static void handle_ppp_packet(unsigned char* args, con
|
Line 564 static void handle_ppp_packet(unsigned char* args, con
|
packet += 2; |
packet += 2; |
length -= 2; |
length -= 2; |
|
|
if(proto == PPP_IP || proto == ETHERTYPE_IP) { | if(proto == PPP_IP || proto == ETHERTYPE_IP || proto == ETHERTYPE_IPV6) { |
handle_ip_packet((struct ip*)packet, -1); |
handle_ip_packet((struct ip*)packet, -1); |
} |
} |
} |
} |
Line 411 static void handle_eth_packet(unsigned char* args, con
|
Line 601 static void handle_eth_packet(unsigned char* args, con
|
ether_type = ntohs(eptr->ether_type); |
ether_type = ntohs(eptr->ether_type); |
payload = packet + sizeof(struct ether_header); |
payload = packet + sizeof(struct ether_header); |
|
|
tick(0); |
|
|
|
if(ether_type == ETHERTYPE_8021Q) { |
if(ether_type == ETHERTYPE_8021Q) { |
struct vlan_8021q_header* vptr; | struct vlan_8021q_header* vptr; |
vptr = (struct vlan_8021q_header*)payload; | vptr = (struct vlan_8021q_header*)payload; |
ether_type = ntohs(vptr->ether_type); | ether_type = ntohs(vptr->ether_type); |
payload += sizeof(struct vlan_8021q_header); |
payload += sizeof(struct vlan_8021q_header); |
} |
} |
|
|
if(ether_type == ETHERTYPE_IP) { | if(ether_type == ETHERTYPE_IP || ether_type == ETHERTYPE_IPV6) { |
struct ip* iptr; |
struct ip* iptr; |
int dir = -1; |
int dir = -1; |
|
|
Line 432 static void handle_eth_packet(unsigned char* args, con
|
Line 620 static void handle_eth_packet(unsigned char* args, con
|
dir = 1; |
dir = 1; |
} |
} |
else if(have_hw_addr && memcmp(eptr->ether_dhost, if_hw_addr, 6) == 0 ) { |
else if(have_hw_addr && memcmp(eptr->ether_dhost, if_hw_addr, 6) == 0 ) { |
/* packet entering this i/f */ | /* packet entering this i/f */ |
dir = 0; | |
} | |
else if (memcmp("\xFF\xFF\xFF\xFF\xFF\xFF", eptr->ether_dhost, 6) == 0) { | |
/* broadcast packet, count as incoming */ | |
dir = 0; |
dir = 0; |
} |
} |
|
else if (memcmp("\xFF\xFF\xFF\xFF\xFF\xFF", eptr->ether_dhost, 6) == 0) { |
|
/* broadcast packet, count as incoming */ |
|
dir = 0; |
|
} |
|
|
|
/* Distinguishing ip_hdr and ip6_hdr will be done later. */ |
iptr = (struct ip*)(payload); /* alignment? */ |
iptr = (struct ip*)(payload); /* alignment? */ |
handle_ip_packet(iptr, dir); |
handle_ip_packet(iptr, dir); |
} |
} |
} |
} |
|
|
|
#ifdef DLT_IEEE802_11_RADIO |
|
/* |
|
* Packets with a bonus radiotap header. |
|
* See http://www.gsp.com/cgi-bin/man.cgi?section=9&topic=ieee80211_radiotap |
|
*/ |
|
static void handle_radiotap_packet(unsigned char* args, const struct pcap_pkthdr* pkthdr, const unsigned char* packet) |
|
{ |
|
/* 802.11 MAC header is = 34 bytes (not sure if that's universally true) */ |
|
/* We could try harder to figure out hardware direction from the MAC header */ |
|
handle_ip_packet((struct ip*)(packet + ((struct radiotap_header *)packet)->it_len + 34),-1); |
|
} |
|
|
|
|
|
#endif |
|
|
/* set_filter_code: |
/* set_filter_code: |
* Install some filter code. Returns NULL on success or an error message on |
* Install some filter code. Returns NULL on success or an error message on |
* failure. */ |
* failure. */ |
char *set_filter_code(const char *filter) { |
char *set_filter_code(const char *filter) { |
char *x; |
char *x; |
if (filter) { |
if (filter) { |
x = xmalloc(strlen(filter) + sizeof "() and ip"); | x = xmalloc(strlen(filter) + sizeof "() and (ip or ip6)"); |
sprintf(x, "(%s) and ip", filter); | sprintf(x, "(%s) and (ip or ip6)", filter); |
} else |
} else |
x = xstrdup("ip"); | x = xstrdup("ip or ip6"); |
if (pcap_compile(pd, &pcap_filter, x, 1, 0) == -1) { |
if (pcap_compile(pd, &pcap_filter, x, 1, 0) == -1) { |
xfree(x); |
xfree(x); |
return pcap_geterr(pd); |
return pcap_geterr(pd); |
Line 477 char *set_filter_code(const char *filter) {
|
Line 680 char *set_filter_code(const char *filter) {
|
void packet_init() { |
void packet_init() { |
char errbuf[PCAP_ERRBUF_SIZE]; |
char errbuf[PCAP_ERRBUF_SIZE]; |
char *m; |
char *m; |
int s; |
|
int i; |
int i; |
int dlt; |
int dlt; |
int result; |
int result; |
Line 485 void packet_init() {
|
Line 687 void packet_init() {
|
#ifdef HAVE_DLPI |
#ifdef HAVE_DLPI |
result = get_addrs_dlpi(options.interface, if_hw_addr, &if_ip_addr); |
result = get_addrs_dlpi(options.interface, if_hw_addr, &if_ip_addr); |
#else |
#else |
result = get_addrs_ioctl(options.interface, if_hw_addr, &if_ip_addr); | result = get_addrs_ioctl(options.interface, if_hw_addr, |
| &if_ip_addr, &if_ip6_addr); |
#endif |
#endif |
|
|
if (result < 0) { |
if (result < 0) { |
exit(1); |
exit(1); |
} |
} |
|
|
have_hw_addr = result & 1; | have_hw_addr = result & 0x01; |
have_ip_addr = result & 2; | have_ip_addr = result & 0x02; |
| have_ip6_addr = result & 0x04; |
|
|
if(have_ip_addr) { |
if(have_ip_addr) { |
fprintf(stderr, "IP address is: %s\n", inet_ntoa(if_ip_addr)); |
fprintf(stderr, "IP address is: %s\n", inet_ntoa(if_ip_addr)); |
} |
} |
|
if(have_ip6_addr) { |
|
char ip6str[INET6_ADDRSTRLEN]; |
|
|
|
ip6str[0] = '\0'; |
|
inet_ntop(AF_INET6, &if_ip6_addr, ip6str, sizeof(ip6str)); |
|
fprintf(stderr, "IPv6 address is: %s\n", ip6str); |
|
} |
|
|
if(have_hw_addr) { |
if(have_hw_addr) { |
fprintf(stderr, "MAC address is:"); |
fprintf(stderr, "MAC address is:"); |
for (i = 0; i < 6; ++i) |
for (i = 0; i < 6; ++i) |
Line 519 void packet_init() {
|
Line 730 void packet_init() {
|
if(dlt == DLT_EN10MB) { |
if(dlt == DLT_EN10MB) { |
packet_handler = handle_eth_packet; |
packet_handler = handle_eth_packet; |
} |
} |
else if(dlt == DLT_RAW || dlt == DLT_NULL) { | #ifdef DLT_PFLOG |
| else if (dlt == DLT_PFLOG) { |
| packet_handler = handle_pflog_packet; |
| } |
| #endif |
| else if(dlt == DLT_RAW) { |
packet_handler = handle_raw_packet; |
packet_handler = handle_raw_packet; |
} |
} |
|
else if(dlt == DLT_NULL) { |
|
packet_handler = handle_null_packet; |
|
} |
|
#ifdef DLT_LOOP |
|
else if(dlt == DLT_LOOP) { |
|
packet_handler = handle_null_packet; |
|
} |
|
#endif |
|
#ifdef DLT_IEEE802_11_RADIO |
|
else if(dlt == DLT_IEEE802_11_RADIO) { |
|
packet_handler = handle_radiotap_packet; |
|
} |
|
#endif |
else if(dlt == DLT_IEEE802) { |
else if(dlt == DLT_IEEE802) { |
packet_handler = handle_tokenring_packet; |
packet_handler = handle_tokenring_packet; |
} |
} |
Line 563 int main(int argc, char **argv) {
|
Line 792 int main(int argc, char **argv) {
|
pthread_t thread; |
pthread_t thread; |
struct sigaction sa = {}; |
struct sigaction sa = {}; |
|
|
|
setlocale(LC_ALL, ""); |
|
|
/* TODO: tidy this up */ |
/* TODO: tidy this up */ |
/* read command line options and config file */ |
/* read command line options and config file */ |
config_init(); |
config_init(); |
Line 581 int main(int argc, char **argv) {
|
Line 812 int main(int argc, char **argv) {
|
|
|
init_history(); |
init_history(); |
|
|
ui_init(); | if (options.no_curses) { |
| tui_init(); |
| } |
| else { |
| ui_init(); |
| } |
|
|
pthread_create(&thread, NULL, (void*)&packet_loop, NULL); |
pthread_create(&thread, NULL, (void*)&packet_loop, NULL); |
|
|
ui_loop(); | /* Keep the starting time (used for timed termination) */ |
| first_timestamp = time(NULL); |
| |
| if (options.no_curses) { |
| if (options.timed_output) { |
| while(!foad) { |
| sleep(1); |
| } |
| } |
| else { |
| tui_loop(); |
| } |
| } |
| else { |
| ui_loop(); |
| } |
|
|
pthread_cancel(thread); |
pthread_cancel(thread); |
|
|