diff options
author | Guy Harris <gharris@steve.local> | 2009-06-28 12:16:43 -0700 |
---|---|---|
committer | Guy Harris <gharris@steve.local> | 2009-06-28 12:16:43 -0700 |
commit | 429c8b46eeabf29e9bac4b5e9a6d3915e2721716 (patch) | |
tree | a1f915f4a49e62e37cee551db38cf46baebf8e1b /print-olsr.c | |
parent | 2ef070a02f972661a096b43bb5e4deb273fbf2d5 (diff) | |
download | tcpdump-429c8b46eeabf29e9bac4b5e9a6d3915e2721716.tar.gz |
Fix up length checking for the MID message to check before *each*
interface address, not just the *first* interface address.
For the name service message:
add length checking, both against truncated packets and bogus
lengths;
use fn_printn to print the name, to protect against control
characters, etc. in the name.
Diffstat (limited to 'print-olsr.c')
-rw-r--r-- | print-olsr.c | 52 |
1 files changed, 32 insertions, 20 deletions
diff --git a/print-olsr.c b/print-olsr.c index 895c9f37..ba0ed2be 100644 --- a/print-olsr.c +++ b/print-olsr.c @@ -262,6 +262,7 @@ olsr_print (const u_char *pptr, u_int length, int is_ipv6) u_int msg_type, msg_len, msg_tlen, hello_len; u_int16_t name_entry_type, name_entry_len; + u_int name_entry_padding; u_int8_t link_type, neighbor_type; const u_char *tptr, *msg_data; @@ -452,10 +453,10 @@ olsr_print (const u_char *pptr, u_int length, int is_ipv6) addr_size = sizeof(struct in6_addr); #endif - if (!TTEST2(*msg_data, addr_size)) - goto trunc; - while (msg_tlen >= addr_size) { + if (!TTEST2(*msg_data, addr_size)) + goto trunc; + printf("\n\t interface address %s", #if INET6 is_ipv6 ? ip6addr_string(msg_data) : @@ -532,6 +533,11 @@ olsr_print (const u_char *pptr, u_int length, int is_ipv6) && ((name_entries * (4 + addr_size)) <= msg_tlen)) name_entries_valid = 1; + if (msg_tlen < 4) + goto trunc; + if (!TTEST2(*msg_data, 4)) + goto trunc; + printf("\n\t Version %u, Entries %u%s", EXTRACT_16BITS(msg_data), name_entries, (name_entries_valid == 0) ? " (invalid)" : ""); @@ -547,6 +553,8 @@ olsr_print (const u_char *pptr, u_int length, int is_ipv6) if (msg_tlen < 4) break; + if (!TTEST2(*msg_data, 4)) + goto trunc; name_entry_type = EXTRACT_16BITS(msg_data); name_entry_len = EXTRACT_16BITS(msg_data+2); @@ -564,26 +572,30 @@ olsr_print (const u_char *pptr, u_int length, int is_ipv6) if (name_entry_len_valid == 0) break; - { - char name[name_entry_len + 1]; - memcpy (name, msg_data + addr_size, name_entry_len); - name[name_entry_len] = 0; -#if INET6 - if (is_ipv6) - printf(", address %s, name \"%s\"", - ip6addr_string(msg_data), name); - else -#endif - printf(", address %s, name \"%s\"", - ipaddr_string(msg_data), name); - } - /* 32-bit alignment */ + name_entry_padding = 0; if (name_entry_len%4 != 0) - name_entry_len+=4-(name_entry_len%4); + name_entry_padding = 4-(name_entry_len%4); + + if (msg_tlen < addr_size + name_entry_len + name_entry_padding) + goto trunc; + + if (!TTEST2(*msg_data, addr_size + name_entry_len + name_entry_padding)) + goto trunc; + +#if INET6 + if (is_ipv6) + printf(", address %s, name \"", + ip6addr_string(msg_data)); + else +#endif + printf(", address %s, name \"", + ipaddr_string(msg_data)); + fn_printn(msg_data + addr_size, name_entry_len, NULL); + printf("\""); - msg_data += addr_size + name_entry_len; - msg_tlen -= addr_size + name_entry_len; + msg_data += addr_size + name_entry_len + name_entry_padding; + msg_tlen -= addr_size + name_entry_len + name_entry_padding; } /* for (i = 0; i < name_entries; i++) */ break; } /* case OLSR_NAMESERVICE_MSG */ |