Author: marek Date: 2010-07-22 17:32:02 +0200 (Thu, 22 Jul 2010) New Revision: 1742
Modified: trunk/batctl/tcpdump.c Log: batctl: tcpdump add support for multiple header encapsulation
Signed-off-by: Marek Lindner lindner_marek@yahoo.de
Modified: trunk/batctl/tcpdump.c =================================================================== --- trunk/batctl/tcpdump.c 2010-07-22 15:32:01 UTC (rev 1741) +++ trunk/batctl/tcpdump.c 2010-07-22 15:32:02 UTC (rev 1742) @@ -50,8 +50,12 @@ return; \ }
+static unsigned short dump_level = DUMP_TYPE_BATOGM | DUMP_TYPE_BATICMP | DUMP_TYPE_BATUCAST | + DUMP_TYPE_BATBCAST | DUMP_TYPE_BATVIS | DUMP_TYPE_NONBAT;
-void tcpdump_usage(void) +static void parse_eth_hdr(unsigned char *packet_buff, ssize_t buff_len, int read_opt, int time_printed); + +static void tcpdump_usage(void) { printf("Usage: batctl tcpdump [options] interface [interface]\n"); printf("options:\n"); @@ -67,7 +71,7 @@ printf(" \t\t%d - batman ogm & non batman packets\n", DUMP_TYPE_BATOGM | DUMP_TYPE_NONBAT); }
-void print_time(void) +static int print_time(void) { struct timeval tv; struct tm *tm; @@ -76,16 +80,17 @@ tm = localtime(&tv.tv_sec);
printf("%02d:%02d:%02d.%06ld ", tm->tm_hour, tm->tm_min, tm->tm_sec, tv.tv_usec); + return 1; }
-void dump_arp(unsigned char *packet_buff, ssize_t buff_len, int time_printed) +static void dump_arp(unsigned char *packet_buff, ssize_t buff_len, int time_printed) { struct ether_arp *arphdr;
LEN_CHECK((size_t)buff_len, sizeof(struct ether_arp), "ARP");
if (!time_printed) - print_time(); + time_printed = print_time();
arphdr = (struct ether_arp *)packet_buff;
@@ -105,7 +110,7 @@ } }
-void dump_ip(unsigned char *packet_buff, ssize_t buff_len, int time_printed) +static void dump_ip(unsigned char *packet_buff, ssize_t buff_len, int time_printed) { struct iphdr *iphdr, *tmp_iphdr; struct tcphdr *tcphdr; @@ -116,7 +121,7 @@ LEN_CHECK((size_t)buff_len, (size_t)(iphdr->ihl * 4), "IP");
if (!time_printed) - print_time(); + time_printed = print_time();
switch (iphdr->protocol) { case IPPROTO_ICMP: @@ -221,35 +226,26 @@ } }
-void dump_vlan(unsigned char *packet_buff, ssize_t buff_len, int time_printed) +static void dump_vlan(unsigned char *packet_buff, ssize_t buff_len, int read_opt, int time_printed) { struct vlanhdr *vlanhdr;
- vlanhdr = (struct vlanhdr *)packet_buff; - LEN_CHECK((size_t)buff_len, sizeof(struct vlanhdr), "VLAN"); + vlanhdr = (struct vlanhdr *)(packet_buff + sizeof(struct ether_header)); + LEN_CHECK((size_t)buff_len, sizeof(struct ether_header) + sizeof(struct vlanhdr), "VLAN");
if (!time_printed) - print_time(); + time_printed = print_time();
vlanhdr->vid = ntohs(vlanhdr->vid); printf("vlan %u, p %u, ", vlanhdr->vid, vlanhdr->vid >> 12);
- switch (ntohs(vlanhdr->ether_type)) { - case ETH_P_ARP: - dump_arp(packet_buff + sizeof(struct vlanhdr), - buff_len - sizeof(struct vlanhdr), 1); - break; - case ETH_P_IP: - dump_ip(packet_buff + sizeof(struct vlanhdr), - buff_len - sizeof(struct vlanhdr), 1); - break; - default: - printf(" unknown payload ether type: 0x%04x\n", ntohs(vlanhdr->ether_type)); - break; - } + /* overwrite vlan tags */ + memmove(packet_buff + 4, packet_buff, 2 * ETH_ALEN); + + parse_eth_hdr(packet_buff + 4, buff_len - 4, read_opt, time_printed); }
-void dump_batman_ogm(unsigned char *packet_buff, ssize_t buff_len, int read_opt) +static void dump_batman_ogm(unsigned char *packet_buff, ssize_t buff_len, int read_opt, int time_printed) { struct ether_header *ether_header; struct batman_packet *batman_packet; @@ -259,7 +255,8 @@ ether_header = (struct ether_header *)packet_buff; batman_packet = (struct batman_packet *)(packet_buff + sizeof(struct ether_header));
- print_time(); + if (!time_printed) + time_printed = print_time();
printf("BAT %s: ", get_name_by_macaddr((struct ether_addr *)batman_packet->orig, read_opt)); @@ -274,7 +271,7 @@ (size_t)buff_len - sizeof(struct ether_header)); }
-void dump_batman_icmp(unsigned char *packet_buff, ssize_t buff_len, int read_opt) +static void dump_batman_icmp(unsigned char *packet_buff, ssize_t buff_len, int read_opt, int time_printed) { struct ether_header *ether_header; struct icmp_packet *icmp_packet; @@ -285,7 +282,8 @@ ether_header = (struct ether_header *)packet_buff; icmp_packet = (struct icmp_packet *)(packet_buff + sizeof(struct ether_header));
- print_time(); + if (!time_printed) + time_printed = print_time();
printf("BAT %s > ", get_name_by_macaddr((struct ether_addr *)icmp_packet->orig, read_opt));
@@ -317,7 +315,7 @@ } }
-void dump_batman_ucast(unsigned char *packet_buff, ssize_t buff_len, int read_opt) +static void dump_batman_ucast(unsigned char *packet_buff, ssize_t buff_len, int read_opt, int time_printed) { struct ether_header *ether_header; struct unicast_packet *unicast_packet; @@ -329,7 +327,8 @@ ether_header = (struct ether_header *)packet_buff; unicast_packet = (struct unicast_packet *)(packet_buff + sizeof(struct ether_header));
- print_time(); + if (!time_printed) + time_printed = print_time();
printf("BAT %s > ", get_name_by_macaddr((struct ether_addr *)ether_header->ether_shost, read_opt)); @@ -338,28 +337,12 @@ get_name_by_macaddr((struct ether_addr *)unicast_packet->dest, read_opt), unicast_packet->ttl);
- ether_header = (struct ether_header *)(packet_buff + sizeof(struct ether_header) + sizeof(struct unicast_packet)); - - switch (ntohs(ether_header->ether_type)) { - case ETH_P_ARP: - dump_arp(packet_buff + (2 * sizeof(struct ether_header)) + sizeof(struct unicast_packet), - buff_len - (2 * sizeof(struct ether_header)) - sizeof(struct unicast_packet), 1); - break; - case ETH_P_IP: - dump_ip(packet_buff + (2 * sizeof(struct ether_header)) + sizeof(struct unicast_packet), - buff_len - (2 * sizeof(struct ether_header)) - sizeof(struct unicast_packet), 1); - break; - case ETH_P_8021Q: - dump_vlan(packet_buff + (2 * sizeof(struct ether_header)) + sizeof(struct unicast_packet), - buff_len - (2 * sizeof(struct ether_header)) - sizeof(struct unicast_packet), 1); - break; - default: - printf(" unknown payload ether type: 0x%04x\n", ntohs(ether_header->ether_type)); - break; - } + parse_eth_hdr(packet_buff + ETH_HLEN + sizeof(struct unicast_packet), + buff_len - ETH_HLEN - sizeof(struct unicast_packet), + read_opt, time_printed); }
-void dump_batman_bcast(unsigned char *packet_buff, ssize_t buff_len, int read_opt) +static void dump_batman_bcast(unsigned char *packet_buff, ssize_t buff_len, int read_opt, int time_printed) { struct ether_header *ether_header; struct bcast_packet *bcast_packet; @@ -371,7 +354,8 @@ ether_header = (struct ether_header *)packet_buff; bcast_packet = (struct bcast_packet *)(packet_buff + sizeof(struct ether_header));
- print_time(); + if (!time_printed) + time_printed = print_time();
printf("BAT %s: ", get_name_by_macaddr((struct ether_addr *)ether_header->ether_shost, read_opt)); @@ -380,23 +364,66 @@ get_name_by_macaddr((struct ether_addr *)bcast_packet->orig, read_opt), ntohl(bcast_packet->seqno));
- ether_header = (struct ether_header *)(packet_buff + sizeof(struct ether_header) + sizeof(struct bcast_packet)); + parse_eth_hdr(packet_buff + ETH_HLEN + sizeof(struct bcast_packet), + buff_len - ETH_HLEN - sizeof(struct bcast_packet), + read_opt, time_printed); +}
- switch (ntohs(ether_header->ether_type)) { +static void parse_eth_hdr(unsigned char *packet_buff, ssize_t buff_len, int read_opt, int time_printed) +{ + struct batman_packet *batman_packet; + struct ether_header *eth_hdr; + + eth_hdr = (struct ether_header *)packet_buff; + + switch (ntohs(eth_hdr->ether_type)) { case ETH_P_ARP: - dump_arp(packet_buff + (2 * sizeof(struct ether_header)) + sizeof(struct bcast_packet), - buff_len - (2 * sizeof(struct ether_header)) - sizeof(struct bcast_packet), 1); + if (dump_level & DUMP_TYPE_NONBAT) + dump_arp(packet_buff + sizeof(struct ether_header), + buff_len - sizeof(struct ether_header), time_printed); break; case ETH_P_IP: - dump_ip(packet_buff + (2 * sizeof(struct ether_header)) + sizeof(struct bcast_packet), - buff_len - (2 * sizeof(struct ether_header)) - sizeof(struct bcast_packet), 1); + if (dump_level & DUMP_TYPE_NONBAT) + dump_ip(packet_buff + sizeof(struct ether_header), + buff_len - sizeof(struct ether_header), time_printed); break; case ETH_P_8021Q: - dump_vlan(packet_buff + (2 * sizeof(struct ether_header)) + sizeof(struct bcast_packet), - buff_len - (2 * sizeof(struct ether_header)) - sizeof(struct bcast_packet), 1); + if (dump_level & DUMP_TYPE_NONBAT) + dump_vlan(packet_buff, buff_len, read_opt, time_printed); break; + case ETH_P_BATMAN: + batman_packet = (struct batman_packet *)(packet_buff + sizeof(struct ether_header)); + + switch (batman_packet->packet_type) { + case BAT_PACKET: + if (dump_level & DUMP_TYPE_BATOGM) + dump_batman_ogm(packet_buff, buff_len, read_opt, time_printed); + break; + case BAT_ICMP: + if (dump_level & DUMP_TYPE_BATICMP) + dump_batman_icmp(packet_buff, buff_len, read_opt, time_printed); + break; + case BAT_UNICAST: + if (dump_level & DUMP_TYPE_BATUCAST) + dump_batman_ucast(packet_buff, buff_len, read_opt, time_printed); + break; + case BAT_BCAST: + if (dump_level & DUMP_TYPE_BATBCAST) + dump_batman_bcast(packet_buff, buff_len, read_opt, time_printed); + break; + case BAT_VIS: + if (dump_level & DUMP_TYPE_BATVIS) + printf("Warning - batman vis packet received: function not implemented yet\n"); + break; + default: + printf("Warning - packet contains unknown batman packet type: 0x%02x\n", batman_packet->packet_type); + break; + } + + break; + default: - printf(" unknown payload ether type: 0x%04x\n", ntohs(ether_header->ether_type)); + printf("Warning - packet contains unknown ether type: 0x%04x\n", ntohs(eth_hdr->ether_type)); break; } } @@ -406,14 +433,11 @@ struct ifreq req; struct timeval tv; struct dump_if *dump_if, *dump_if_tmp; - struct batman_packet *batman_packet; struct list_head_first dump_if_list; fd_set wait_sockets, tmp_wait_sockets; ssize_t read_len; - int ret = EXIT_FAILURE, res, optchar, found_args = 1, max_sock = 0, ether_type, tmp; + int ret = EXIT_FAILURE, res, optchar, found_args = 1, max_sock = 0, tmp; int read_opt = USE_BAT_HOSTS; - unsigned char dump_level = DUMP_TYPE_BATOGM | DUMP_TYPE_BATICMP | - DUMP_TYPE_BATUCAST | DUMP_TYPE_BATBCAST | DUMP_TYPE_BATVIS | DUMP_TYPE_NONBAT; unsigned char packet_buff[2000];
while ((optchar = getopt(argc, argv, "hnp:")) != -1) { @@ -534,56 +558,7 @@ continue; }
- ether_type = ntohs(((struct ether_header *)packet_buff)->ether_type); - - switch (ether_type) { - case ETH_P_ARP: - if (dump_level & DUMP_TYPE_NONBAT) - dump_arp(packet_buff + sizeof(struct ether_header), - read_len - sizeof(struct ether_header), 0); - break; - case ETH_P_IP: - if (dump_level & DUMP_TYPE_NONBAT) - dump_ip(packet_buff + sizeof(struct ether_header), - read_len - sizeof(struct ether_header), 0); - break; - case ETH_P_8021Q: - if (dump_level & DUMP_TYPE_NONBAT) - dump_vlan(packet_buff + sizeof(struct ether_header), - read_len - sizeof(struct ether_header), 0); - break; - case ETH_P_BATMAN: - batman_packet = (struct batman_packet *)(packet_buff + sizeof(struct ether_header)); - - switch (batman_packet->packet_type) { - case BAT_PACKET: - if (dump_level & DUMP_TYPE_BATOGM) - dump_batman_ogm(packet_buff, read_len, read_opt); - break; - case BAT_ICMP: - if (dump_level & DUMP_TYPE_BATICMP) - dump_batman_icmp(packet_buff, read_len, read_opt); - break; - case BAT_UNICAST: - if (dump_level & DUMP_TYPE_BATUCAST) - dump_batman_ucast(packet_buff, read_len, read_opt); - break; - case BAT_BCAST: - if (dump_level & DUMP_TYPE_BATBCAST) - dump_batman_bcast(packet_buff, read_len, read_opt); - break; - case BAT_VIS: - if (dump_level & DUMP_TYPE_BATVIS) - printf("Warning - batman vis packet received: function not implemented yet\n"); - break; - } - - break; - default: - printf("Warning - packet contains unknown ether type: 0x%04x\n", ether_type); - break; - } - + parse_eth_hdr(packet_buff, read_len, read_opt, 0); fflush(stdout); }