print-egp.c revision 56893
1/* 2 * Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are permitted 6 * provided that the above copyright notice and this paragraph are 7 * duplicated in all such forms and that any documentation, 8 * advertising materials, and other materials related to such 9 * distribution and use acknowledge that the software was developed 10 * by the University of California, Lawrence Berkeley Laboratory, 11 * Berkeley, CA. The name of the University may not be used to 12 * endorse or promote products derived from this software without 13 * specific prior written permission. 14 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 17 * 18 * Initial contribution from Jeff Honig (jch@MITCHELL.CIT.CORNELL.EDU). 19 */ 20 21#ifndef lint 22static const char rcsid[] = 23 "@(#) $Header: /tcpdump/master/tcpdump/print-egp.c,v 1.24 1999/11/21 09:36:51 fenner Exp $ (LBL)"; 24#endif 25 26#ifdef HAVE_CONFIG_H 27#include "config.h" 28#endif 29 30#include <sys/param.h> 31#include <sys/time.h> 32#include <sys/uio.h> 33#include <sys/socket.h> 34 35#include <netinet/in.h> 36#include <netinet/in_systm.h> 37#include <netinet/ip.h> 38 39#include <netdb.h> 40#include <stdio.h> 41 42#include "interface.h" 43#include "addrtoname.h" 44 45struct egp_packet { 46 u_char egp_version; 47#define EGP_VERSION 2 48 u_char egp_type; 49#define EGPT_ACQUIRE 3 50#define EGPT_REACH 5 51#define EGPT_POLL 2 52#define EGPT_UPDATE 1 53#define EGPT_ERROR 8 54 u_char egp_code; 55#define EGPC_REQUEST 0 56#define EGPC_CONFIRM 1 57#define EGPC_REFUSE 2 58#define EGPC_CEASE 3 59#define EGPC_CEASEACK 4 60#define EGPC_HELLO 0 61#define EGPC_HEARDU 1 62 u_char egp_status; 63#define EGPS_UNSPEC 0 64#define EGPS_ACTIVE 1 65#define EGPS_PASSIVE 2 66#define EGPS_NORES 3 67#define EGPS_ADMIN 4 68#define EGPS_GODOWN 5 69#define EGPS_PARAM 6 70#define EGPS_PROTO 7 71#define EGPS_INDET 0 72#define EGPS_UP 1 73#define EGPS_DOWN 2 74#define EGPS_UNSOL 0x80 75 u_short egp_checksum; 76 u_short egp_as; 77 u_short egp_sequence; 78 union { 79 u_short egpu_hello; 80 u_char egpu_gws[2]; 81 u_short egpu_reason; 82#define EGPR_UNSPEC 0 83#define EGPR_BADHEAD 1 84#define EGPR_BADDATA 2 85#define EGPR_NOREACH 3 86#define EGPR_XSPOLL 4 87#define EGPR_NORESP 5 88#define EGPR_UVERSION 6 89 } egp_handg; 90#define egp_hello egp_handg.egpu_hello 91#define egp_intgw egp_handg.egpu_gws[0] 92#define egp_extgw egp_handg.egpu_gws[1] 93#define egp_reason egp_handg.egpu_reason 94 union { 95 u_short egpu_poll; 96 u_int32_t egpu_sourcenet; 97 } egp_pands; 98#define egp_poll egp_pands.egpu_poll 99#define egp_sourcenet egp_pands.egpu_sourcenet 100}; 101 102char *egp_acquire_codes[] = { 103 "request", 104 "confirm", 105 "refuse", 106 "cease", 107 "cease_ack" 108}; 109 110char *egp_acquire_status[] = { 111 "unspecified", 112 "active_mode", 113 "passive_mode", 114 "insufficient_resources", 115 "administratively_prohibited", 116 "going_down", 117 "parameter_violation", 118 "protocol_violation" 119}; 120 121char *egp_reach_codes[] = { 122 "hello", 123 "i-h-u" 124}; 125 126char *egp_status_updown[] = { 127 "indeterminate", 128 "up", 129 "down" 130}; 131 132char *egp_reasons[] = { 133 "unspecified", 134 "bad_EGP_header_format", 135 "bad_EGP_data_field_format", 136 "reachability_info_unavailable", 137 "excessive_polling_rate", 138 "no_response", 139 "unsupported_version" 140}; 141 142static void 143egpnrprint(register const struct egp_packet *egp, register u_int length) 144{ 145 register const u_char *cp; 146 u_int32_t addr; 147 register u_int32_t net; 148 register u_int netlen; 149 int gateways, distances, networks; 150 int t_gateways; 151 char *comma; 152 153 addr = egp->egp_sourcenet; 154 if (IN_CLASSA(addr)) { 155 net = addr & IN_CLASSA_NET; 156 netlen = 1; 157 } else if (IN_CLASSB(addr)) { 158 net = addr & IN_CLASSB_NET; 159 netlen = 2; 160 } else if (IN_CLASSC(addr)) { 161 net = addr & IN_CLASSC_NET; 162 netlen = 3; 163 } else { 164 net = 0; 165 netlen = 0; 166 } 167 cp = (u_char *)(egp + 1); 168 169 t_gateways = egp->egp_intgw + egp->egp_extgw; 170 for (gateways = 0; gateways < t_gateways; ++gateways) { 171 /* Pickup host part of gateway address */ 172 addr = 0; 173 TCHECK2(cp[0], 4 - netlen); 174 switch (netlen) { 175 176 case 1: 177 addr = *cp++; 178 /* fall through */ 179 case 2: 180 addr = (addr << 8) | *cp++; 181 /* fall through */ 182 case 3: 183 addr = (addr << 8) | *cp++; 184 } 185 addr |= net; 186 TCHECK2(cp[0], 1); 187 distances = *cp++; 188 printf(" %s %s ", 189 gateways < (int)egp->egp_intgw ? "int" : "ext", 190 ipaddr_string(&addr)); 191 192 comma = ""; 193 putchar('('); 194 while (--distances >= 0) { 195 TCHECK2(cp[0], 2); 196 printf("%sd%d:", comma, (int)*cp++); 197 comma = ", "; 198 networks = *cp++; 199 while (--networks >= 0) { 200 /* Pickup network number */ 201 TCHECK2(cp[0], 1); 202 addr = (u_int32_t)*cp++ << 24; 203 if (IN_CLASSB(addr)) { 204 TCHECK2(cp[0], 1); 205 addr |= (u_int32_t)*cp++ << 16; 206 } else if (!IN_CLASSA(addr)) { 207 TCHECK2(cp[0], 2); 208 addr |= (u_int32_t)*cp++ << 16; 209 addr |= (u_int32_t)*cp++ << 8; 210 } 211 printf(" %s", ipaddr_string(&addr)); 212 } 213 } 214 putchar(')'); 215 } 216 return; 217trunc: 218 fputs("[|]", stdout); 219} 220 221void 222egp_print(register const u_char *bp, register u_int length, 223 register const u_char *bp2) 224{ 225 register const struct egp_packet *egp; 226 register const struct ip *ip; 227 register int status; 228 register int code; 229 register int type; 230 231 egp = (struct egp_packet *)bp; 232 ip = (struct ip *)bp2; 233 (void)printf("%s > %s: egp: ", 234 ipaddr_string(&ip->ip_src), 235 ipaddr_string(&ip->ip_dst)); 236 237 if (egp->egp_version != EGP_VERSION) { 238 printf("[version %d]", egp->egp_version); 239 return; 240 } 241 printf("as:%d seq:%d", ntohs(egp->egp_as), ntohs(egp->egp_sequence)); 242 243 type = egp->egp_type; 244 code = egp->egp_code; 245 status = egp->egp_status; 246 247 switch (type) { 248 case EGPT_ACQUIRE: 249 printf(" acquire"); 250 switch (code) { 251 case EGPC_REQUEST: 252 case EGPC_CONFIRM: 253 printf(" %s", egp_acquire_codes[code]); 254 switch (status) { 255 case EGPS_UNSPEC: 256 case EGPS_ACTIVE: 257 case EGPS_PASSIVE: 258 printf(" %s", egp_acquire_status[status]); 259 break; 260 261 default: 262 printf(" [status %d]", status); 263 break; 264 } 265 printf(" hello:%d poll:%d", 266 ntohs(egp->egp_hello), 267 ntohs(egp->egp_poll)); 268 break; 269 270 case EGPC_REFUSE: 271 case EGPC_CEASE: 272 case EGPC_CEASEACK: 273 printf(" %s", egp_acquire_codes[code]); 274 switch (status ) { 275 case EGPS_UNSPEC: 276 case EGPS_NORES: 277 case EGPS_ADMIN: 278 case EGPS_GODOWN: 279 case EGPS_PARAM: 280 case EGPS_PROTO: 281 printf(" %s", egp_acquire_status[status]); 282 break; 283 284 default: 285 printf("[status %d]", status); 286 break; 287 } 288 break; 289 290 default: 291 printf("[code %d]", code); 292 break; 293 } 294 break; 295 296 case EGPT_REACH: 297 switch (code) { 298 299 case EGPC_HELLO: 300 case EGPC_HEARDU: 301 printf(" %s", egp_reach_codes[code]); 302 if (status <= EGPS_DOWN) 303 printf(" state:%s", egp_status_updown[status]); 304 else 305 printf(" [status %d]", status); 306 break; 307 308 default: 309 printf("[reach code %d]", code); 310 break; 311 } 312 break; 313 314 case EGPT_POLL: 315 printf(" poll"); 316 if (egp->egp_status <= EGPS_DOWN) 317 printf(" state:%s", egp_status_updown[status]); 318 else 319 printf(" [status %d]", status); 320 printf(" net:%s", ipaddr_string(&egp->egp_sourcenet)); 321 break; 322 323 case EGPT_UPDATE: 324 printf(" update"); 325 if (status & EGPS_UNSOL) { 326 status &= ~EGPS_UNSOL; 327 printf(" unsolicited"); 328 } 329 if (status <= EGPS_DOWN) 330 printf(" state:%s", egp_status_updown[status]); 331 else 332 printf(" [status %d]", status); 333 printf(" %s int %d ext %d", 334 ipaddr_string(&egp->egp_sourcenet), 335 egp->egp_intgw, 336 egp->egp_extgw); 337 if (vflag) 338 egpnrprint(egp, length); 339 break; 340 341 case EGPT_ERROR: 342 printf(" error"); 343 if (status <= EGPS_DOWN) 344 printf(" state:%s", egp_status_updown[status]); 345 else 346 printf(" [status %d]", status); 347 348 if (ntohs(egp->egp_reason) <= EGPR_UVERSION) 349 printf(" %s", egp_reasons[ntohs(egp->egp_reason)]); 350 else 351 printf(" [reason %d]", ntohs(egp->egp_reason)); 352 break; 353 354 default: 355 printf("[type %d]", type); 356 break; 357 } 358} 359