Repository : ssh://git@open-mesh.org/batctl
On branch : next
commit 499d0a2b2b76a2646527f628e39ab1aab5c8b474 Author: Antonio Quartulli antonio@meshcoding.com Date: Thu Dec 5 15:33:00 2013 +0100
batctl: fix size of batadv_icmp_header
struct batadv_icmp_header currently has a size of 17, which will be padded to 20 on some architectures. Fix this by unrolling the header into the parent structures.
Moreover keep the ICMP parsing functions as generic as they are now by using a stub icmp_header struct during packet parsing.
Signed-off-by: Antonio Quartulli antonio@meshcoding.com Signed-off-by: Marek Lindner mareklindner@neomailbox.ch
499d0a2b2b76a2646527f628e39ab1aab5c8b474 packet.h | 40 +++++++++++++++++++++++++++++++++++----- ping.c | 18 +++++++++--------- tcpdump.c | 25 ++++++++++--------------- traceroute.c | 28 ++++++++++++++-------------- 4 files changed, 68 insertions(+), 43 deletions(-)
diff --git a/packet.h b/packet.h index 175ce7d..2a857ed 100644 --- a/packet.h +++ b/packet.h @@ -191,7 +191,7 @@ struct batadv_ogm_packet { #define BATADV_OGM_HLEN sizeof(struct batadv_ogm_packet)
/** - * batadv_icmp_header - common ICMP header + * batadv_icmp_header - common members among all the ICMP packets * @packet_type: batman-adv packet type, part of the general header * @version: batman-adv protocol version, part of the genereal header * @ttl: time to live for this packet, part of the genereal header @@ -199,6 +199,11 @@ struct batadv_ogm_packet { * @dst: address of the destination node * @orig: address of the source node * @uid: local ICMP socket identifier + * @align: not used - useful for alignment purposes only + * + * This structure is used for ICMP packets parsing only and it is never sent + * over the wire. The alignment field at the end is there to ensure that + * members are padded the same way as they are in real packets. */ struct batadv_icmp_header { uint8_t packet_type; @@ -208,16 +213,29 @@ struct batadv_icmp_header { uint8_t dst[ETH_ALEN]; uint8_t orig[ETH_ALEN]; uint8_t uid; + uint8_t align[3]; };
/** * batadv_icmp_packet - ICMP packet - * @icmph: common ICMP header + * @packet_type: batman-adv packet type, part of the general header + * @version: batman-adv protocol version, part of the genereal header + * @ttl: time to live for this packet, part of the genereal header + * @msg_type: ICMP packet type + * @dst: address of the destination node + * @orig: address of the source node + * @uid: local ICMP socket identifier * @reserved: not used - useful for alignment * @seqno: ICMP sequence number */ struct batadv_icmp_packet { - struct batadv_icmp_header icmph; + uint8_t packet_type; + uint8_t version; + uint8_t ttl; + uint8_t msg_type; /* see ICMP message types above */ + uint8_t dst[ETH_ALEN]; + uint8_t orig[ETH_ALEN]; + uint8_t uid; uint8_t reserved; __be16 seqno; }; @@ -226,13 +244,25 @@ struct batadv_icmp_packet {
/** * batadv_icmp_packet_rr - ICMP RouteRecord packet - * @icmph: common ICMP header + * @packet_type: batman-adv packet type, part of the general header + * @version: batman-adv protocol version, part of the genereal header + * @ttl: time to live for this packet, part of the genereal header + * @msg_type: ICMP packet type + * @dst: address of the destination node + * @orig: address of the source node + * @uid: local ICMP socket identifier * @rr_cur: number of entries the rr array * @seqno: ICMP sequence number * @rr: route record array */ struct batadv_icmp_packet_rr { - struct batadv_icmp_header icmph; + uint8_t packet_type; + uint8_t version; + uint8_t ttl; + uint8_t msg_type; /* see ICMP message types above */ + uint8_t dst[ETH_ALEN]; + uint8_t orig[ETH_ALEN]; + uint8_t uid; uint8_t rr_cur; __be16 seqno; uint8_t rr[BATADV_RR_LEN][ETH_ALEN]; diff --git a/ping.c b/ping.c index 778e8ae..bce8ea2 100644 --- a/ping.c +++ b/ping.c @@ -176,11 +176,11 @@ int ping(char *mesh_iface, int argc, char **argv)
packet_len = sizeof(struct batadv_icmp_packet);
- memcpy(&icmp_packet_out.icmph.dst, dst_mac, ETH_ALEN); - icmp_packet_out.icmph.packet_type = BATADV_ICMP; - icmp_packet_out.icmph.version = BATADV_COMPAT_VERSION; - icmp_packet_out.icmph.msg_type = BATADV_ECHO_REQUEST; - icmp_packet_out.icmph.ttl = 50; + memcpy(&icmp_packet_out.dst, dst_mac, ETH_ALEN); + icmp_packet_out.packet_type = BATADV_ICMP; + icmp_packet_out.version = BATADV_COMPAT_VERSION; + icmp_packet_out.msg_type = BATADV_ECHO_REQUEST; + icmp_packet_out.ttl = 50; icmp_packet_out.seqno = 0;
if (rr) { @@ -250,13 +250,13 @@ read_packet: if (htons(seq_counter) != icmp_packet_in.seqno) goto read_packet;
- switch (icmp_packet_in.icmph.msg_type) { + switch (icmp_packet_in.msg_type) { case BATADV_ECHO_REPLY: time_delta = end_timer(); printf("%zd bytes from %s icmp_seq=%hu ttl=%d time=%.2f ms", read_len, dst_string, ntohs(icmp_packet_in.seqno), - icmp_packet_in.icmph.ttl, + icmp_packet_in.ttl, time_delta);
if (read_len == sizeof(struct batadv_icmp_packet_rr)) { @@ -306,12 +306,12 @@ read_packet: break; case BATADV_PARAMETER_PROBLEM: fprintf(stderr, "Error - the batman adv kernel module version (%d) differs from ours (%d)\n", - icmp_packet_in.icmph.version, BATADV_COMPAT_VERSION); + icmp_packet_in.version, BATADV_COMPAT_VERSION); printf("Please make sure to use compatible versions!\n"); goto out; default: printf("Unknown message type %d len %zd received\n", - icmp_packet_in.icmph.msg_type, read_len); + icmp_packet_in.msg_type, read_len); break; }
diff --git a/tcpdump.c b/tcpdump.c index b2376fd..3c9ece5 100644 --- a/tcpdump.c +++ b/tcpdump.c @@ -369,37 +369,32 @@ static void dump_batman_icmp(unsigned char *packet_buff, ssize_t buff_len, int r print_time();
printf("BAT %s > ", - get_name_by_macaddr((struct ether_addr *)icmp_packet->icmph.orig, - read_opt)); + get_name_by_macaddr((struct ether_addr *)icmp_packet->orig, read_opt));
- name = get_name_by_macaddr((struct ether_addr *)icmp_packet->icmph.dst, - read_opt); + name = get_name_by_macaddr((struct ether_addr *)icmp_packet->dst, read_opt);
- switch (icmp_packet->icmph.msg_type) { + switch (icmp_packet->msg_type) { case BATADV_ECHO_REPLY: printf("%s: ICMP echo reply, id %hhu, seq %hu, ttl %2d, v %d, length %zu\n", - name, icmp_packet->icmph.uid, ntohs(icmp_packet->seqno), - icmp_packet->icmph.ttl, - icmp_packet->icmph.version, + name, icmp_packet->uid, ntohs(icmp_packet->seqno), + icmp_packet->ttl, icmp_packet->version, (size_t)buff_len - sizeof(struct ether_header)); break; case BATADV_ECHO_REQUEST: printf("%s: ICMP echo request, id %hhu, seq %hu, ttl %2d, v %d, length %zu\n", - name, icmp_packet->icmph.uid, ntohs(icmp_packet->seqno), - icmp_packet->icmph.ttl, - icmp_packet->icmph.version, + name, icmp_packet->uid, ntohs(icmp_packet->seqno), + icmp_packet->ttl, icmp_packet->version, (size_t)buff_len - sizeof(struct ether_header)); break; case BATADV_TTL_EXCEEDED: printf("%s: ICMP time exceeded in-transit, id %hhu, seq %hu, ttl %2d, v %d, length %zu\n", - name, icmp_packet->icmph.uid, ntohs(icmp_packet->seqno), - icmp_packet->icmph.ttl, - icmp_packet->icmph.version, + 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->icmph.msg_type, + name, icmp_packet->msg_type, (size_t)buff_len - sizeof(struct ether_header)); break; } diff --git a/traceroute.c b/traceroute.c index 7b0a826..fccd80c 100644 --- a/traceroute.c +++ b/traceroute.c @@ -133,19 +133,19 @@ int traceroute(char *mesh_iface, int argc, char **argv) goto out; }
- memcpy(&icmp_packet_out.icmph.dst, dst_mac, ETH_ALEN); - icmp_packet_out.icmph.version = BATADV_COMPAT_VERSION; - icmp_packet_out.icmph.packet_type = BATADV_ICMP; - icmp_packet_out.icmph.msg_type = BATADV_ECHO_REQUEST; + memcpy(&icmp_packet_out.dst, dst_mac, ETH_ALEN); + icmp_packet_out.version = BATADV_COMPAT_VERSION; + icmp_packet_out.packet_type = BATADV_ICMP; + icmp_packet_out.msg_type = BATADV_ECHO_REQUEST; icmp_packet_out.seqno = 0; icmp_packet_out.reserved = 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.icmph.ttl = 1; - !dst_reached && icmp_packet_out.icmph.ttl < TTL_MAX; - icmp_packet_out.icmph.ttl++) { + for (icmp_packet_out.ttl = 1; + !dst_reached && icmp_packet_out.ttl < TTL_MAX; + icmp_packet_out.ttl++) { return_mac = NULL; bat_host = NULL;
@@ -189,7 +189,7 @@ read_packet: if (htons(seq_counter) != icmp_packet_in.seqno) goto read_packet;
- switch (icmp_packet_in.icmph.msg_type) { + switch (icmp_packet_in.msg_type) { case BATADV_ECHO_REPLY: dst_reached = 1; /* fall through */ @@ -197,10 +197,10 @@ read_packet: time_delta[i] = end_timer();
if (!return_mac) { - return_mac = ether_ntoa_long((struct ether_addr *)&icmp_packet_in.icmph.orig); + return_mac = ether_ntoa_long((struct ether_addr *)&icmp_packet_in.orig);
if (read_opt & USE_BAT_HOSTS) - bat_host = bat_hosts_find_by_mac((char *)&icmp_packet_in.icmph.orig); + bat_host = bat_hosts_find_by_mac((char *)&icmp_packet_in.orig); }
break; @@ -209,22 +209,22 @@ read_packet: goto out; case BATADV_PARAMETER_PROBLEM: fprintf(stderr, "Error - the batman adv kernel module version (%d) differs from ours (%d)\n", - icmp_packet_in.icmph.version, BATADV_COMPAT_VERSION); + icmp_packet_in.version, BATADV_COMPAT_VERSION); fprintf(stderr, "Please make sure to use compatible versions!\n"); goto out; default: printf("Unknown message type %d len %zd received\n", - icmp_packet_in.icmph.msg_type, read_len); + icmp_packet_in.msg_type, read_len); break; } }
if (!bat_host) - printf("%2hhu: %s", icmp_packet_out.icmph.ttl, + printf("%2hhu: %s", icmp_packet_out.ttl, (return_mac ? return_mac : "*")); else printf("%2hhu: %s (%s)", - icmp_packet_out.icmph.ttl, + icmp_packet_out.ttl, bat_host->name, return_mac);
for (i = 0; i < NUM_PACKETS; i++) {