diff options
-rw-r--r-- | usr.sbin/tcpdump/interface.h | 6 | ||||
-rw-r--r-- | usr.sbin/tcpdump/print-dhcp6.c | 426 | ||||
-rw-r--r-- | usr.sbin/tcpdump/print-udp.c | 7 |
3 files changed, 159 insertions, 280 deletions
diff --git a/usr.sbin/tcpdump/interface.h b/usr.sbin/tcpdump/interface.h index 81f669b1701..f7a55d0492f 100644 --- a/usr.sbin/tcpdump/interface.h +++ b/usr.sbin/tcpdump/interface.h @@ -1,4 +1,4 @@ -/* $OpenBSD: interface.h,v 1.81 2019/05/26 22:42:42 dlg Exp $ */ +/* $OpenBSD: interface.h,v 1.82 2019/12/02 22:07:20 dlg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 @@ -20,7 +20,7 @@ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * @(#) $Id: interface.h,v 1.81 2019/05/26 22:42:42 dlg Exp $ (LBL) + * @(#) $Id: interface.h,v 1.82 2019/12/02 22:07:20 dlg Exp $ (LBL) */ #ifndef tcpdump_interface_h @@ -296,7 +296,7 @@ extern void icmp6_print(const u_char *, u_int, const u_char *); extern void ripng_print(const u_char *, int); extern int rt6_print(const u_char *, const u_char *); extern void ospf6_print(const u_char *, u_int); -extern void dhcp6_print(const u_char *, u_int, u_short, u_short); +extern void dhcp6_print(const u_char *, u_int); extern uint32_t in_cksum_add(const void *, size_t, uint32_t); extern uint16_t in_cksum_fini(uint32_t); diff --git a/usr.sbin/tcpdump/print-dhcp6.c b/usr.sbin/tcpdump/print-dhcp6.c index 95d24fa21c4..bb4e0aa20d4 100644 --- a/usr.sbin/tcpdump/print-dhcp6.c +++ b/usr.sbin/tcpdump/print-dhcp6.c @@ -1,32 +1,19 @@ -/* $OpenBSD: print-dhcp6.c,v 1.11 2018/10/22 16:12:45 kn Exp $ */ +/* $OpenBSD: print-dhcp6.c,v 1.12 2019/12/02 22:07:20 dlg Exp $ */ /* - * Copyright (C) 1998 and 1999 WIDE Project. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + * Copyright (c) 2019 David Gwynne <dlg@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include <sys/time.h> @@ -44,286 +31,179 @@ struct rtentry; #include <arpa/inet.h> #include "interface.h" +#include "extract.h" #include "addrtoname.h" -#include "dhcp6.h" -#include "dhcp6opt.h" - -#if 0 -static void dhcp6opttab_init(void); -static struct dhcp6_opt *dhcp6opttab_byname(char *); -#endif -static struct dhcp6_opt *dhcp6opttab_bycode(u_int); - -static char tstr[] = " [|dhcp6]"; - -static struct dhcp6_opt dh6opttab[] = { - /* IP Address Extension */ - { 1, OL6_N, "IP Address", OT6_NONE, }, - - /* General Extension */ - { 2, 4, "Time Offset", OT6_NUM, }, - { 3, OL6_N, "IEEE 1003.1 POSIX Timezone", OT6_STR, }, - { 6, OL6_16N, "Domain Name Server", OT6_V6, }, - { 10, OL6_N, "Domain Name", OT6_STR, }, - - /* Application and Service Parameters */ - { 16, OL6_N, "Directory Agent", OT6_NONE, }, - { 17, OL6_N, "Service Scope" , OT6_NONE, }, - { 18, OL6_16N, "Network Time Protocol Servers", OT6_V6, }, - { 19, OL6_N, "NIS Domain", OT6_STR, }, - { 20, OL6_16N, "NIS Servers", OT6_V6, }, - { 21, OL6_N, "NIS+ Domain", OT6_STR, }, - { 22, OL6_16N, "NIS+ Servers", OT6_V6, }, - - /* TCP Parameters */ - { 32, 4, "TCP Keepalive Interval", OT6_NUM, }, - - /* DHCPv6 Extensions */ - { 40, 4, "Maximum DHCPv6 Message Size", OT6_NUM, }, - { 41, OL6_N, "DHCP Retransmission and Configuration Parameter", - OT6_NONE, }, - { 48, OL6_N, "Platform Specific Information", OT6_NONE, }, - { 49, OL6_N, "Platform Class Identifier", OT6_STR, }, - { 64, OL6_N, "Class Identifier", OT6_STR, }, - { 66, 16, "Reconfigure Multicast Address", OT6_V6, }, - { 67, 16, "Renumber DHCPv6 Server Address", - OT6_V6, }, - { 68, OL6_N, "DHCP Relay ICMP Error Message", OT6_NONE, }, - { 84, OL6_N, "Client-Server Authentication", OT6_NONE, }, - { 85, 4, "Client Key Selection", OT6_NUM, }, - - /* End Extension */ - { 65536, OL6_Z, "End", OT6_NONE, }, - - { 0 }, -}; - -#if 0 -static struct dhcp6_opt *dh6o_pad; -static struct dhcp6_opt *dh6o_end; -static void -dhcp6opttab_init() -{ - dh6o_pad = dhcp6opttab_bycode(0); - dh6o_end = dhcp6opttab_bycode(65536); -} -#endif +/* Message type */ +#define DH6_SOLICIT 1 +#define DH6_ADVERTISE 2 +#define DH6_REQUEST 3 +#define DH6_CONFIRM 4 +#define DH6_RENEW 5 +#define DH6_REBIND 6 +#define DH6_REPLY 7 +#define DH6_RELEASE 8 +#define DH6_DECLINE 9 +#define DH6_RECONFIGURE 10 +#define DH6_INFORMATION_REQUEST 11 +#define DH6_RELAY_FORW 12 +#define DH6_RELAY_REPL 13 -#if 0 -static struct dhcp6_opt * -dhcp6opttab_byname(name) - char *name; +static void +dhcp6opt_print(const u_char *cp, u_int length) { - struct dhcp6_opt *p; + uint16_t code, len; + u_int i; + int l = snapend - cp; + + while (length > 0) { + if (l < sizeof(code)) + goto trunc; + if (length < sizeof(code)) + goto iptrunc; + + code = EXTRACT_16BITS(cp); + cp += sizeof(code); + length -= sizeof(code); + l -= sizeof(code); + + if (l < sizeof(len)) + goto trunc; + if (length < sizeof(len)) + goto iptrunc; + + len = EXTRACT_16BITS(cp); + cp += sizeof(len); + length -= sizeof(len); + l -= sizeof(len); + + printf("\n\toption %u len %u", code, len); + + if (len > 0) { + if (l < len) + goto trunc; + if (length < len) + goto iptrunc; - for (p = dh6opttab; p->code; p++) - if (strcmp(name, p->name) == 0) - return p; - return NULL; -} -#endif + printf(" "); + for (i = 0; i < len; i++) + printf("%02x", cp[4 + i] & 0xff); -static struct dhcp6_opt * -dhcp6opttab_bycode(code) - u_int code; -{ - struct dhcp6_opt *p; + cp += len; + length -= len; + l -= len; + } + } + return; - for (p = dh6opttab; p->code; p++) - if (p->code == code) - return p; - return NULL; +trunc: + printf(" [|dhcp6opt]"); + return; +iptrunc: + printf(" ip truncated"); } static void -dhcp6ext_print(u_char *cp, u_char *ep) +dhcp6_relay_print(const u_char *cp, u_int length) { - u_int16_t code, len; - struct dhcp6_opt *p; - char buf[BUFSIZ]; - int i; - - if (cp == ep) - return; - printf(" "); - while (cp < ep) { - code = ntohs(*(u_int16_t *)&cp[0]); - if (code != 65535) - len = ntohs(*(u_int16_t *)&cp[2]); - else - len = 0; - p = dhcp6opttab_bycode(code); - if (p == NULL) { - printf("(unknown, len=%d)", len); - cp += len + 4; - continue; - } + uint8_t msgtype; + const char *msgname = NULL; - /* sanity check on length */ - switch (p->len) { - case OL6_N: - break; - case OL6_16N: - if (len % 16 != 0) - goto trunc; - break; - case OL6_Z: - if (len != 0) - goto trunc; - break; - default: - if (len != p->len) - goto trunc; - break; - } - if (cp + 4 + len > ep) { - printf("[|%s]", p->name); - return; - } + msgtype = *cp; - printf("(%s, ", p->name); - switch (p->type) { - case OT6_V6: - for (i = 0; i < len; i += 16) { - inet_ntop(AF_INET6, &cp[4 + i], buf, - sizeof(buf)); - if (i != 0) - printf(","); - printf("%s", buf); - } - break; - case OT6_STR: - memset(&buf, 0, sizeof(buf)); - strlcpy(buf, &cp[4], len); - printf("%s", buf); - break; - case OT6_NUM: - printf("%d", (u_int32_t)ntohl(*(u_int32_t *)&cp[4])); - break; - default: - for (i = 0; i < len; i++) - printf("%02x", cp[4 + i] & 0xff); - } - printf(")"); - cp += len + 4; + switch (msgtype) { + case DH6_RELAY_FORW: + msgname = "Relay-forward"; + break; + case DH6_RELAY_REPL: + msgname = "Relay-reply"; + break; } - return; -trunc: - printf("[|dhcp6ext]"); + printf(" %s", msgname); } -/* - * Print dhcp6 requests - */ void -dhcp6_print(const u_char *cp, u_int length, - u_short sport, u_short dport) +dhcp6_print(const u_char *cp, u_int length) { - union dhcp6 *dh6; - u_char *ep; - u_char *extp; + uint8_t msgtype; + uint32_t hdr; + int l = snapend - cp; + const char *msgname; - printf("dhcp6"); + printf("DHCPv6"); - ep = (u_char *)snapend; + if (l < sizeof(msgtype)) + goto trunc; + if (length < sizeof(msgtype)) + goto iptrunc; - dh6 = (union dhcp6 *)cp; - TCHECK(dh6->dh6_msgtype); - switch (dh6->dh6_msgtype) { + msgtype = *cp; + + switch (msgtype) { case DH6_SOLICIT: - if (vflag && TTEST(dh6->dh6_sol.dh6sol_relayaddr)) { - printf(" solicit("); - if ((dh6->dh6_sol.dh6sol_flags & DH6SOL_CLOSE) != 0) - printf("C"); - if (dh6->dh6_sol.dh6sol_flags != 0) - printf(" "); - printf("cliaddr=%s", - ip6addr_string(&dh6->dh6_sol.dh6sol_cliaddr)); - printf(" relayaddr=%s", - ip6addr_string(&dh6->dh6_sol.dh6sol_relayaddr)); - printf(")"); - } else - printf(" solicit"); + msgname = "Solicit"; break; - case DH6_ADVERT: - if (!(vflag && TTEST(dh6->dh6_adv.dh6adv_serveraddr))) { - printf(" advert"); - break; - } - printf(" advert("); - if ((dh6->dh6_adv.dh6adv_flags & DH6ADV_SERVPRESENT) != 0) - printf("S"); - if (dh6->dh6_adv.dh6adv_flags != 0) - printf(" "); - printf("pref=%u", dh6->dh6_adv.dh6adv_pref); - printf(" cliaddr=%s", - ip6addr_string(&dh6->dh6_adv.dh6adv_cliaddr)); - printf(" relayaddr=%s", - ip6addr_string(&dh6->dh6_adv.dh6adv_relayaddr)); - printf(" servaddr=%s", - ip6addr_string(&dh6->dh6_adv.dh6adv_serveraddr)); - extp = (u_char *)((&dh6->dh6_adv) + 1); - dhcp6ext_print(extp, ep); - printf(")"); + case DH6_ADVERTISE: + msgname = "Advertise"; break; case DH6_REQUEST: - if (!(vflag && TTEST(dh6->dh6_req.dh6req_relayaddr))) { - printf(" request"); - break; - } - printf(" request("); - if ((dh6->dh6_req.dh6req_flags & DH6REQ_CLOSE) != 0) - printf("C"); - if ((dh6->dh6_req.dh6req_flags & DH6REQ_SERVPRESENT) != 0) - printf("S"); - if ((dh6->dh6_req.dh6req_flags & DH6REQ_REBOOT) != 0) - printf("R"); - if (dh6->dh6_req.dh6req_flags != 0) - printf(" "); - printf("xid=0x%04x", dh6->dh6_req.dh6req_xid); - printf(" cliaddr=%s", - ip6addr_string(&dh6->dh6_req.dh6req_cliaddr)); - printf(" relayaddr=%s", - ip6addr_string(&dh6->dh6_req.dh6req_relayaddr)); - extp = (char *)((&dh6->dh6_req) + 1); - if ((dh6->dh6_req.dh6req_flags & DH6REQ_SERVPRESENT) != 0) { - printf(" servaddr=%s", ip6addr_string(extp)); - extp += 16; - } - dhcp6ext_print(extp, ep); - printf(")"); + msgname = "Request"; + break; + case DH6_CONFIRM: + msgname = "Confirm"; + break; + case DH6_RENEW: + msgname = "Renew"; + break; + case DH6_REBIND: + msgname = "Rebind"; break; case DH6_REPLY: - if (!(vflag && TTEST(dh6->dh6_rep.dh6rep_xid))) { - printf(" reply"); - break; - } - printf(" reply("); - if ((dh6->dh6_rep.dh6rep_flagandstat & DH6REP_CLIPRESENT) != 0) - printf("C"); - if (dh6->dh6_rep.dh6rep_flagandstat != 0) - printf(" "); - printf("stat=0x%02x", - dh6->dh6_rep.dh6rep_flagandstat & DH6REP_STATMASK); - extp = (u_char *)((&dh6->dh6_rep) + 1); - if ((dh6->dh6_rep.dh6rep_flagandstat & DH6REP_CLIPRESENT) != 0) { - printf(" cliaddr=%s", ip6addr_string(extp)); - extp += 16; - } - dhcp6ext_print(extp, ep); - printf(")"); + msgname = "Reply"; break; case DH6_RELEASE: - printf(" release"); + msgname = "Release"; + break; + case DH6_DECLINE: + msgname = "Decline"; + break; + case DH6_RECONFIGURE: + msgname = "Reconfigure"; break; - case DH6_RECONFIG: - printf(" reconfig"); + case DH6_INFORMATION_REQUEST: + msgname = "Information-request"; break; + case DH6_RELAY_FORW: + case DH6_RELAY_REPL: + dhcp6_relay_print(cp, length); + return; + default: + printf(" unknown message type %u", msgtype); + return; + } + + printf(" %s", msgname); + + if (l < sizeof(hdr)) + goto trunc; + if (length < sizeof(hdr)) + goto iptrunc; + + hdr = EXTRACT_32BITS(cp); + printf(" xid %x", hdr & 0xffffff); + + if (vflag) { + cp += sizeof(hdr); + length -= sizeof(hdr); + + dhcp6opt_print(cp, length); } return; trunc: - printf("%s", tstr); + printf(" [|dhcp6]"); + return; +iptrunc: + printf(" ip truncated"); } diff --git a/usr.sbin/tcpdump/print-udp.c b/usr.sbin/tcpdump/print-udp.c index f27ff8959a7..bb2d4878a75 100644 --- a/usr.sbin/tcpdump/print-udp.c +++ b/usr.sbin/tcpdump/print-udp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: print-udp.c,v 1.51 2018/10/22 16:12:45 kn Exp $ */ +/* $OpenBSD: print-udp.c,v 1.52 2019/12/02 22:07:20 dlg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996 @@ -565,9 +565,8 @@ udp_print(const u_char *bp, u_int length, const void *iph) mpls_print(cp, length); else if (ISPORT(RIPNG_PORT)) ripng_print(cp, length); - else if (ISPORT(DHCP6_PORT1) || ISPORT(DHCP6_PORT2)) { - dhcp6_print(cp, length, sport, dport); - } + else if (ISPORT(DHCP6_PORT1) || ISPORT(DHCP6_PORT2)) + dhcp6_print(cp, length); else if (ISPORT(GTP_C_PORT) || ISPORT(GTP_U_PORT) || ISPORT(GTP_PRIME_PORT)) gtp_print(cp, length, sport, dport); |