117680Spst/* 217680Spst * Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996 317680Spst * The Regents of the University of California. All rights reserved. 417680Spst * 517680Spst * Redistribution and use in source and binary forms are permitted 617680Spst * provided that the above copyright notice and this paragraph are 717680Spst * duplicated in all such forms and that any documentation, 817680Spst * advertising materials, and other materials related to such 917680Spst * distribution and use acknowledge that the software was developed 1017680Spst * by the University of California, Lawrence Berkeley Laboratory, 1117680Spst * Berkeley, CA. The name of the University may not be used to 1217680Spst * endorse or promote products derived from this software without 1317680Spst * specific prior written permission. 1417680Spst * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1517680Spst * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1617680Spst * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1717680Spst * 1817680Spst * Initial contribution from Jeff Honig (jch@MITCHELL.CIT.CORNELL.EDU). 1917680Spst */ 2017680Spst 2117680Spst#ifndef lint 22127668Sbmsstatic const char rcsid[] _U_ = 23190207Srpaulo "@(#) $Header: /tcpdump/master/tcpdump/print-egp.c,v 1.38 2006-02-11 22:13:24 hannes Exp $ (LBL)"; 2417680Spst#endif 2517680Spst 2656893Sfenner#ifdef HAVE_CONFIG_H 2756893Sfenner#include "config.h" 2856893Sfenner#endif 2956893Sfenner 30127668Sbms#include <tcpdump-stdinc.h> 3117680Spst 3217680Spst#include <stdio.h> 3317680Spst 3417680Spst#include "interface.h" 3517680Spst#include "addrtoname.h" 36127668Sbms#include "extract.h" 3717680Spst 3875115Sfenner#include "ip.h" 3975115Sfenner 4017680Spststruct egp_packet { 41127668Sbms u_int8_t egp_version; 4217680Spst#define EGP_VERSION 2 43127668Sbms u_int8_t egp_type; 4417680Spst#define EGPT_ACQUIRE 3 4517680Spst#define EGPT_REACH 5 4617680Spst#define EGPT_POLL 2 4717680Spst#define EGPT_UPDATE 1 4817680Spst#define EGPT_ERROR 8 49127668Sbms u_int8_t egp_code; 5017680Spst#define EGPC_REQUEST 0 5117680Spst#define EGPC_CONFIRM 1 5217680Spst#define EGPC_REFUSE 2 5317680Spst#define EGPC_CEASE 3 5417680Spst#define EGPC_CEASEACK 4 5517680Spst#define EGPC_HELLO 0 5617680Spst#define EGPC_HEARDU 1 57127668Sbms u_int8_t egp_status; 5817680Spst#define EGPS_UNSPEC 0 5917680Spst#define EGPS_ACTIVE 1 6017680Spst#define EGPS_PASSIVE 2 6117680Spst#define EGPS_NORES 3 6217680Spst#define EGPS_ADMIN 4 6317680Spst#define EGPS_GODOWN 5 6417680Spst#define EGPS_PARAM 6 6517680Spst#define EGPS_PROTO 7 6617680Spst#define EGPS_INDET 0 6717680Spst#define EGPS_UP 1 6817680Spst#define EGPS_DOWN 2 6917680Spst#define EGPS_UNSOL 0x80 70127668Sbms u_int16_t egp_checksum; 71127668Sbms u_int16_t egp_as; 72127668Sbms u_int16_t egp_sequence; 7317680Spst union { 74127668Sbms u_int16_t egpu_hello; 75127668Sbms u_int8_t egpu_gws[2]; 76127668Sbms u_int16_t egpu_reason; 7717680Spst#define EGPR_UNSPEC 0 7817680Spst#define EGPR_BADHEAD 1 7917680Spst#define EGPR_BADDATA 2 8017680Spst#define EGPR_NOREACH 3 8117680Spst#define EGPR_XSPOLL 4 8217680Spst#define EGPR_NORESP 5 8317680Spst#define EGPR_UVERSION 6 8417680Spst } egp_handg; 8517680Spst#define egp_hello egp_handg.egpu_hello 8617680Spst#define egp_intgw egp_handg.egpu_gws[0] 8717680Spst#define egp_extgw egp_handg.egpu_gws[1] 8817680Spst#define egp_reason egp_handg.egpu_reason 8917680Spst union { 90127668Sbms u_int16_t egpu_poll; 9117680Spst u_int32_t egpu_sourcenet; 9217680Spst } egp_pands; 9317680Spst#define egp_poll egp_pands.egpu_poll 9417680Spst#define egp_sourcenet egp_pands.egpu_sourcenet 9517680Spst}; 9617680Spst 9798524Sfennerconst char *egp_acquire_codes[] = { 9817680Spst "request", 9917680Spst "confirm", 10017680Spst "refuse", 10117680Spst "cease", 10217680Spst "cease_ack" 10317680Spst}; 10417680Spst 10598524Sfennerconst char *egp_acquire_status[] = { 10617680Spst "unspecified", 10717680Spst "active_mode", 10817680Spst "passive_mode", 10917680Spst "insufficient_resources", 11017680Spst "administratively_prohibited", 11117680Spst "going_down", 11217680Spst "parameter_violation", 11317680Spst "protocol_violation" 11417680Spst}; 11517680Spst 11698524Sfennerconst char *egp_reach_codes[] = { 11717680Spst "hello", 11817680Spst "i-h-u" 11917680Spst}; 12017680Spst 12198524Sfennerconst char *egp_status_updown[] = { 12217680Spst "indeterminate", 12317680Spst "up", 12417680Spst "down" 12517680Spst}; 12617680Spst 12798524Sfennerconst char *egp_reasons[] = { 12817680Spst "unspecified", 12917680Spst "bad_EGP_header_format", 13017680Spst "bad_EGP_data_field_format", 13117680Spst "reachability_info_unavailable", 13217680Spst "excessive_polling_rate", 13317680Spst "no_response", 13417680Spst "unsupported_version" 13517680Spst}; 13617680Spst 13717680Spststatic void 138127668Sbmsegpnrprint(register const struct egp_packet *egp) 13917680Spst{ 140127668Sbms register const u_int8_t *cp; 14117680Spst u_int32_t addr; 14217680Spst register u_int32_t net; 14317680Spst register u_int netlen; 14417680Spst int gateways, distances, networks; 14517680Spst int t_gateways; 146127668Sbms const char *comma; 14717680Spst 14817680Spst addr = egp->egp_sourcenet; 14917680Spst if (IN_CLASSA(addr)) { 15017680Spst net = addr & IN_CLASSA_NET; 15117680Spst netlen = 1; 15217680Spst } else if (IN_CLASSB(addr)) { 15317680Spst net = addr & IN_CLASSB_NET; 15417680Spst netlen = 2; 15517680Spst } else if (IN_CLASSC(addr)) { 15617680Spst net = addr & IN_CLASSC_NET; 15717680Spst netlen = 3; 15817680Spst } else { 15917680Spst net = 0; 16017680Spst netlen = 0; 16117680Spst } 162127668Sbms cp = (u_int8_t *)(egp + 1); 16317680Spst 16417680Spst t_gateways = egp->egp_intgw + egp->egp_extgw; 16517680Spst for (gateways = 0; gateways < t_gateways; ++gateways) { 16617680Spst /* Pickup host part of gateway address */ 16717680Spst addr = 0; 16817680Spst TCHECK2(cp[0], 4 - netlen); 16917680Spst switch (netlen) { 17017680Spst 17117680Spst case 1: 17217680Spst addr = *cp++; 17317680Spst /* fall through */ 17417680Spst case 2: 17517680Spst addr = (addr << 8) | *cp++; 17617680Spst /* fall through */ 17717680Spst case 3: 17817680Spst addr = (addr << 8) | *cp++; 17917680Spst } 18017680Spst addr |= net; 18117680Spst TCHECK2(cp[0], 1); 18217680Spst distances = *cp++; 18317680Spst printf(" %s %s ", 18426180Sfenner gateways < (int)egp->egp_intgw ? "int" : "ext", 18517680Spst ipaddr_string(&addr)); 18617680Spst 18717680Spst comma = ""; 18817680Spst putchar('('); 18917680Spst while (--distances >= 0) { 19017680Spst TCHECK2(cp[0], 2); 19117680Spst printf("%sd%d:", comma, (int)*cp++); 19217680Spst comma = ", "; 19317680Spst networks = *cp++; 19417680Spst while (--networks >= 0) { 19517680Spst /* Pickup network number */ 19617680Spst TCHECK2(cp[0], 1); 19717680Spst addr = (u_int32_t)*cp++ << 24; 19817680Spst if (IN_CLASSB(addr)) { 19917680Spst TCHECK2(cp[0], 1); 20017680Spst addr |= (u_int32_t)*cp++ << 16; 20117680Spst } else if (!IN_CLASSA(addr)) { 20217680Spst TCHECK2(cp[0], 2); 20317680Spst addr |= (u_int32_t)*cp++ << 16; 20417680Spst addr |= (u_int32_t)*cp++ << 8; 20517680Spst } 20617680Spst printf(" %s", ipaddr_string(&addr)); 20717680Spst } 20817680Spst } 20917680Spst putchar(')'); 21017680Spst } 21117680Spst return; 21217680Spsttrunc: 21317680Spst fputs("[|]", stdout); 21417680Spst} 21517680Spst 21617680Spstvoid 217146773Ssamegp_print(register const u_int8_t *bp, register u_int length) 21817680Spst{ 21917680Spst register const struct egp_packet *egp; 22017680Spst register int status; 22117680Spst register int code; 22217680Spst register int type; 22317680Spst 22417680Spst egp = (struct egp_packet *)bp; 225146773Ssam if (!TTEST2(*egp, length)) { 226127668Sbms printf("[|egp]"); 227127668Sbms return; 228127668Sbms } 22917680Spst 230190207Srpaulo if (!vflag) { 231190207Srpaulo printf("EGPv%u, AS %u, seq %u, length %u", 232190207Srpaulo egp->egp_version, 233190207Srpaulo EXTRACT_16BITS(&egp->egp_as), 234190207Srpaulo EXTRACT_16BITS(&egp->egp_sequence), 235190207Srpaulo length); 236190207Srpaulo return; 237190207Srpaulo } else 238190207Srpaulo printf("EGPv%u, length %u", 239190207Srpaulo egp->egp_version, 240190207Srpaulo length); 241190207Srpaulo 24217680Spst if (egp->egp_version != EGP_VERSION) { 24317680Spst printf("[version %d]", egp->egp_version); 24417680Spst return; 24517680Spst } 24617680Spst 24717680Spst type = egp->egp_type; 24817680Spst code = egp->egp_code; 24917680Spst status = egp->egp_status; 25017680Spst 25117680Spst switch (type) { 25217680Spst case EGPT_ACQUIRE: 25317680Spst printf(" acquire"); 25417680Spst switch (code) { 25517680Spst case EGPC_REQUEST: 25617680Spst case EGPC_CONFIRM: 25717680Spst printf(" %s", egp_acquire_codes[code]); 25817680Spst switch (status) { 25917680Spst case EGPS_UNSPEC: 26017680Spst case EGPS_ACTIVE: 26117680Spst case EGPS_PASSIVE: 26217680Spst printf(" %s", egp_acquire_status[status]); 26317680Spst break; 26417680Spst 26517680Spst default: 26617680Spst printf(" [status %d]", status); 26717680Spst break; 26817680Spst } 26917680Spst printf(" hello:%d poll:%d", 270127668Sbms EXTRACT_16BITS(&egp->egp_hello), 271127668Sbms EXTRACT_16BITS(&egp->egp_poll)); 27217680Spst break; 27317680Spst 27417680Spst case EGPC_REFUSE: 27517680Spst case EGPC_CEASE: 27617680Spst case EGPC_CEASEACK: 27717680Spst printf(" %s", egp_acquire_codes[code]); 27817680Spst switch (status ) { 27917680Spst case EGPS_UNSPEC: 28017680Spst case EGPS_NORES: 28117680Spst case EGPS_ADMIN: 28217680Spst case EGPS_GODOWN: 28317680Spst case EGPS_PARAM: 28417680Spst case EGPS_PROTO: 28517680Spst printf(" %s", egp_acquire_status[status]); 28617680Spst break; 28717680Spst 28817680Spst default: 28917680Spst printf("[status %d]", status); 29017680Spst break; 29117680Spst } 29217680Spst break; 29317680Spst 29417680Spst default: 29517680Spst printf("[code %d]", code); 29617680Spst break; 29717680Spst } 29817680Spst break; 29917680Spst 30017680Spst case EGPT_REACH: 30117680Spst switch (code) { 30217680Spst 30317680Spst case EGPC_HELLO: 30417680Spst case EGPC_HEARDU: 30517680Spst printf(" %s", egp_reach_codes[code]); 30617680Spst if (status <= EGPS_DOWN) 30717680Spst printf(" state:%s", egp_status_updown[status]); 30817680Spst else 30917680Spst printf(" [status %d]", status); 31017680Spst break; 31117680Spst 31217680Spst default: 31317680Spst printf("[reach code %d]", code); 31417680Spst break; 31517680Spst } 31617680Spst break; 31717680Spst 31817680Spst case EGPT_POLL: 31917680Spst printf(" poll"); 32017680Spst if (egp->egp_status <= EGPS_DOWN) 32117680Spst printf(" state:%s", egp_status_updown[status]); 32217680Spst else 32317680Spst printf(" [status %d]", status); 32417680Spst printf(" net:%s", ipaddr_string(&egp->egp_sourcenet)); 32517680Spst break; 32617680Spst 32717680Spst case EGPT_UPDATE: 32817680Spst printf(" update"); 32917680Spst if (status & EGPS_UNSOL) { 33017680Spst status &= ~EGPS_UNSOL; 33117680Spst printf(" unsolicited"); 33217680Spst } 33317680Spst if (status <= EGPS_DOWN) 33417680Spst printf(" state:%s", egp_status_updown[status]); 33517680Spst else 33617680Spst printf(" [status %d]", status); 33717680Spst printf(" %s int %d ext %d", 33817680Spst ipaddr_string(&egp->egp_sourcenet), 33917680Spst egp->egp_intgw, 34017680Spst egp->egp_extgw); 34117680Spst if (vflag) 342127668Sbms egpnrprint(egp); 34317680Spst break; 34417680Spst 34517680Spst case EGPT_ERROR: 34617680Spst printf(" error"); 34717680Spst if (status <= EGPS_DOWN) 34817680Spst printf(" state:%s", egp_status_updown[status]); 34917680Spst else 35017680Spst printf(" [status %d]", status); 35117680Spst 352127668Sbms if (EXTRACT_16BITS(&egp->egp_reason) <= EGPR_UVERSION) 353127668Sbms printf(" %s", egp_reasons[EXTRACT_16BITS(&egp->egp_reason)]); 35417680Spst else 355127668Sbms printf(" [reason %d]", EXTRACT_16BITS(&egp->egp_reason)); 35617680Spst break; 35717680Spst 35817680Spst default: 35917680Spst printf("[type %d]", type); 36017680Spst break; 36117680Spst } 36217680Spst} 363