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(a)q-dsl.de>, Marek Lindner <lindner_marek(a)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(a)q-dsl.de>, Marek Lindner <lindner_marek(a)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(a)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(a)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(a)q-dsl.de>, Marek Lindner <lindner_marek(a)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(a)q-dsl.de>, Marek Lindner <lindner_marek(a)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
+