1 /* $OpenBSD: print-isoclns.c,v 1.14 2020/01/24 22:46:37 procter Exp $ */ 2 3 /* 4 * Copyright (c) 1992, 1993, 1994, 1995, 1996 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that: (1) source code distributions 9 * retain the above copyright notice and this paragraph in its entirety, (2) 10 * distributions including binary code include the above copyright notice and 11 * this paragraph in its entirety in the documentation or other materials 12 * provided with the distribution, and (3) all advertising materials mentioning 13 * features or use of this software display the following acknowledgement: 14 * ``This product includes software developed by the University of California, 15 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 16 * the University nor the names of its contributors may be used to endorse 17 * or promote products derived from this software without specific prior 18 * written permission. 19 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 20 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 22 * 23 * Original code by Matt Thomas, Digital Equipment Corporation 24 */ 25 26 #include <sys/types.h> 27 #include <sys/time.h> 28 #include <sys/socket.h> 29 30 struct mbuf; 31 struct rtentry; 32 #include <net/if.h> 33 34 #include <netinet/in.h> 35 #include <netinet/if_ether.h> 36 37 #include <stdio.h> 38 39 #include "interface.h" 40 #include "addrtoname.h" 41 #include "ethertype.h" 42 43 #define CLNS 129 44 #define ESIS 130 45 #define ISIS 131 46 #define NULLNS 0 47 48 static int osi_cksum(const u_char *, u_int, const u_char *, u_char *, u_char *); 49 static void esis_print(const u_char *, u_int); 50 51 void 52 isoclns_print(const u_char *p, u_int length, u_int caplen, 53 const u_char *esrc, const u_char *edst) 54 { 55 if (caplen < 1) { 56 printf("[|iso-clns] "); 57 if (!eflag) 58 printf("%s > %s", 59 etheraddr_string(esrc), 60 etheraddr_string(edst)); 61 return; 62 } 63 64 switch (*p) { 65 66 case CLNS: 67 /* esis_print(&p, &length); */ 68 printf("iso-clns"); 69 if (!eflag) 70 printf(" %s > %s", 71 etheraddr_string(esrc), 72 etheraddr_string(edst)); 73 break; 74 75 case ESIS: 76 printf("iso-esis"); 77 if (!eflag) 78 printf(" %s > %s", 79 etheraddr_string(esrc), 80 etheraddr_string(edst)); 81 esis_print(p, length); 82 return; 83 84 case ISIS: 85 printf("iso-isis"); 86 if (!eflag) 87 printf(" %s > %s", 88 etheraddr_string(esrc), 89 etheraddr_string(edst)); 90 /* isis_print(&p, &length); */ 91 printf(" len=%d ", length); 92 if (caplen > 1) 93 default_print_unaligned(p, caplen); 94 break; 95 96 case NULLNS: 97 printf("iso-nullns"); 98 if (!eflag) 99 printf(" %s > %s", 100 etheraddr_string(esrc), 101 etheraddr_string(edst)); 102 break; 103 104 default: 105 printf("iso-clns %02x", p[0]); 106 if (!eflag) 107 printf(" %s > %s", 108 etheraddr_string(esrc), 109 etheraddr_string(edst)); 110 printf(" len=%d ", length); 111 if (caplen > 1) 112 default_print_unaligned(p, caplen); 113 break; 114 } 115 } 116 117 #define ESIS_REDIRECT 6 118 #define ESIS_ESH 2 119 #define ESIS_ISH 4 120 121 struct esis_hdr { 122 u_char version; 123 u_char reserved; 124 u_char type; 125 u_char tmo[2]; 126 u_char cksum[2]; 127 }; 128 129 static void 130 esis_print(const u_char *p, u_int length) 131 { 132 const u_char *ep; 133 int li = p[1]; 134 const struct esis_hdr *eh = (const struct esis_hdr *) &p[2]; 135 u_char cksum[2]; 136 u_char off[2]; 137 138 if (length == 2) { 139 if (qflag) 140 printf(" bad pkt!"); 141 else 142 printf(" no header at all!"); 143 return; 144 } 145 ep = p + li; 146 if (li > length) { 147 if (qflag) 148 printf(" bad pkt!"); 149 else 150 printf(" LI(%d) > PDU size (%d)!", li, length); 151 return; 152 } 153 if (li < sizeof(struct esis_hdr) + 2) { 154 if (qflag) 155 printf(" bad pkt!"); 156 else { 157 printf(" too short for esis header %d:", li); 158 while (--length != 0) 159 printf("%02X", *p++); 160 } 161 return; 162 } 163 switch (eh->type & 0x1f) { 164 165 case ESIS_REDIRECT: 166 printf(" redirect"); 167 break; 168 169 case ESIS_ESH: 170 printf(" esh"); 171 break; 172 173 case ESIS_ISH: 174 printf(" ish"); 175 break; 176 177 default: 178 printf(" type %d", eh->type & 0x1f); 179 break; 180 } 181 off[0] = eh->cksum[0]; 182 off[1] = eh->cksum[1]; 183 if (vflag && osi_cksum(p, li, eh->cksum, cksum, off)) { 184 printf(" bad cksum (got %02x%02x want %02x%02x)", 185 eh->cksum[1], eh->cksum[0], cksum[1], cksum[0]); 186 return; 187 } 188 if (eh->version != 1) { 189 printf(" unsupported version %d", eh->version); 190 return; 191 } 192 p += sizeof(*eh) + 2; 193 li -= sizeof(*eh) + 2; /* protoid * li */ 194 195 switch (eh->type & 0x1f) { 196 case ESIS_REDIRECT: { 197 const u_char *dst, *snpa, *is; 198 199 dst = p; p += *p + 1; 200 if (p > snapend) 201 return; 202 printf(" %s", isonsap_string(dst)); 203 snpa = p; p += *p + 1; 204 is = p; p += *p + 1; 205 if (p > snapend) 206 return; 207 if (p > ep) { 208 printf(" [bad li]"); 209 return; 210 } 211 if (is[0] == 0) 212 printf(" > %s", etheraddr_string(&snpa[1])); 213 else 214 printf(" > %s", isonsap_string(is)); 215 li = ep - p; 216 break; 217 } 218 case ESIS_ESH: { 219 const u_char *nsap; 220 int i, nnsaps; 221 222 nnsaps = *p++; 223 224 /* print NSAPs */ 225 for (i = 0; i < nnsaps; i++) { 226 nsap = p; 227 p += *p + 1; 228 if (p > ep) { 229 printf(" [bad li]"); 230 return; 231 } 232 if (p > snapend) 233 return; 234 printf(" nsap %s", isonsap_string(nsap)); 235 } 236 li = ep - p; 237 break; 238 } 239 case ESIS_ISH: { 240 const u_char *is; 241 242 is = p; p += *p + 1; 243 if (p > ep) { 244 printf(" [bad li]"); 245 return; 246 } 247 if (p > snapend) 248 return; 249 printf(" net %s", isonsap_string(is)); 250 li = ep - p; 251 break; 252 } 253 254 default: 255 printf(" len=%d", length); 256 if (length && p < snapend) { 257 length = snapend - p; 258 default_print(p, length); 259 } 260 return; 261 } 262 if (vflag) 263 while (p < ep && li) { 264 int op, opli; 265 const u_char *q; 266 267 if (snapend - p < 2) 268 return; 269 if (li < 2) { 270 printf(" bad opts/li"); 271 return; 272 } 273 op = *p++; 274 opli = *p++; 275 li -= 2; 276 if (opli > li) { 277 printf(" opt (%d) too long", op); 278 return; 279 } 280 li -= opli; 281 q = p; 282 p += opli; 283 if (snapend < p) 284 return; 285 if (op == 198 && opli == 2) { 286 printf(" tmo=%d", q[0] * 256 + q[1]); 287 continue; 288 } 289 printf (" %d:<", op); 290 while (--opli >= 0) 291 printf("%02x", *q++); 292 printf (">"); 293 } 294 } 295 296 static int 297 osi_cksum(const u_char *p, u_int len, 298 const u_char *toff, u_char *cksum, u_char *off) 299 { 300 const u_char *ep; 301 int c0, c1; 302 int n; 303 304 if ((cksum[0] = off[0]) == 0 && (cksum[1] = off[1]) == 0) 305 return 0; 306 307 n = toff - p + 1; 308 c0 = c1 = 0; 309 ep = p + len; 310 for (; p < toff; p++) { 311 c0 = (c0 + *p); 312 c1 += c0; 313 } 314 315 /* skip cksum bytes */ 316 p += 2; 317 c1 += c0; c1 += c0; 318 319 for (; p < ep; p++) { 320 c0 = (c0 + *p); 321 c1 += c0; 322 } 323 324 c1 = (((c0 * (len - n)) - c1) % 255); 325 cksum[0] = (u_char) ((c1 < 0) ? c1 + 255 : c1); 326 c1 = (-(int) (c1 + c0)) % 255; 327 cksum[1] = (u_char) (c1 < 0 ? c1 + 255 : c1); 328 329 return (off[0] != cksum[0] || off[1] != cksum[1]); 330 } 331