Author: simon Date: 2009-11-08 14:05:47 +0000 (Sun, 08 Nov 2009) New Revision: 1479
Added: tags/batctl-0.2/ping.c tags/batctl-0.2/tcpdump.c tags/batctl-0.2/traceroute.c Removed: tags/batctl-0.2/ping.c tags/batctl-0.2/tcpdump.c tags/batctl-0.2/traceroute.c Log: apply last minute patches r1476, r1477, r1478 on batctl-0.2 tags
Deleted: tags/batctl-0.2/ping.c =================================================================== --- tags/batctl-0.2/ping.c 2009-11-08 13:58:57 UTC (rev 1478) +++ tags/batctl-0.2/ping.c 2009-11-08 14:05:47 UTC (rev 1479) @@ -1,253 +0,0 @@ -/* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: - * - * Andreas Langer a.langer@q-dsl.de, Marek Lindner lindner_marek@yahoo.de - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - - - -#include <netinet/in.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <signal.h> -#include <fcntl.h> -#include <string.h> - -#include "main.h" -#include "ping.h" -#include "functions.h" -#include "packet.h" -#include "bat-hosts.h" - - -char is_aborted = 0; - - -void ping_usage(void) -{ - printf("Usage: batctl ping [options] mac|bat-host \n"); - printf("options:\n"); - printf(" \t -c ping packet count \n"); - printf(" \t -h print this help\n"); - printf(" \t -i interval in seconds\n"); - printf(" \t -t timeout in seconds\n"); -} - -void sig_handler(int sig) -{ - switch (sig) { - case SIGINT: - case SIGTERM: - is_aborted = 1; - break; - default: - break; - } -} - -int ping(int argc, char **argv) -{ - struct icmp_packet icmp_packet_out, icmp_packet_in; - struct timeval tv; - struct ether_addr *dst_mac = NULL; - struct bat_host *bat_host; - ssize_t read_len; - fd_set read_socket; - int ret = EXIT_FAILURE, ping_fd = 0, res, optchar, found_args = 1; - int loop_count = -1, loop_interval = 1, timeout = 1; - unsigned int seq_counter = 0, packets_out = 0, packets_in = 0; - char *dst_string, *mac_string; - double time_delta; - float min = 0.0, max = 0.0, avg = 0.0; - - while ((optchar = getopt(argc, argv, "hc:i:t:")) != -1) { - switch (optchar) { - case 'c': - loop_count = strtol(optarg, NULL , 10); - if (loop_count < 1) - loop_count = -1; - found_args += ((*((char*)(optarg - 1)) == optchar ) ? 1 : 2); - break; - case 'h': - ping_usage(); - return EXIT_SUCCESS; - case 'i': - loop_interval = strtol(optarg, NULL , 10); - if (loop_interval < 1) - loop_interval = 1; - found_args += ((*((char*)(optarg - 1)) == optchar ) ? 1 : 2); - break; - case 't': - timeout = strtol(optarg, NULL , 10); - if (timeout < 1) - timeout = 1; - found_args += ((*((char*)(optarg - 1)) == optchar ) ? 1 : 2); - break; - default: - ping_usage(); - return EXIT_FAILURE; - } - } - - if (argc <= found_args) { - printf("Error - target mac address or bat-host name not specified\n"); - ping_usage(); - return EXIT_FAILURE; - } - - dst_string = argv[found_args]; - bat_hosts_init(); - bat_host = bat_hosts_find_by_name(dst_string); - - if (bat_host) - dst_mac = &bat_host->mac_addr; - - if (!dst_mac) { - dst_mac = ether_aton(dst_string); - - if (!dst_mac) { - printf("Error - the ping destination is not a mac address or bat-host name: %s\n", dst_string); - goto out; - } - } - - mac_string = ether_ntoa_long(dst_mac); - signal(SIGINT, sig_handler); - signal(SIGTERM, sig_handler); - - ping_fd = open(BAT_DEVICE, O_RDWR); - - if (ping_fd < 0) { - printf("Error - can't open a connection to the batman adv kernel module via the device '%s': %s\n", - BAT_DEVICE, strerror(errno)); - printf("Check whether the module is loaded and active.\n"); - goto out; - } - - memcpy(&icmp_packet_out.dst, dst_mac, ETH_ALEN); - icmp_packet_out.packet_type = BAT_ICMP; - icmp_packet_out.version = COMPAT_VERSION; - icmp_packet_out.msg_type = ECHO_REQUEST; - icmp_packet_out.ttl = 50; - icmp_packet_out.seqno = 0; - - printf("PING %s (%s) %zi(%zi) bytes of data\n", dst_string, mac_string, - sizeof(icmp_packet_out), sizeof(icmp_packet_out) + 28); - - while (!is_aborted) { - if (loop_count == 0) - break; - - if (loop_count > 0) - loop_count--; - - icmp_packet_out.seqno = htons(++seq_counter); - - if (write(ping_fd, (char *)&icmp_packet_out, sizeof(icmp_packet_out)) < 0) { - printf("Error - can't write to batman adv kernel file '%s': %s\n", BAT_DEVICE, strerror(errno)); - goto sleep; - } - - start_timer(); - - tv.tv_sec = timeout; - tv.tv_usec = 0; - - FD_ZERO(&read_socket); - FD_SET(ping_fd, &read_socket); - - res = select(ping_fd + 1, &read_socket, NULL, NULL, &tv); - - if (is_aborted) - break; - - packets_out++; - - if (res == 0) { - printf("Reply from host %s timed out\n", dst_string); - goto sleep; - } - - if (res < 0) - goto sleep; - - read_len = read(ping_fd, (char *)&icmp_packet_in, sizeof(icmp_packet_in)); - - if (read_len < 0) { - printf("Error - can't read from batman adv kernel file '%s': %s\n", BAT_DEVICE, strerror(errno)); - goto sleep; - } - - if ((size_t)read_len < sizeof(icmp_packet_in)) { - printf("Warning - dropping received packet as it is smaller than expected (%zd): %zd\n", - sizeof(icmp_packet_in), read_len); - goto sleep; - } - - switch (icmp_packet_in.msg_type) { - case ECHO_REPLY: - time_delta = end_timer(); - printf("%zd bytes from %s icmp_seq=%u ttl=%d time=%.2f ms\n", - read_len, dst_string, ntohs(icmp_packet_in.seqno), - icmp_packet_in.ttl, time_delta); - - if ((time_delta < min) || (min == 0.0)) - min = time_delta; - if (time_delta > max) - max = time_delta; - avg += time_delta; - packets_in++; - break; - case DESTINATION_UNREACHABLE: - printf("From %s: Destination Host Unreachable (icmp_seq %u)\n", dst_string, ntohs(icmp_packet_in.seqno)); - break; - case TTL_EXCEEDED: - printf("From %s: Time to live exceeded (icmp_seq %u)\n", dst_string, ntohs(icmp_packet_in.seqno)); - break; - case PARAMETER_PROBLEM: - printf("Error - the batman adv kernel module version (%d) differs from ours (%d)\n", - icmp_packet_in.ttl, COMPAT_VERSION); - printf("Please make sure to compatible versions!\n"); - goto out; - default: - printf("Unknown message type %d len %zd received\n", icmp_packet_in.msg_type, read_len); - break; - } - -sleep: - if ((tv.tv_sec != 0) || (tv.tv_usec != 0)) - select(0, NULL, NULL, NULL, &tv); - - } - - printf("--- %s ping statistics ---\n", dst_string); - printf("%d packets transmitted, %d received, %d%% packet loss\n", - packets_out, packets_in, (((packets_out - packets_in) * 100) / packets_out)); - printf("rtt min/avg/max/mdev = %.3f/%.3f/%.3f/%.3f ms\n", - min, (packets_in ? (avg / packets_in) : 0.000), max, (max - min)); - - ret = EXIT_SUCCESS; - -out: - bat_hosts_free(); - if (ping_fd) - close(ping_fd); - return ret; -}
Copied: tags/batctl-0.2/ping.c (from rev 1478, trunk/batctl/ping.c) =================================================================== --- tags/batctl-0.2/ping.c (rev 0) +++ tags/batctl-0.2/ping.c 2009-11-08 14:05:47 UTC (rev 1479) @@ -0,0 +1,258 @@ +/* + * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * + * Andreas Langer a.langer@q-dsl.de, Marek Lindner lindner_marek@yahoo.de + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + + + +#include <netinet/in.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <signal.h> +#include <fcntl.h> +#include <string.h> + +#include "main.h" +#include "ping.h" +#include "functions.h" +#include "packet.h" +#include "bat-hosts.h" + + +char is_aborted = 0; + + +void ping_usage(void) +{ + printf("Usage: batctl ping [options] mac|bat-host \n"); + printf("options:\n"); + printf(" \t -c ping packet count \n"); + printf(" \t -h print this help\n"); + printf(" \t -i interval in seconds\n"); + printf(" \t -t timeout in seconds\n"); +} + +void sig_handler(int sig) +{ + switch (sig) { + case SIGINT: + case SIGTERM: + is_aborted = 1; + break; + default: + break; + } +} + +int ping(int argc, char **argv) +{ + struct icmp_packet icmp_packet_out, icmp_packet_in; + struct timeval tv; + struct ether_addr *dst_mac = NULL; + struct bat_host *bat_host; + ssize_t read_len; + fd_set read_socket; + int ret = EXIT_FAILURE, ping_fd = 0, res, optchar, found_args = 1; + int loop_count = -1, loop_interval = 1, timeout = 1; + unsigned int seq_counter = 0, packets_out = 0, packets_in = 0, packets_loss; + char *dst_string, *mac_string; + double time_delta; + float min = 0.0, max = 0.0, avg = 0.0; + + while ((optchar = getopt(argc, argv, "hc:i:t:")) != -1) { + switch (optchar) { + case 'c': + loop_count = strtol(optarg, NULL , 10); + if (loop_count < 1) + loop_count = -1; + found_args += ((*((char*)(optarg - 1)) == optchar ) ? 1 : 2); + break; + case 'h': + ping_usage(); + return EXIT_SUCCESS; + case 'i': + loop_interval = strtol(optarg, NULL , 10); + if (loop_interval < 1) + loop_interval = 1; + found_args += ((*((char*)(optarg - 1)) == optchar ) ? 1 : 2); + break; + case 't': + timeout = strtol(optarg, NULL , 10); + if (timeout < 1) + timeout = 1; + found_args += ((*((char*)(optarg - 1)) == optchar ) ? 1 : 2); + break; + default: + ping_usage(); + return EXIT_FAILURE; + } + } + + if (argc <= found_args) { + printf("Error - target mac address or bat-host name not specified\n"); + ping_usage(); + return EXIT_FAILURE; + } + + dst_string = argv[found_args]; + bat_hosts_init(); + bat_host = bat_hosts_find_by_name(dst_string); + + if (bat_host) + dst_mac = &bat_host->mac_addr; + + if (!dst_mac) { + dst_mac = ether_aton(dst_string); + + if (!dst_mac) { + printf("Error - the ping destination is not a mac address or bat-host name: %s\n", dst_string); + goto out; + } + } + + mac_string = ether_ntoa_long(dst_mac); + signal(SIGINT, sig_handler); + signal(SIGTERM, sig_handler); + + ping_fd = open(BAT_DEVICE, O_RDWR); + + if (ping_fd < 0) { + printf("Error - can't open a connection to the batman adv kernel module via the device '%s': %s\n", + BAT_DEVICE, strerror(errno)); + printf("Check whether the module is loaded and active.\n"); + goto out; + } + + memcpy(&icmp_packet_out.dst, dst_mac, ETH_ALEN); + icmp_packet_out.packet_type = BAT_ICMP; + icmp_packet_out.version = COMPAT_VERSION; + icmp_packet_out.msg_type = ECHO_REQUEST; + icmp_packet_out.ttl = 50; + icmp_packet_out.seqno = 0; + + printf("PING %s (%s) %zu(%zu) bytes of data\n", dst_string, mac_string, + sizeof(icmp_packet_out), sizeof(icmp_packet_out) + 28); + + while (!is_aborted) { + if (loop_count == 0) + break; + + if (loop_count > 0) + loop_count--; + + icmp_packet_out.seqno = htons(++seq_counter); + + if (write(ping_fd, (char *)&icmp_packet_out, sizeof(icmp_packet_out)) < 0) { + printf("Error - can't write to batman adv kernel file '%s': %s\n", BAT_DEVICE, strerror(errno)); + goto sleep; + } + + start_timer(); + + tv.tv_sec = timeout; + tv.tv_usec = 0; + + FD_ZERO(&read_socket); + FD_SET(ping_fd, &read_socket); + + res = select(ping_fd + 1, &read_socket, NULL, NULL, &tv); + + if (is_aborted) + break; + + packets_out++; + + if (res == 0) { + printf("Reply from host %s timed out\n", dst_string); + goto sleep; + } + + if (res < 0) + goto sleep; + + read_len = read(ping_fd, (char *)&icmp_packet_in, sizeof(icmp_packet_in)); + + if (read_len < 0) { + printf("Error - can't read from batman adv kernel file '%s': %s\n", BAT_DEVICE, strerror(errno)); + goto sleep; + } + + if ((size_t)read_len < sizeof(icmp_packet_in)) { + printf("Warning - dropping received packet as it is smaller than expected (%zu): %zd\n", + sizeof(icmp_packet_in), read_len); + goto sleep; + } + + switch (icmp_packet_in.msg_type) { + case ECHO_REPLY: + time_delta = end_timer(); + printf("%zd bytes from %s icmp_seq=%hu ttl=%d time=%.2f ms\n", + read_len, dst_string, ntohs(icmp_packet_in.seqno), + icmp_packet_in.ttl, time_delta); + + if ((time_delta < min) || (min == 0.0)) + min = time_delta; + if (time_delta > max) + max = time_delta; + avg += time_delta; + packets_in++; + break; + case DESTINATION_UNREACHABLE: + printf("From %s: Destination Host Unreachable (icmp_seq %hu)\n", dst_string, ntohs(icmp_packet_in.seqno)); + break; + case TTL_EXCEEDED: + printf("From %s: Time to live exceeded (icmp_seq %hu)\n", dst_string, ntohs(icmp_packet_in.seqno)); + break; + case PARAMETER_PROBLEM: + printf("Error - the batman adv kernel module version (%d) differs from ours (%d)\n", + icmp_packet_in.ttl, COMPAT_VERSION); + printf("Please make sure to compatible versions!\n"); + goto out; + default: + printf("Unknown message type %d len %zd received\n", icmp_packet_in.msg_type, read_len); + break; + } + +sleep: + if ((tv.tv_sec != 0) || (tv.tv_usec != 0)) + select(0, NULL, NULL, NULL, &tv); + + } + + if (packets_out == 0) + packets_loss = 0; + else + packets_loss = ((packets_out - packets_in) * 100) / packets_out; + + printf("--- %s ping statistics ---\n", dst_string); + printf("%u packets transmitted, %u received, %u%% packet loss\n", + packets_out, packets_in, packets_loss); + printf("rtt min/avg/max/mdev = %.3f/%.3f/%.3f/%.3f ms\n", + min, (packets_in ? (avg / packets_in) : 0.000), max, (max - min)); + + ret = EXIT_SUCCESS; + +out: + bat_hosts_free(); + if (ping_fd) + close(ping_fd); + return ret; +}
Property changes on: tags/batctl-0.2/ping.c ___________________________________________________________________ Added: svn:mergeinfo +
Deleted: tags/batctl-0.2/tcpdump.c =================================================================== --- tags/batctl-0.2/tcpdump.c 2009-11-08 13:58:57 UTC (rev 1478) +++ tags/batctl-0.2/tcpdump.c 2009-11-08 14:05:47 UTC (rev 1479) @@ -1,563 +0,0 @@ -/* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: - * - * Andreas Langer a.langer@q-dsl.de - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <errno.h> -#include <sys/ioctl.h> -#include <time.h> -#include <sys/time.h> -#include <arpa/inet.h> -#include <net/if.h> -#include <netinet/in.h> -#include <netinet/ip.h> -#include <netinet/tcp.h> -#include <netinet/udp.h> -#include <netinet/ip_icmp.h> -#include <netinet/if_ether.h> - -#include "main.h" -#include "tcpdump.h" -#include "packet.h" -#include "bat-hosts.h" -#include "functions.h" - - -#define LEN_CHECK(buff_len, check_len, desc) \ -if ((size_t)(buff_len) < (check_len)) { \ - printf("Warning - dropping received %s packet as it is smaller than expected (%zd): %zd\n", \ - desc, (check_len), (size_t)(buff_len)); \ - return; \ -} - - -void tcpdump_usage(void) -{ - printf("Usage: batctl tcpdump [options] interface [interface]\n"); - printf("options:\n"); - printf(" \t -h print this help\n"); - printf(" \t -n don't convert addresses to bat-host names\n"); - printf(" \t -p dump specific packet type\n"); - printf(" \t\t%d - batman ogm packets\n", DUMP_TYPE_BATOGM); - printf(" \t\t%d - batman icmp packets\n", DUMP_TYPE_BATICMP); - printf(" \t\t%d - batman unicast packets\n", DUMP_TYPE_BATUCAST); - printf(" \t\t%d - batman broadcast packets\n", DUMP_TYPE_BATBCAST); - printf(" \t\t%d - batman vis packets\n", DUMP_TYPE_BATVIS); - printf(" \t\t%d - non batman packets\n", DUMP_TYPE_NONBAT); - printf(" \t\t%d - batman ogm & non batman packets\n", DUMP_TYPE_BATOGM | DUMP_TYPE_NONBAT); -} - -void print_time(void) -{ - struct timeval tv; - struct tm *tm; - - gettimeofday(&tv, NULL); - tm = localtime(&tv.tv_sec); - - printf("%02d:%02d:%02d.%06ld ", tm->tm_hour, tm->tm_min, tm->tm_sec, tv.tv_usec); -} - -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(); - - arphdr = (struct ether_arp *)packet_buff; - - switch (ntohs(arphdr->arp_op)) { - case ARPOP_REQUEST: - printf("ARP, Request who-has %s", inet_ntoa(*(struct in_addr *)&arphdr->arp_tpa)); - printf(" tell %s (%s), length %zd\n", inet_ntoa(*(struct in_addr *)&arphdr->arp_spa), - ether_ntoa_long((struct ether_addr *)&arphdr->arp_sha), buff_len); - break; - case ARPOP_REPLY: - printf("ARP, Reply %s is-at %s, length %zd\n", inet_ntoa(*(struct in_addr *)&arphdr->arp_spa), - ether_ntoa_long((struct ether_addr *)&arphdr->arp_sha), buff_len); - break; - default: - printf("ARP, unknown op code: %i\n", ntohs(arphdr->arp_op)); - break; - } -} - -void dump_ip(unsigned char *packet_buff, ssize_t buff_len, int time_printed) -{ - struct iphdr *iphdr, *tmp_iphdr; - struct tcphdr *tcphdr; - struct udphdr *udphdr, *tmp_udphdr; - struct icmphdr *icmphdr; - - iphdr = (struct iphdr *)packet_buff; - LEN_CHECK((size_t)buff_len, (size_t)(iphdr->ihl * 4), "IP"); - - if (!time_printed) - print_time(); - - switch (iphdr->protocol) { - case IPPROTO_ICMP: - LEN_CHECK((size_t)buff_len - (iphdr->ihl * 4), sizeof(struct icmphdr), "ICMP"); - - icmphdr = (struct icmphdr *)(packet_buff + (iphdr->ihl * 4)); - printf("IP %s > ", inet_ntoa(*(struct in_addr *)&iphdr->saddr)); - - switch (icmphdr->type) { - case ICMP_ECHOREPLY: - printf("%s: ICMP echo reply, id %u, seq %u, length %zd\n", - inet_ntoa(*(struct in_addr *)&iphdr->daddr), - ntohs(icmphdr->un.echo.id), ntohs(icmphdr->un.echo.sequence), - (size_t)buff_len - (iphdr->ihl * 4)); - break; - case ICMP_DEST_UNREACH: - LEN_CHECK((size_t)buff_len - (iphdr->ihl * 4) - sizeof(struct icmphdr), - sizeof(struct iphdr) + 8, "ICMP DEST_UNREACH"); - - switch (icmphdr->code) { - case ICMP_PORT_UNREACH: - tmp_iphdr = (struct iphdr *)(((char *)icmphdr) + sizeof(struct icmphdr)); - tmp_udphdr = (struct udphdr *)(((char *)tmp_iphdr) + (tmp_iphdr->ihl * 4)); - - printf("%s: ICMP ", inet_ntoa(*(struct in_addr *)&iphdr->daddr)); - printf("%s udp port %u unreachable, length %zd\n", - inet_ntoa(*(struct in_addr *)&tmp_iphdr->daddr), - ntohs(tmp_udphdr->dest), (size_t)buff_len - (iphdr->ihl * 4)); - break; - default: - printf("%s: ICMP unreachable %u, length %zd\n", - inet_ntoa(*(struct in_addr *)&iphdr->daddr), - icmphdr->code, (size_t)buff_len - (iphdr->ihl * 4)); - break; - } - - break; - case ICMP_ECHO: - printf("%s: ICMP echo request, id %u, seq %u, length %zd\n", - inet_ntoa(*(struct in_addr *)&iphdr->daddr), - ntohs(icmphdr->un.echo.id), ntohs(icmphdr->un.echo.sequence), - (size_t)buff_len - (iphdr->ihl * 4)); - break; - case ICMP_TIME_EXCEEDED: - printf("%s: ICMP time exceeded in-transit, length %zd\n", - inet_ntoa(*(struct in_addr *)&iphdr->daddr), - (size_t)buff_len - (iphdr->ihl * 4)); - break; - default: - printf("%s: ICMP type %u, length %zd\n", - inet_ntoa(*(struct in_addr *)&iphdr->daddr), icmphdr->type, - (size_t)buff_len - (iphdr->ihl * 4)); - break; - } - - break; - case IPPROTO_TCP: - LEN_CHECK((size_t)buff_len - (iphdr->ihl * 4), sizeof(struct tcphdr), "TCP"); - - tcphdr = (struct tcphdr *)(packet_buff + (iphdr->ihl * 4)); - printf("IP %s.%i > ", inet_ntoa(*(struct in_addr *)&iphdr->saddr), ntohs(tcphdr->source)); - printf("%s.%i: TCP, flags [%c%c%c%c%c%c], length %zd\n", - inet_ntoa(*(struct in_addr *)&iphdr->daddr), ntohs(tcphdr->dest), - (tcphdr->fin ? 'F' : '.'), (tcphdr->syn ? 'S' : '.'), - (tcphdr->rst ? 'R' : '.'), (tcphdr->psh ? 'P' : '.'), - (tcphdr->ack ? 'A' : '.'), (tcphdr->urg ? 'U' : '.'), - (size_t)buff_len - (iphdr->ihl * 4) - sizeof(struct tcphdr)); - break; - case IPPROTO_UDP: - LEN_CHECK((size_t)buff_len - (iphdr->ihl * 4), sizeof(struct udphdr), "UDP"); - - udphdr = (struct udphdr *)(packet_buff + (iphdr->ihl * 4)); - printf("IP %s.%i > ", inet_ntoa(*(struct in_addr *)&iphdr->saddr), ntohs(udphdr->source)); - - switch (ntohs(udphdr->dest)) { - case 67: - LEN_CHECK((size_t)buff_len - (iphdr->ihl * 4) - sizeof(struct udphdr), (size_t) 44, "DHCP"); - printf("%s.67: BOOTP/DHCP, Request from %s, length %zd\n", - inet_ntoa(*(struct in_addr *)&iphdr->daddr), - ether_ntoa_long((struct ether_addr *)(((char *)udphdr) + sizeof(struct udphdr) + 28)), - (size_t)buff_len - (iphdr->ihl * 4) - sizeof(struct udphdr)); - break; - case 68: - printf("%s.68: BOOTP/DHCP, Reply, length %zd\n", - inet_ntoa(*(struct in_addr *)&iphdr->daddr), - (size_t)buff_len - (iphdr->ihl * 4) - sizeof(struct udphdr)); - break; - default: - printf("%s.%i: UDP, length %zd\n", - inet_ntoa(*(struct in_addr *)&iphdr->daddr), ntohs(udphdr->dest), - (size_t)buff_len - (iphdr->ihl * 4) - sizeof(struct udphdr)); - break; - } - - break; - case IPPROTO_IPV6: - printf("IP6: not implemented yet\n"); - break; - default: - printf("IP unknown protocol: %i\n", iphdr->protocol); - break; - } -} - -void dump_batman_ogm(unsigned char *packet_buff, ssize_t buff_len, int read_opt) -{ - struct ether_header *ether_header; - struct batman_packet *batman_packet; - - LEN_CHECK((size_t)buff_len - sizeof(struct ether_header), sizeof(struct batman_packet), "BAT OGM"); - - ether_header = (struct ether_header *)packet_buff; - batman_packet = (struct batman_packet *)(packet_buff + sizeof(struct ether_header)); - - print_time(); - - printf("BAT %s: ", - get_name_by_macaddr((struct ether_addr *)batman_packet->orig, read_opt)); - - printf("OGM via neigh %s, seqno %d, tq %3d, ttl %2d, v %d, flags [%c%c], length %zd\n", - get_name_by_macaddr((struct ether_addr *)ether_header->ether_shost, read_opt), - ntohs(batman_packet->seqno), batman_packet->tq, - batman_packet->ttl, batman_packet->version, - (batman_packet->flags & VIS_SERVER ? 'V' : '.'), - (batman_packet->flags & DIRECTLINK ? 'D' : '.'), - (size_t)buff_len - sizeof(struct ether_header)); -} - -void dump_batman_icmp(unsigned char *packet_buff, ssize_t buff_len, int read_opt) -{ - struct ether_header *ether_header; - struct icmp_packet *icmp_packet; - char *name; - - LEN_CHECK((size_t)buff_len - sizeof(struct ether_header), sizeof(struct icmp_packet), "BAT ICMP"); - - ether_header = (struct ether_header *)packet_buff; - icmp_packet = (struct icmp_packet *)(packet_buff + sizeof(struct ether_header)); - - print_time(); - - printf("BAT %s > ", get_name_by_macaddr((struct ether_addr *)icmp_packet->orig, read_opt)); - - name = get_name_by_macaddr((struct ether_addr *)icmp_packet->dst, read_opt); - - switch (icmp_packet->msg_type) { - case ECHO_REPLY: - printf("%s: ICMP echo reply, id %u, seq %u, ttl %2d, v %d, length %zd\n", - name, icmp_packet->uid, ntohs(icmp_packet->seqno), - icmp_packet->ttl, icmp_packet->version, - (size_t)buff_len - sizeof(struct ether_header)); - break; - case ECHO_REQUEST: - printf("%s: ICMP echo request, id %u, seq %u, ttl %2d, v %d, length %zd\n", - name, icmp_packet->uid, ntohs(icmp_packet->seqno), - icmp_packet->ttl, icmp_packet->version, - (size_t)buff_len - sizeof(struct ether_header)); - break; - case TTL_EXCEEDED: - printf("%s: ICMP time exceeded in-transit, id %u, seq %u, ttl %2d, v %d, length %zd\n", - name, icmp_packet->uid, ntohs(icmp_packet->seqno), - icmp_packet->ttl, icmp_packet->version, - (size_t)buff_len - sizeof(struct ether_header)); - break; - default: - printf("%s: ICMP type %u, length %zd\n", - name, icmp_packet->msg_type, (size_t)buff_len - sizeof(struct ether_header)); - break; - } -} - -void dump_batman_ucast(unsigned char *packet_buff, ssize_t buff_len, int read_opt) -{ - struct ether_header *ether_header; - struct unicast_packet *unicast_packet; - - LEN_CHECK((size_t)buff_len - sizeof(struct ether_header), sizeof(struct unicast_packet), "BAT UCAST"); - LEN_CHECK((size_t)buff_len - sizeof(struct ether_header) - sizeof(struct unicast_packet), - sizeof(struct ether_header), "BAT UCAST (unpacked)"); - - ether_header = (struct ether_header *)packet_buff; - unicast_packet = (struct unicast_packet *)(packet_buff + sizeof(struct ether_header)); - - print_time(); - - printf("BAT %s > ", - get_name_by_macaddr((struct ether_addr *)ether_header->ether_shost, read_opt)); - - printf("%s: UCAST, ttl %u, ", - 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; - default: - printf(" unknown payload ether type: %u\n", ntohs(ether_header->ether_type)); - break; - } -} - -void dump_batman_bcast(unsigned char *packet_buff, ssize_t buff_len, int read_opt) -{ - struct ether_header *ether_header; - struct bcast_packet *bcast_packet; - - LEN_CHECK((size_t)buff_len - sizeof(struct ether_header), sizeof(struct bcast_packet), "BAT BCAST"); - LEN_CHECK((size_t)buff_len - sizeof(struct ether_header) - sizeof(struct bcast_packet), - sizeof(struct ether_header), "BAT BCAST (unpacked)"); - - ether_header = (struct ether_header *)packet_buff; - bcast_packet = (struct bcast_packet *)(packet_buff + sizeof(struct ether_header)); - - print_time(); - - printf("BAT %s: ", - get_name_by_macaddr((struct ether_addr *)ether_header->ether_shost, read_opt)); - - printf("BCAST, orig %s, seqno %u, ", - get_name_by_macaddr((struct ether_addr *)bcast_packet->orig, read_opt), - ntohs(bcast_packet->seqno)); - - ether_header = (struct ether_header *)(packet_buff + sizeof(struct ether_header) + sizeof(struct bcast_packet)); - - switch (ntohs(ether_header->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); - 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); - break; - default: - printf(" unknown payload ether type: %u\n", ntohs(ether_header->ether_type)); - break; - } -} - -int tcpdump(int argc, char **argv) -{ - 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 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) { - switch (optchar) { - case 'h': - tcpdump_usage(); - return EXIT_SUCCESS; - case 'n': - read_opt &= ~USE_BAT_HOSTS; - found_args += 1; - break; - case 'p': - tmp = strtol(optarg, NULL , 10); - if ((tmp > 0) && (tmp <= dump_level)) - dump_level = tmp; - found_args += ((*((char*)(optarg - 1)) == optchar ) ? 1 : 2); - break; - default: - tcpdump_usage(); - return EXIT_FAILURE; - } - } - - if (argc <= found_args) { - printf("Error - target interface not specified\n"); - tcpdump_usage(); - return EXIT_FAILURE; - } - - bat_hosts_init(); - - /* init interfaces list */ - INIT_LIST_HEAD_FIRST(dump_if_list); - FD_ZERO(&wait_sockets); - - while (argc > found_args) { - - dump_if = malloc(sizeof(struct dump_if)); - memset(dump_if, 0, sizeof(struct dump_if)); - INIT_LIST_HEAD(&dump_if->list); - - dump_if->dev = argv[found_args]; - - if (strlen(dump_if->dev) > IFNAMSIZ - 1) { - printf("Error - interface name too long: %s\n", dump_if->dev); - goto out; - } - - dump_if->raw_sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); - - if (dump_if->raw_sock < 0) { - printf("Error - can't create raw socket: %s\n", strerror(errno)); - goto out; - } - - memset(&req, 0, sizeof (struct ifreq)); - strncpy(req.ifr_name, dump_if->dev, IFNAMSIZ); - - res = ioctl(dump_if->raw_sock, SIOCGIFINDEX, &req); - - if (res < 0) { - printf("Error - can't create raw socket (SIOCGIFINDEX): %s\n", strerror(errno)); - close(dump_if->raw_sock); - goto out; - } - - dump_if->addr.sll_family = AF_PACKET; - dump_if->addr.sll_protocol = htons(ETH_P_ALL); - dump_if->addr.sll_ifindex = req.ifr_ifindex; - - res = bind(dump_if->raw_sock, (struct sockaddr *)&dump_if->addr, sizeof(struct sockaddr_ll)); - - if (res < 0) { - printf("Error - can't bind raw socket: %s\n", strerror(errno)); - close(dump_if->raw_sock); - goto out; - } - - if (dump_if->raw_sock > max_sock) - max_sock = dump_if->raw_sock; - - FD_SET(dump_if->raw_sock, &wait_sockets); - list_add_tail(&dump_if->list, &dump_if_list); - found_args++; - } - - while (1) { - - memcpy(&tmp_wait_sockets, &wait_sockets, sizeof(fd_set)); - - tv.tv_sec = 1; - tv.tv_usec = 0; - - res = select(max_sock + 1, &tmp_wait_sockets, NULL, NULL, &tv); - - if (res == 0) - continue; - - if (res < 0) { - printf("Error - can't select on raw socket: %s\n", strerror(errno)); - continue; - } - - list_for_each_entry(dump_if, &dump_if_list, list) { - if (!FD_ISSET(dump_if->raw_sock, &tmp_wait_sockets)) - continue; - - read_len = read(dump_if->raw_sock, packet_buff, sizeof(packet_buff)); - - if (read_len < 0) { - printf("Error - can't read from interface '%s': %s\n", dump_if->dev, strerror(errno)); - continue; - } - - if ((size_t)read_len < sizeof(struct ether_header)) { - printf("Warning - dropping received packet as it is smaller than expected (%zd): %zd\n", - sizeof(struct ether_header), read_len); - 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_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: %u\n", ether_type); - break; - } - - fflush(stdout); - } - - } - - ret = EXIT_SUCCESS; - -out: - list_for_each_entry_safe(dump_if, dump_if_tmp, &dump_if_list, list) { - if (dump_if->raw_sock) - close(dump_if->raw_sock); - - list_del((struct list_head *)&dump_if_list, &dump_if->list, &dump_if_list); - free(dump_if); - } - - bat_hosts_free(); - return ret; -}
Copied: tags/batctl-0.2/tcpdump.c (from rev 1478, trunk/batctl/tcpdump.c) =================================================================== --- tags/batctl-0.2/tcpdump.c (rev 0) +++ tags/batctl-0.2/tcpdump.c 2009-11-08 14:05:47 UTC (rev 1479) @@ -0,0 +1,561 @@ +/* + * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * + * Andreas Langer a.langer@q-dsl.de + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <errno.h> +#include <sys/ioctl.h> +#include <time.h> +#include <sys/time.h> +#include <arpa/inet.h> +#include <net/if.h> +#include <netinet/in.h> +#include <netinet/ip.h> +#include <netinet/tcp.h> +#include <netinet/udp.h> +#include <netinet/ip_icmp.h> +#include <netinet/if_ether.h> + +#include "main.h" +#include "tcpdump.h" +#include "packet.h" +#include "bat-hosts.h" +#include "functions.h" + + +#define LEN_CHECK(buff_len, check_len, desc) \ +if ((size_t)(buff_len) < (check_len)) { \ + printf("Warning - dropping received %s packet as it is smaller than expected (%zu): %zu\n", \ + desc, (check_len), (size_t)(buff_len)); \ + return; \ +} + + +void tcpdump_usage(void) +{ + printf("Usage: batctl tcpdump [options] interface [interface]\n"); + printf("options:\n"); + printf(" \t -h print this help\n"); + printf(" \t -n don't convert addresses to bat-host names\n"); + printf(" \t -p dump specific packet type\n"); + printf(" \t\t%d - batman ogm packets\n", DUMP_TYPE_BATOGM); + printf(" \t\t%d - batman icmp packets\n", DUMP_TYPE_BATICMP); + printf(" \t\t%d - batman unicast packets\n", DUMP_TYPE_BATUCAST); + printf(" \t\t%d - batman broadcast packets\n", DUMP_TYPE_BATBCAST); + printf(" \t\t%d - batman vis packets\n", DUMP_TYPE_BATVIS); + printf(" \t\t%d - non batman packets\n", DUMP_TYPE_NONBAT); + printf(" \t\t%d - batman ogm & non batman packets\n", DUMP_TYPE_BATOGM | DUMP_TYPE_NONBAT); +} + +void print_time(void) +{ + struct timeval tv; + struct tm *tm; + + gettimeofday(&tv, NULL); + tm = localtime(&tv.tv_sec); + + printf("%02d:%02d:%02d.%06ld ", tm->tm_hour, tm->tm_min, tm->tm_sec, tv.tv_usec); +} + +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(); + + arphdr = (struct ether_arp *)packet_buff; + + switch (ntohs(arphdr->arp_op)) { + case ARPOP_REQUEST: + printf("ARP, Request who-has %s", inet_ntoa(*(struct in_addr *)&arphdr->arp_tpa)); + printf(" tell %s (%s), length %zd\n", inet_ntoa(*(struct in_addr *)&arphdr->arp_spa), + ether_ntoa_long((struct ether_addr *)&arphdr->arp_sha), buff_len); + break; + case ARPOP_REPLY: + printf("ARP, Reply %s is-at %s, length %zd\n", inet_ntoa(*(struct in_addr *)&arphdr->arp_spa), + ether_ntoa_long((struct ether_addr *)&arphdr->arp_sha), buff_len); + break; + default: + printf("ARP, unknown op code: %i\n", ntohs(arphdr->arp_op)); + break; + } +} + +void dump_ip(unsigned char *packet_buff, ssize_t buff_len, int time_printed) +{ + struct iphdr *iphdr, *tmp_iphdr; + struct tcphdr *tcphdr; + struct udphdr *udphdr, *tmp_udphdr; + struct icmphdr *icmphdr; + + iphdr = (struct iphdr *)packet_buff; + LEN_CHECK((size_t)buff_len, (size_t)(iphdr->ihl * 4), "IP"); + + if (!time_printed) + print_time(); + + switch (iphdr->protocol) { + case IPPROTO_ICMP: + LEN_CHECK((size_t)buff_len - (iphdr->ihl * 4), sizeof(struct icmphdr), "ICMP"); + + icmphdr = (struct icmphdr *)(packet_buff + (iphdr->ihl * 4)); + printf("IP %s > ", inet_ntoa(*(struct in_addr *)&iphdr->saddr)); + + switch (icmphdr->type) { + case ICMP_ECHOREPLY: + printf("%s: ICMP echo reply, id %hu, seq %hu, length %zu\n", + inet_ntoa(*(struct in_addr *)&iphdr->daddr), + ntohs(icmphdr->un.echo.id), ntohs(icmphdr->un.echo.sequence), + (size_t)buff_len - (iphdr->ihl * 4)); + break; + case ICMP_DEST_UNREACH: + LEN_CHECK((size_t)buff_len - (iphdr->ihl * 4) - sizeof(struct icmphdr), + sizeof(struct iphdr) + 8, "ICMP DEST_UNREACH"); + + switch (icmphdr->code) { + case ICMP_PORT_UNREACH: + tmp_iphdr = (struct iphdr *)(((char *)icmphdr) + sizeof(struct icmphdr)); + tmp_udphdr = (struct udphdr *)(((char *)tmp_iphdr) + (tmp_iphdr->ihl * 4)); + + printf("%s: ICMP ", inet_ntoa(*(struct in_addr *)&iphdr->daddr)); + printf("%s udp port %hu unreachable, length %zu\n", + inet_ntoa(*(struct in_addr *)&tmp_iphdr->daddr), + ntohs(tmp_udphdr->dest), (size_t)buff_len - (iphdr->ihl * 4)); + break; + default: + printf("%s: ICMP unreachable %hhu, length %zu\n", + inet_ntoa(*(struct in_addr *)&iphdr->daddr), + icmphdr->code, (size_t)buff_len - (iphdr->ihl * 4)); + break; + } + + break; + case ICMP_ECHO: + printf("%s: ICMP echo request, id %hu, seq %hu, length %zu\n", + inet_ntoa(*(struct in_addr *)&iphdr->daddr), + ntohs(icmphdr->un.echo.id), ntohs(icmphdr->un.echo.sequence), + (size_t)buff_len - (iphdr->ihl * 4)); + break; + case ICMP_TIME_EXCEEDED: + printf("%s: ICMP time exceeded in-transit, length %zu\n", + inet_ntoa(*(struct in_addr *)&iphdr->daddr), + (size_t)buff_len - (iphdr->ihl * 4)); + break; + default: + printf("%s: ICMP type %hhu, length %zu\n", + inet_ntoa(*(struct in_addr *)&iphdr->daddr), icmphdr->type, + (size_t)buff_len - (iphdr->ihl * 4)); + break; + } + + break; + case IPPROTO_TCP: + LEN_CHECK((size_t)buff_len - (iphdr->ihl * 4), sizeof(struct tcphdr), "TCP"); + + tcphdr = (struct tcphdr *)(packet_buff + (iphdr->ihl * 4)); + printf("IP %s.%i > ", inet_ntoa(*(struct in_addr *)&iphdr->saddr), ntohs(tcphdr->source)); + printf("%s.%i: TCP, flags [%c%c%c%c%c%c], length %zu\n", + inet_ntoa(*(struct in_addr *)&iphdr->daddr), ntohs(tcphdr->dest), + (tcphdr->fin ? 'F' : '.'), (tcphdr->syn ? 'S' : '.'), + (tcphdr->rst ? 'R' : '.'), (tcphdr->psh ? 'P' : '.'), + (tcphdr->ack ? 'A' : '.'), (tcphdr->urg ? 'U' : '.'), + (size_t)buff_len - (iphdr->ihl * 4) - sizeof(struct tcphdr)); + break; + case IPPROTO_UDP: + LEN_CHECK((size_t)buff_len - (iphdr->ihl * 4), sizeof(struct udphdr), "UDP"); + + udphdr = (struct udphdr *)(packet_buff + (iphdr->ihl * 4)); + printf("IP %s.%i > ", inet_ntoa(*(struct in_addr *)&iphdr->saddr), ntohs(udphdr->source)); + + switch (ntohs(udphdr->dest)) { + case 67: + LEN_CHECK((size_t)buff_len - (iphdr->ihl * 4) - sizeof(struct udphdr), (size_t) 44, "DHCP"); + printf("%s.67: BOOTP/DHCP, Request from %s, length %zu\n", + inet_ntoa(*(struct in_addr *)&iphdr->daddr), + ether_ntoa_long((struct ether_addr *)(((char *)udphdr) + sizeof(struct udphdr) + 28)), + (size_t)buff_len - (iphdr->ihl * 4) - sizeof(struct udphdr)); + break; + case 68: + printf("%s.68: BOOTP/DHCP, Reply, length %zu\n", + inet_ntoa(*(struct in_addr *)&iphdr->daddr), + (size_t)buff_len - (iphdr->ihl * 4) - sizeof(struct udphdr)); + break; + default: + printf("%s.%i: UDP, length %zu\n", + inet_ntoa(*(struct in_addr *)&iphdr->daddr), ntohs(udphdr->dest), + (size_t)buff_len - (iphdr->ihl * 4) - sizeof(struct udphdr)); + break; + } + + break; + case IPPROTO_IPV6: + printf("IP6: not implemented yet\n"); + break; + default: + printf("IP unknown protocol: %i\n", iphdr->protocol); + break; + } +} + +void dump_batman_ogm(unsigned char *packet_buff, ssize_t buff_len, int read_opt) +{ + struct ether_header *ether_header; + struct batman_packet *batman_packet; + + LEN_CHECK((size_t)buff_len - sizeof(struct ether_header), sizeof(struct batman_packet), "BAT OGM"); + + ether_header = (struct ether_header *)packet_buff; + batman_packet = (struct batman_packet *)(packet_buff + sizeof(struct ether_header)); + + print_time(); + + printf("BAT %s: ", + get_name_by_macaddr((struct ether_addr *)batman_packet->orig, read_opt)); + + printf("OGM via neigh %s, seqno %d, tq %3d, ttl %2d, v %d, flags [%c%c], length %zu\n", + get_name_by_macaddr((struct ether_addr *)ether_header->ether_shost, read_opt), + ntohs(batman_packet->seqno), batman_packet->tq, + batman_packet->ttl, batman_packet->version, + (batman_packet->flags & VIS_SERVER ? 'V' : '.'), + (batman_packet->flags & DIRECTLINK ? 'D' : '.'), + (size_t)buff_len - sizeof(struct ether_header)); +} + +void dump_batman_icmp(unsigned char *packet_buff, ssize_t buff_len, int read_opt) +{ + struct ether_header *ether_header; + struct icmp_packet *icmp_packet; + char *name; + + LEN_CHECK((size_t)buff_len - sizeof(struct ether_header), sizeof(struct icmp_packet), "BAT ICMP"); + + ether_header = (struct ether_header *)packet_buff; + icmp_packet = (struct icmp_packet *)(packet_buff + sizeof(struct ether_header)); + + print_time(); + + printf("BAT %s > ", get_name_by_macaddr((struct ether_addr *)icmp_packet->orig, read_opt)); + + name = get_name_by_macaddr((struct ether_addr *)icmp_packet->dst, read_opt); + + switch (icmp_packet->msg_type) { + case ECHO_REPLY: + printf("%s: ICMP echo reply, id %hhu, seq %hu, ttl %2d, v %d, length %zu\n", + name, icmp_packet->uid, ntohs(icmp_packet->seqno), + icmp_packet->ttl, icmp_packet->version, + (size_t)buff_len - sizeof(struct ether_header)); + break; + case ECHO_REQUEST: + printf("%s: ICMP echo request, id %hhu, seq %hu, ttl %2d, v %d, length %zu\n", + name, icmp_packet->uid, ntohs(icmp_packet->seqno), + icmp_packet->ttl, icmp_packet->version, + (size_t)buff_len - sizeof(struct ether_header)); + break; + case TTL_EXCEEDED: + printf("%s: ICMP time exceeded in-transit, id %hhu, seq %hu, ttl %2d, v %d, length %zu\n", + name, icmp_packet->uid, ntohs(icmp_packet->seqno), + icmp_packet->ttl, icmp_packet->version, + (size_t)buff_len - sizeof(struct ether_header)); + break; + default: + printf("%s: ICMP type %hhu, length %zu\n", + name, icmp_packet->msg_type, (size_t)buff_len - sizeof(struct ether_header)); + break; + } +} + +void dump_batman_ucast(unsigned char *packet_buff, ssize_t buff_len, int read_opt) +{ + struct ether_header *ether_header; + struct unicast_packet *unicast_packet; + + LEN_CHECK((size_t)buff_len - sizeof(struct ether_header), sizeof(struct unicast_packet), "BAT UCAST"); + LEN_CHECK((size_t)buff_len - sizeof(struct ether_header) - sizeof(struct unicast_packet), + sizeof(struct ether_header), "BAT UCAST (unpacked)"); + + ether_header = (struct ether_header *)packet_buff; + unicast_packet = (struct unicast_packet *)(packet_buff + sizeof(struct ether_header)); + + print_time(); + + printf("BAT %s > ", + get_name_by_macaddr((struct ether_addr *)ether_header->ether_shost, read_opt)); + + printf("%s: UCAST, ttl %hu, ", + 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; + default: + printf(" unknown payload ether type: %hu\n", ntohs(ether_header->ether_type)); + break; + } +} + +void dump_batman_bcast(unsigned char *packet_buff, ssize_t buff_len, int read_opt) +{ + struct ether_header *ether_header; + struct bcast_packet *bcast_packet; + + LEN_CHECK((size_t)buff_len - sizeof(struct ether_header), sizeof(struct bcast_packet), "BAT BCAST"); + LEN_CHECK((size_t)buff_len - sizeof(struct ether_header) - sizeof(struct bcast_packet), + sizeof(struct ether_header), "BAT BCAST (unpacked)"); + + ether_header = (struct ether_header *)packet_buff; + bcast_packet = (struct bcast_packet *)(packet_buff + sizeof(struct ether_header)); + + print_time(); + + printf("BAT %s: ", + get_name_by_macaddr((struct ether_addr *)ether_header->ether_shost, read_opt)); + + printf("BCAST, orig %s, seqno %hu, ", + get_name_by_macaddr((struct ether_addr *)bcast_packet->orig, read_opt), + ntohs(bcast_packet->seqno)); + + ether_header = (struct ether_header *)(packet_buff + sizeof(struct ether_header) + sizeof(struct bcast_packet)); + + switch (ntohs(ether_header->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); + 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); + break; + default: + printf(" unknown payload ether type: %hu\n", ntohs(ether_header->ether_type)); + break; + } +} + +int tcpdump(int argc, char **argv) +{ + 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 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) { + switch (optchar) { + case 'h': + tcpdump_usage(); + return EXIT_SUCCESS; + case 'n': + read_opt &= ~USE_BAT_HOSTS; + found_args += 1; + break; + case 'p': + tmp = strtol(optarg, NULL , 10); + if ((tmp > 0) && (tmp <= dump_level)) + dump_level = tmp; + found_args += ((*((char*)(optarg - 1)) == optchar ) ? 1 : 2); + break; + default: + tcpdump_usage(); + return EXIT_FAILURE; + } + } + + if (argc <= found_args) { + printf("Error - target interface not specified\n"); + tcpdump_usage(); + return EXIT_FAILURE; + } + + bat_hosts_init(); + + /* init interfaces list */ + INIT_LIST_HEAD_FIRST(dump_if_list); + FD_ZERO(&wait_sockets); + + while (argc > found_args) { + + dump_if = malloc(sizeof(struct dump_if)); + memset(dump_if, 0, sizeof(struct dump_if)); + INIT_LIST_HEAD(&dump_if->list); + + dump_if->dev = argv[found_args]; + + if (strlen(dump_if->dev) > IFNAMSIZ - 1) { + printf("Error - interface name too long: %s\n", dump_if->dev); + goto out; + } + + dump_if->raw_sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); + + if (dump_if->raw_sock < 0) { + printf("Error - can't create raw socket: %s\n", strerror(errno)); + goto out; + } + + memset(&req, 0, sizeof (struct ifreq)); + strncpy(req.ifr_name, dump_if->dev, IFNAMSIZ); + + res = ioctl(dump_if->raw_sock, SIOCGIFINDEX, &req); + + if (res < 0) { + printf("Error - can't create raw socket (SIOCGIFINDEX): %s\n", strerror(errno)); + close(dump_if->raw_sock); + goto out; + } + + dump_if->addr.sll_family = AF_PACKET; + dump_if->addr.sll_protocol = htons(ETH_P_ALL); + dump_if->addr.sll_ifindex = req.ifr_ifindex; + + res = bind(dump_if->raw_sock, (struct sockaddr *)&dump_if->addr, sizeof(struct sockaddr_ll)); + + if (res < 0) { + printf("Error - can't bind raw socket: %s\n", strerror(errno)); + close(dump_if->raw_sock); + goto out; + } + + if (dump_if->raw_sock > max_sock) + max_sock = dump_if->raw_sock; + + FD_SET(dump_if->raw_sock, &wait_sockets); + list_add_tail(&dump_if->list, &dump_if_list); + found_args++; + } + + while (1) { + + memcpy(&tmp_wait_sockets, &wait_sockets, sizeof(fd_set)); + + tv.tv_sec = 1; + tv.tv_usec = 0; + + res = select(max_sock + 1, &tmp_wait_sockets, NULL, NULL, &tv); + + if (res == 0) + continue; + + if (res < 0) { + printf("Error - can't select on raw socket: %s\n", strerror(errno)); + continue; + } + + list_for_each_entry(dump_if, &dump_if_list, list) { + if (!FD_ISSET(dump_if->raw_sock, &tmp_wait_sockets)) + continue; + + read_len = read(dump_if->raw_sock, packet_buff, sizeof(packet_buff)); + + if (read_len < 0) { + printf("Error - can't read from interface '%s': %s\n", dump_if->dev, strerror(errno)); + continue; + } + + if ((size_t)read_len < sizeof(struct ether_header)) { + printf("Warning - dropping received packet as it is smaller than expected (%zu): %zd\n", + sizeof(struct ether_header), read_len); + 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_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: %hu\n", ether_type); + break; + } + + fflush(stdout); + } + + } + +out: + list_for_each_entry_safe(dump_if, dump_if_tmp, &dump_if_list, list) { + if (dump_if->raw_sock) + close(dump_if->raw_sock); + + list_del((struct list_head *)&dump_if_list, &dump_if->list, &dump_if_list); + free(dump_if); + } + + bat_hosts_free(); + return ret; +}
Property changes on: tags/batctl-0.2/tcpdump.c ___________________________________________________________________ Added: svn:mergeinfo +
Deleted: tags/batctl-0.2/traceroute.c =================================================================== --- tags/batctl-0.2/traceroute.c 2009-11-08 13:58:57 UTC (rev 1478) +++ tags/batctl-0.2/traceroute.c 2009-11-08 14:05:47 UTC (rev 1479) @@ -1,213 +0,0 @@ -/* - * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: - * - * Andreas Langer a.langer@q-dsl.de, Marek Lindner lindner_marek@yahoo.de - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - - - -#include <netinet/in.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <string.h> - -#include "main.h" -#include "traceroute.h" -#include "functions.h" -#include "packet.h" -#include "bat-hosts.h" - - -#define TTL_MAX 50 - - -void traceroute_usage(void) -{ - printf("Usage: batctl traceroute [options] mac|bat-host \n"); - printf("options:\n"); - printf(" \t -h print this help\n"); - printf(" \t -n don't convert addresses to bat-host names\n"); -} - -int traceroute(int argc, char **argv) -{ - struct icmp_packet icmp_packet_out, icmp_packet_in; - struct bat_host *bat_host; - struct ether_addr *dst_mac = NULL; - struct timeval tv; - fd_set read_socket; - ssize_t read_len; - char *dst_string, *mac_string, *return_mac, dst_reached = 0; - int ret = EXIT_FAILURE, res, trace_fd = 0, i; - int found_args = 1, optchar, seq_counter = 0, read_opt = USE_BAT_HOSTS; - double time_delta; - - while ((optchar = getopt(argc, argv, "hn")) != -1) { - switch (optchar) { - case 'h': - traceroute_usage(); - return EXIT_SUCCESS; - case 'n': - read_opt &= ~USE_BAT_HOSTS; - found_args += 1; - break; - default: - traceroute_usage(); - return EXIT_FAILURE; - } - } - - if (argc <= found_args) { - printf("Error - target mac address or bat-host name not specified\n"); - traceroute_usage(); - return EXIT_FAILURE; - } - - dst_string = argv[found_args]; - bat_hosts_init(); - bat_host = bat_hosts_find_by_name(dst_string); - - if (bat_host) - dst_mac = &bat_host->mac_addr; - - if (!dst_mac) { - dst_mac = ether_aton(dst_string); - - if (!dst_mac) { - printf("Error - the traceroute destination is not a mac address or bat-host name: %s\n", dst_string); - goto out; - } - } - - mac_string = ether_ntoa_long(dst_mac); - - trace_fd = open(BAT_DEVICE, O_RDWR); - - if (trace_fd < 0) { - printf("Error - can't open a connection to the batman adv kernel module via the device '%s': %s\n", - BAT_DEVICE, strerror(errno)); - printf("Check whether the module is loaded and active.\n"); - goto out; - } - - memcpy(&icmp_packet_out.dst, dst_mac, ETH_ALEN); - icmp_packet_out.version = COMPAT_VERSION; - icmp_packet_out.packet_type = BAT_ICMP; - icmp_packet_out.msg_type = ECHO_REQUEST; - icmp_packet_out.seqno = 0; - - printf("traceroute to %s (%s), %d hops max, %zd byte packets\n", - dst_string, mac_string, TTL_MAX, sizeof(icmp_packet_out)); - - for (icmp_packet_out.ttl = 1; !dst_reached && icmp_packet_out.ttl < TTL_MAX; icmp_packet_out.ttl++) { - - for (i = 0; i < 3; i++) { - icmp_packet_out.seqno = htons(++seq_counter); - - if (write(trace_fd, (char *)&icmp_packet_out, sizeof(icmp_packet_out)) < 0) { - printf("Error - can't write to batman adv kernel file '%s': %s\n", BAT_DEVICE, strerror(errno)); - continue; - } - - start_timer(); - - tv.tv_sec = 2; - tv.tv_usec = 0; - - FD_ZERO(&read_socket); - FD_SET(trace_fd, &read_socket); - - res = select(trace_fd + 1, &read_socket, NULL, NULL, &tv); - - if (res <= 0) { - if (i == 0) - printf("%2u: ", icmp_packet_out.ttl); - - printf(" * "); - fflush(stdout); - continue; - } - - read_len = read(trace_fd, (char *)&icmp_packet_in, sizeof(icmp_packet_in)); - - if (read_len < 0) { - printf("Error - can't read from batman adv kernel file '%s': %s\n", BAT_DEVICE, strerror(errno)); - continue; - } - - if ((size_t)read_len < sizeof(icmp_packet_in)) { - printf("Warning - dropping received packet as it is smaller than expected (%zd): %zd\n", - sizeof(icmp_packet_in), read_len); - continue; - } - - switch (icmp_packet_in.msg_type) { - case ECHO_REPLY: - case TTL_EXCEEDED: - time_delta = end_timer(); - - if (i > 0) { - printf(" %.3f ms", time_delta); - break; - } - - return_mac = ether_ntoa_long((struct ether_addr *)&icmp_packet_in.orig); - - bat_host = NULL; - if (read_opt & USE_BAT_HOSTS) - bat_host = bat_hosts_find_by_mac((char *)&icmp_packet_in.orig); - - if (!bat_host) - printf("%2u: %s %.3f ms", - icmp_packet_out.ttl, return_mac, time_delta); - else - printf("%2u: %s (%s) %.3f ms", - icmp_packet_out.ttl, bat_host->name, return_mac, time_delta); - - if (icmp_packet_in.msg_type == ECHO_REPLY) - dst_reached = 1; - - break; - case DESTINATION_UNREACHABLE: - printf("%s: Destination Host Unreachable\n", dst_string); - break; - case PARAMETER_PROBLEM: - printf("Error - the batman adv kernel module version (%d) differs from ours (%d)\n", - icmp_packet_in.ttl, COMPAT_VERSION); - printf("Please make sure to compatible versions!\n"); - goto out; - default: - printf("Unknown message type %d len %zd received\n", icmp_packet_in.msg_type, read_len); - break; - } - } - - printf("\n"); - } - - ret = EXIT_SUCCESS; - -out: - bat_hosts_free(); - if (trace_fd) - close(trace_fd); - return ret; -}
Copied: tags/batctl-0.2/traceroute.c (from rev 1478, trunk/batctl/traceroute.c) =================================================================== --- tags/batctl-0.2/traceroute.c (rev 0) +++ tags/batctl-0.2/traceroute.c 2009-11-08 14:05:47 UTC (rev 1479) @@ -0,0 +1,213 @@ +/* + * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * + * Andreas Langer a.langer@q-dsl.de, Marek Lindner lindner_marek@yahoo.de + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + + + +#include <netinet/in.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <string.h> + +#include "main.h" +#include "traceroute.h" +#include "functions.h" +#include "packet.h" +#include "bat-hosts.h" + + +#define TTL_MAX 50 + + +void traceroute_usage(void) +{ + printf("Usage: batctl traceroute [options] mac|bat-host \n"); + printf("options:\n"); + printf(" \t -h print this help\n"); + printf(" \t -n don't convert addresses to bat-host names\n"); +} + +int traceroute(int argc, char **argv) +{ + struct icmp_packet icmp_packet_out, icmp_packet_in; + struct bat_host *bat_host; + struct ether_addr *dst_mac = NULL; + struct timeval tv; + fd_set read_socket; + ssize_t read_len; + char *dst_string, *mac_string, *return_mac, dst_reached = 0; + int ret = EXIT_FAILURE, res, trace_fd = 0, i; + int found_args = 1, optchar, seq_counter = 0, read_opt = USE_BAT_HOSTS; + double time_delta; + + while ((optchar = getopt(argc, argv, "hn")) != -1) { + switch (optchar) { + case 'h': + traceroute_usage(); + return EXIT_SUCCESS; + case 'n': + read_opt &= ~USE_BAT_HOSTS; + found_args += 1; + break; + default: + traceroute_usage(); + return EXIT_FAILURE; + } + } + + if (argc <= found_args) { + printf("Error - target mac address or bat-host name not specified\n"); + traceroute_usage(); + return EXIT_FAILURE; + } + + dst_string = argv[found_args]; + bat_hosts_init(); + bat_host = bat_hosts_find_by_name(dst_string); + + if (bat_host) + dst_mac = &bat_host->mac_addr; + + if (!dst_mac) { + dst_mac = ether_aton(dst_string); + + if (!dst_mac) { + printf("Error - the traceroute destination is not a mac address or bat-host name: %s\n", dst_string); + goto out; + } + } + + mac_string = ether_ntoa_long(dst_mac); + + trace_fd = open(BAT_DEVICE, O_RDWR); + + if (trace_fd < 0) { + printf("Error - can't open a connection to the batman adv kernel module via the device '%s': %s\n", + BAT_DEVICE, strerror(errno)); + printf("Check whether the module is loaded and active.\n"); + goto out; + } + + memcpy(&icmp_packet_out.dst, dst_mac, ETH_ALEN); + icmp_packet_out.version = COMPAT_VERSION; + icmp_packet_out.packet_type = BAT_ICMP; + icmp_packet_out.msg_type = ECHO_REQUEST; + icmp_packet_out.seqno = 0; + + printf("traceroute to %s (%s), %d hops max, %zu byte packets\n", + dst_string, mac_string, TTL_MAX, sizeof(icmp_packet_out)); + + for (icmp_packet_out.ttl = 1; !dst_reached && icmp_packet_out.ttl < TTL_MAX; icmp_packet_out.ttl++) { + + for (i = 0; i < 3; i++) { + icmp_packet_out.seqno = htons(++seq_counter); + + if (write(trace_fd, (char *)&icmp_packet_out, sizeof(icmp_packet_out)) < 0) { + printf("Error - can't write to batman adv kernel file '%s': %s\n", BAT_DEVICE, strerror(errno)); + continue; + } + + start_timer(); + + tv.tv_sec = 2; + tv.tv_usec = 0; + + FD_ZERO(&read_socket); + FD_SET(trace_fd, &read_socket); + + res = select(trace_fd + 1, &read_socket, NULL, NULL, &tv); + + if (res <= 0) { + if (i == 0) + printf("%2hu: ", icmp_packet_out.ttl); + + printf(" * "); + fflush(stdout); + continue; + } + + read_len = read(trace_fd, (char *)&icmp_packet_in, sizeof(icmp_packet_in)); + + if (read_len < 0) { + printf("Error - can't read from batman adv kernel file '%s': %s\n", BAT_DEVICE, strerror(errno)); + continue; + } + + if ((size_t)read_len < sizeof(icmp_packet_in)) { + printf("Warning - dropping received packet as it is smaller than expected (%zu): %zd\n", + sizeof(icmp_packet_in), read_len); + continue; + } + + switch (icmp_packet_in.msg_type) { + case ECHO_REPLY: + case TTL_EXCEEDED: + time_delta = end_timer(); + + if (i > 0) { + printf(" %.3f ms", time_delta); + break; + } + + return_mac = ether_ntoa_long((struct ether_addr *)&icmp_packet_in.orig); + + bat_host = NULL; + if (read_opt & USE_BAT_HOSTS) + bat_host = bat_hosts_find_by_mac((char *)&icmp_packet_in.orig); + + if (!bat_host) + printf("%2hu: %s %.3f ms", + icmp_packet_out.ttl, return_mac, time_delta); + else + printf("%2hu: %s (%s) %.3f ms", + icmp_packet_out.ttl, bat_host->name, return_mac, time_delta); + + if (icmp_packet_in.msg_type == ECHO_REPLY) + dst_reached = 1; + + break; + case DESTINATION_UNREACHABLE: + printf("%s: Destination Host Unreachable\n", dst_string); + break; + case PARAMETER_PROBLEM: + printf("Error - the batman adv kernel module version (%d) differs from ours (%d)\n", + icmp_packet_in.ttl, COMPAT_VERSION); + printf("Please make sure to compatible versions!\n"); + goto out; + default: + printf("Unknown message type %d len %zd received\n", icmp_packet_in.msg_type, read_len); + break; + } + } + + printf("\n"); + } + + ret = EXIT_SUCCESS; + +out: + bat_hosts_free(); + if (trace_fd) + close(trace_fd); + return ret; +}
Property changes on: tags/batctl-0.2/traceroute.c ___________________________________________________________________ Added: svn:mergeinfo +