1b0453382SBill Fenner /*
2b0453382SBill Fenner * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997
3b0453382SBill Fenner * The Regents of the University of California. All rights reserved.
4b0453382SBill Fenner *
5b0453382SBill Fenner * Redistribution and use in source and binary forms, with or without
6b0453382SBill Fenner * modification, are permitted provided that: (1) source code distributions
7b0453382SBill Fenner * retain the above copyright notice and this paragraph in its entirety, (2)
8b0453382SBill Fenner * distributions including binary code include the above copyright notice and
9b0453382SBill Fenner * this paragraph in its entirety in the documentation or other materials
10b0453382SBill Fenner * provided with the distribution, and (3) all advertising materials mentioning
11b0453382SBill Fenner * features or use of this software display the following acknowledgement:
12b0453382SBill Fenner * ``This product includes software developed by the University of California,
13b0453382SBill Fenner * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14b0453382SBill Fenner * the University nor the names of its contributors may be used to endorse
15b0453382SBill Fenner * or promote products derived from this software without specific prior
16b0453382SBill Fenner * written permission.
17b0453382SBill Fenner * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18b0453382SBill Fenner * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19b0453382SBill Fenner * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20b0453382SBill Fenner */
21b0453382SBill Fenner
223340d773SGleb Smirnoff /* \summary: Cisco HDLC printer */
233340d773SGleb Smirnoff
24*ee67461eSJoseph Mingrone #include <config.h>
25b0453382SBill Fenner
26*ee67461eSJoseph Mingrone #include "netdissect-stdinc.h"
27b0453382SBill Fenner
283340d773SGleb Smirnoff #include "netdissect.h"
29b0453382SBill Fenner #include "addrtoname.h"
30685295f4SBill Fenner #include "ethertype.h"
31a90e161bSBill Fenner #include "extract.h"
32685295f4SBill Fenner #include "chdlc.h"
33*ee67461eSJoseph Mingrone #include "nlpid.h"
34b0453382SBill Fenner
353c602fabSXin LI static void chdlc_slarp_print(netdissect_options *, const u_char *, u_int);
36b0453382SBill Fenner
373c602fabSXin LI static const struct tok chdlc_cast_values[] = {
38b5bfcb5dSMax Laier { CHDLC_UNICAST, "unicast" },
39b5bfcb5dSMax Laier { CHDLC_BCAST, "bcast" },
40b5bfcb5dSMax Laier { 0, NULL}
41b5bfcb5dSMax Laier };
42b5bfcb5dSMax Laier
43b5bfcb5dSMax Laier
44b0453382SBill Fenner /* Standard CHDLC printer */
45*ee67461eSJoseph Mingrone void
chdlc_if_print(netdissect_options * ndo,const struct pcap_pkthdr * h,const u_char * p)46*ee67461eSJoseph Mingrone chdlc_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p)
47b0453382SBill Fenner {
48*ee67461eSJoseph Mingrone ndo->ndo_protocol = "chdlc";
49*ee67461eSJoseph Mingrone ndo->ndo_ll_hdr_len += chdlc_print(ndo, p, h->len);
502ebc47dbSSam Leffler }
512ebc47dbSSam Leffler
522ebc47dbSSam Leffler u_int
chdlc_print(netdissect_options * ndo,const u_char * p,u_int length)53*ee67461eSJoseph Mingrone chdlc_print(netdissect_options *ndo, const u_char *p, u_int length)
548bdc5a62SPatrick Kelsey {
552ebc47dbSSam Leffler u_int proto;
560bff6a5aSEd Maste const u_char *bp = p;
57a90e161bSBill Fenner
58*ee67461eSJoseph Mingrone ndo->ndo_protocol = "chdlc";
590bff6a5aSEd Maste if (length < CHDLC_HDRLEN)
600bff6a5aSEd Maste goto trunc;
61*ee67461eSJoseph Mingrone proto = GET_BE_U_2(p + 2);
623c602fabSXin LI if (ndo->ndo_eflag) {
63*ee67461eSJoseph Mingrone ND_PRINT("%s, ethertype %s (0x%04x), length %u: ",
64*ee67461eSJoseph Mingrone tok2str(chdlc_cast_values, "0x%02x", GET_U_1(p)),
65b5bfcb5dSMax Laier tok2str(ethertype_values, "Unknown", proto),
66b5bfcb5dSMax Laier proto,
67*ee67461eSJoseph Mingrone length);
68b0453382SBill Fenner }
69b0453382SBill Fenner
70b0453382SBill Fenner length -= CHDLC_HDRLEN;
71b5bfcb5dSMax Laier p += CHDLC_HDRLEN;
72b5bfcb5dSMax Laier
73b0453382SBill Fenner switch (proto) {
74b0453382SBill Fenner case ETHERTYPE_IP:
753c602fabSXin LI ip_print(ndo, p, length);
76b0453382SBill Fenner break;
77b0453382SBill Fenner case ETHERTYPE_IPV6:
783c602fabSXin LI ip6_print(ndo, p, length);
79b0453382SBill Fenner break;
80b0453382SBill Fenner case CHDLC_TYPE_SLARP:
813c602fabSXin LI chdlc_slarp_print(ndo, p, length);
82b0453382SBill Fenner break;
835b0fe478SBruce M Simpson case ETHERTYPE_MPLS:
845b0fe478SBruce M Simpson case ETHERTYPE_MPLS_MULTI:
853c602fabSXin LI mpls_print(ndo, p, length);
865b0fe478SBruce M Simpson break;
875b0fe478SBruce M Simpson case ETHERTYPE_ISO:
885b0fe478SBruce M Simpson /* is the fudge byte set ? lets verify by spotting ISO headers */
890bff6a5aSEd Maste if (length < 2)
900bff6a5aSEd Maste goto trunc;
91*ee67461eSJoseph Mingrone if (GET_U_1(p + 1) == NLPID_CLNP ||
92*ee67461eSJoseph Mingrone GET_U_1(p + 1) == NLPID_ESIS ||
93*ee67461eSJoseph Mingrone GET_U_1(p + 1) == NLPID_ISIS)
940bff6a5aSEd Maste isoclns_print(ndo, p + 1, length - 1);
955b0fe478SBruce M Simpson else
960bff6a5aSEd Maste isoclns_print(ndo, p, length);
975b0fe478SBruce M Simpson break;
985b0fe478SBruce M Simpson default:
993c602fabSXin LI if (!ndo->ndo_eflag)
100*ee67461eSJoseph Mingrone ND_PRINT("unknown CHDLC protocol (0x%04x)", proto);
1015b0fe478SBruce M Simpson break;
102b0453382SBill Fenner }
1035b0fe478SBruce M Simpson
1045b0fe478SBruce M Simpson return (CHDLC_HDRLEN);
1050bff6a5aSEd Maste
1060bff6a5aSEd Maste trunc:
107*ee67461eSJoseph Mingrone nd_print_trunc(ndo);
108*ee67461eSJoseph Mingrone return (ND_BYTES_AVAILABLE_AFTER(bp));
109b0453382SBill Fenner }
110b0453382SBill Fenner
111f4d0c64aSSam Leffler /*
112f4d0c64aSSam Leffler * The fixed-length portion of a SLARP packet.
113f4d0c64aSSam Leffler */
114b0453382SBill Fenner struct cisco_slarp {
115*ee67461eSJoseph Mingrone nd_uint32_t code;
116b0453382SBill Fenner #define SLARP_REQUEST 0
117b0453382SBill Fenner #define SLARP_REPLY 1
118b0453382SBill Fenner #define SLARP_KEEPALIVE 2
119b0453382SBill Fenner union {
120b0453382SBill Fenner struct {
1213c602fabSXin LI uint8_t addr[4];
1223c602fabSXin LI uint8_t mask[4];
123b0453382SBill Fenner } addr;
124b0453382SBill Fenner struct {
125*ee67461eSJoseph Mingrone nd_uint32_t myseq;
126*ee67461eSJoseph Mingrone nd_uint32_t yourseq;
127*ee67461eSJoseph Mingrone nd_uint16_t rel;
128b0453382SBill Fenner } keep;
129b0453382SBill Fenner } un;
130b0453382SBill Fenner };
131b0453382SBill Fenner
132f4d0c64aSSam Leffler #define SLARP_MIN_LEN 14
133f4d0c64aSSam Leffler #define SLARP_MAX_LEN 18
134b0453382SBill Fenner
135b0453382SBill Fenner static void
chdlc_slarp_print(netdissect_options * ndo,const u_char * cp,u_int length)1363c602fabSXin LI chdlc_slarp_print(netdissect_options *ndo, const u_char *cp, u_int length)
137b0453382SBill Fenner {
138a90e161bSBill Fenner const struct cisco_slarp *slarp;
139f4d0c64aSSam Leffler u_int sec,min,hrs,days;
140b0453382SBill Fenner
141*ee67461eSJoseph Mingrone ndo->ndo_protocol = "chdlc_slarp";
142*ee67461eSJoseph Mingrone ND_PRINT("SLARP (length: %u), ",length);
143f4d0c64aSSam Leffler if (length < SLARP_MIN_LEN)
1445b0fe478SBruce M Simpson goto trunc;
145b0453382SBill Fenner
146a90e161bSBill Fenner slarp = (const struct cisco_slarp *)cp;
147*ee67461eSJoseph Mingrone ND_TCHECK_LEN(slarp, SLARP_MIN_LEN);
148*ee67461eSJoseph Mingrone switch (GET_BE_U_4(slarp->code)) {
149b0453382SBill Fenner case SLARP_REQUEST:
150*ee67461eSJoseph Mingrone ND_PRINT("request");
151f4d0c64aSSam Leffler /*
152f4d0c64aSSam Leffler * At least according to William "Chops" Westfield's
153f4d0c64aSSam Leffler * message in
154f4d0c64aSSam Leffler *
155*ee67461eSJoseph Mingrone * https://web.archive.org/web/20190725151313/www.nethelp.no/net/cisco-hdlc.txt
156f4d0c64aSSam Leffler *
157f4d0c64aSSam Leffler * the address and mask aren't used in requests -
158f4d0c64aSSam Leffler * they're just zero.
159f4d0c64aSSam Leffler */
160b0453382SBill Fenner break;
161b0453382SBill Fenner case SLARP_REPLY:
162*ee67461eSJoseph Mingrone ND_PRINT("reply %s/%s",
163*ee67461eSJoseph Mingrone GET_IPADDR_STRING(slarp->un.addr.addr),
164*ee67461eSJoseph Mingrone GET_IPADDR_STRING(slarp->un.addr.mask));
165b0453382SBill Fenner break;
166b0453382SBill Fenner case SLARP_KEEPALIVE:
167*ee67461eSJoseph Mingrone ND_PRINT("keepalive: mineseen=0x%08x, yourseen=0x%08x, reliability=0x%04x",
168*ee67461eSJoseph Mingrone GET_BE_U_4(slarp->un.keep.myseq),
169*ee67461eSJoseph Mingrone GET_BE_U_4(slarp->un.keep.yourseq),
170*ee67461eSJoseph Mingrone GET_BE_U_2(slarp->un.keep.rel));
171f4d0c64aSSam Leffler
172f4d0c64aSSam Leffler if (length >= SLARP_MAX_LEN) { /* uptime-stamp is optional */
173f4d0c64aSSam Leffler cp += SLARP_MIN_LEN;
174*ee67461eSJoseph Mingrone sec = GET_BE_U_4(cp) / 1000;
175f4d0c64aSSam Leffler min = sec / 60; sec -= min * 60;
176f4d0c64aSSam Leffler hrs = min / 60; min -= hrs * 60;
177f4d0c64aSSam Leffler days = hrs / 24; hrs -= days * 24;
178*ee67461eSJoseph Mingrone ND_PRINT(", link uptime=%ud%uh%um%us",days,hrs,min,sec);
179f4d0c64aSSam Leffler }
180b0453382SBill Fenner break;
181b0453382SBill Fenner default:
182*ee67461eSJoseph Mingrone ND_PRINT("0x%02x unknown", GET_BE_U_4(slarp->code));
1833c602fabSXin LI if (ndo->ndo_vflag <= 1)
1843c602fabSXin LI print_unknown_data(ndo,cp+4,"\n\t",length-4);
185b0453382SBill Fenner break;
186b0453382SBill Fenner }
187b0453382SBill Fenner
1883c602fabSXin LI if (SLARP_MAX_LEN < length && ndo->ndo_vflag)
189*ee67461eSJoseph Mingrone ND_PRINT(", (trailing junk: %u bytes)", length - SLARP_MAX_LEN);
1903c602fabSXin LI if (ndo->ndo_vflag > 1)
1913c602fabSXin LI print_unknown_data(ndo,cp+4,"\n\t",length-4);
1925b0fe478SBruce M Simpson return;
1935b0fe478SBruce M Simpson
1945b0fe478SBruce M Simpson trunc:
195*ee67461eSJoseph Mingrone nd_print_trunc(ndo);
196b0453382SBill Fenner }
197