diff options
author | Bruce M Simpson <bms@FreeBSD.org> | 2004-03-31 14:57:24 +0000 |
---|---|---|
committer | Bruce M Simpson <bms@FreeBSD.org> | 2004-03-31 14:57:24 +0000 |
commit | cc391cce1125c1163b0cc425704a4279ca0dbe9a (patch) | |
tree | 5b810dd82a76f16819dd3cc55ffa53ff444b2d5a /contrib | |
parent | 1acc2f81b18801b28c72ae0409366c6bc402513a (diff) | |
download | src-cc391cce1125c1163b0cc425704a4279ca0dbe9a.tar.gz src-cc391cce1125c1163b0cc425704a4279ca0dbe9a.zip |
Notes
Diffstat (limited to 'contrib')
34 files changed, 4892 insertions, 3197 deletions
diff --git a/contrib/tcpdump/addrtoname.c b/contrib/tcpdump/addrtoname.c index 99e50dda9fd1..5995d23464e3 100644 --- a/contrib/tcpdump/addrtoname.c +++ b/contrib/tcpdump/addrtoname.c @@ -24,19 +24,15 @@ * $FreeBSD$ */ #ifndef lint -static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/addrtoname.c,v 1.83.4.1 2002/06/02 00:08:07 guy Exp $ (LBL)"; +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/addrtoname.c,v 1.96.2.6 2004/03/24 04:14:31 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/time.h> - -#include <netinet/in.h> +#include <tcpdump-stdinc.h> #ifdef USE_ETHER_NTOHOST #ifdef HAVE_NETINET_IF_ETHER_H @@ -45,30 +41,27 @@ struct rtentry; /* declarations in <net/if.h> */ #include <net/if.h> /* for "struct ifnet" in "struct arpcom" on Solaris */ #include <netinet/if_ether.h> #endif /* HAVE_NETINET_IF_ETHER_H */ +#ifdef HAVE_NETINET_ETHER_H +#include <netinet/ether.h> /* ether_ntohost on linux */ +#endif /* HAVE_NETINET_ETHER_H */ #endif /* USE_ETHER_NTOHOST */ -#include <arpa/inet.h> - -#include <ctype.h> -#include <netdb.h> #include <pcap.h> #include <pcap-namedb.h> #include <signal.h> #include <stdio.h> #include <string.h> #include <stdlib.h> -#include <unistd.h> #include "interface.h" #include "addrtoname.h" #include "llc.h" #include "setsignal.h" -/* Forwards */ -static RETSIGTYPE nohostname(int); - /* * hash tables for whatever-to-name translations + * + * XXX there has to be error checks against strdup(3) failure */ #define HASHNAMESIZE 4096 @@ -85,6 +78,52 @@ struct hnamemem uporttable[HASHNAMESIZE]; struct hnamemem eprototable[HASHNAMESIZE]; struct hnamemem dnaddrtable[HASHNAMESIZE]; struct hnamemem llcsaptable[HASHNAMESIZE]; +struct hnamemem ipxsaptable[HASHNAMESIZE]; + +#if defined(INET6) && defined(WIN32) +/* + * fake gethostbyaddr for Win2k/XP + * gethostbyaddr() returns incorrect value when AF_INET6 is passed + * to 3rd argument. + * + * h_name in struct hostent is only valid. + */ +static struct hostent * +win32_gethostbyaddr(const char *addr, int len, int type) +{ + static struct hostent host; + static char hostbuf[NI_MAXHOST]; + char hname[NI_MAXHOST]; + struct sockaddr_in6 addr6; + + host.h_name = hostbuf; + switch (type) { + case AF_INET: + return gethostbyaddr(addr, len, type); + break; + case AF_INET6: + memset(&addr6, 0, sizeof(addr6)); + addr6.sin6_family = AF_INET6; + memcpy(&addr6.sin6_addr, addr, len); +#ifdef __MINGW32__ + /* MinGW doesn't provide getnameinfo */ + return NULL; +#else + if (getnameinfo((struct sockaddr *)&addr6, sizeof(addr6), + hname, sizeof(hname), NULL, 0, 0)) { + return NULL; + } else { + strcpy(host.h_name, hname); + return &host; + } +#endif /* __MINGW32__ */ + break; + default: + return NULL; + } +} +#define gethostbyaddr win32_gethostbyaddr +#endif /* INET6 & WIN32*/ #ifdef INET6 struct h6namemem { @@ -154,25 +193,25 @@ intoa(u_int32_t addr) static u_int32_t f_netmask; static u_int32_t f_localnet; -static u_int32_t netmask; - -/* - * "getname" is written in this atrocious way to make sure we don't - * wait forever while trying to get hostnames from yp. - */ -#include <setjmp.h> - -jmp_buf getname_env; - -static RETSIGTYPE -nohostname(int signo) -{ - longjmp(getname_env, 1); -} /* * Return a name for the IP address pointed to by ap. This address * is assumed to be in network byte order. + * + * NOTE: ap is *NOT* necessarily part of the packet data (not even if + * this is being called with the "ipaddr_string()" macro), so you + * *CANNOT* use the TCHECK{2}/TTEST{2} macros on it. Furthermore, + * even in cases where it *is* part of the packet data, the caller + * would still have to check for a null return value, even if it's + * just printing the return value with "%s" - not all versions of + * printf print "(null)" with "%s" and a null pointer, some of them + * don't check for a null pointer and crash in that case. + * + * The callers of this routine should, before handing this routine + * a pointer to packet data, be sure that the data is present in + * the packet buffer. They should probably do those checks anyway, + * as other data at that layer might not be IP addresses, and it + * also needs to check whether they're present in the packet buffer. */ const char * getname(const u_char *ap) @@ -191,35 +230,26 @@ getname(const u_char *ap) p->nxt = newhnamemem(); /* - * Only print names when: - * (1) -n was not given. + * Print names unless: + * (1) -n was given. * (2) Address is foreign and -f was given. (If -f was not - * give, f_netmask and f_local are 0 and the test + * given, f_netmask and f_localnet are 0 and the test * evaluates to true) - * (3) -a was given or the host portion is not all ones - * nor all zeros (i.e. not a network or broadcast address) */ if (!nflag && - (addr & f_netmask) == f_localnet && - (aflag || - !((addr & ~netmask) == 0 || (addr | netmask) == 0xffffffff))) { - if (!setjmp(getname_env)) { - (void)setsignal(SIGALRM, nohostname); - (void)alarm(20); - hp = gethostbyaddr((char *)&addr, 4, AF_INET); - (void)alarm(0); - if (hp) { - char *dotp; - - p->name = strdup(hp->h_name); - if (Nflag) { - /* Remove domain qualifications */ - dotp = strchr(p->name, '.'); - if (dotp) - *dotp = '\0'; - } - return (p->name); + (addr & f_netmask) == f_localnet) { + hp = gethostbyaddr((char *)&addr, 4, AF_INET); + if (hp) { + char *dotp; + + p->name = strdup(hp->h_name); + if (Nflag) { + /* Remove domain qualifications */ + dotp = strchr(p->name, '.'); + if (dotp) + *dotp = '\0'; } + return (p->name); } } p->name = strdup(intoa(addr)); @@ -250,39 +280,21 @@ getname6(const u_char *ap) p->nxt = newh6namemem(); /* - * Only print names when: - * (1) -n was not given. - * (2) Address is foreign and -f was given. (If -f was not - * give, f_netmask and f_local are 0 and the test - * evaluates to true) - * (3) -a was given or the host portion is not all ones - * nor all zeros (i.e. not a network or broadcast address) + * Do not print names if -n was given. */ - if (!nflag -#if 0 - && - (addr & f_netmask) == f_localnet && - (aflag || - !((addr & ~netmask) == 0 || (addr | netmask) == 0xffffffff)) -#endif - ) { - if (!setjmp(getname_env)) { - (void)setsignal(SIGALRM, nohostname); - (void)alarm(20); - hp = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET6); - (void)alarm(0); - if (hp) { - char *dotp; - - p->name = strdup(hp->h_name); - if (Nflag) { - /* Remove domain qualifications */ - dotp = strchr(p->name, '.'); - if (dotp) - *dotp = '\0'; - } - return (p->name); + if (!nflag) { + hp = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET6); + if (hp) { + char *dotp; + + p->name = strdup(hp->h_name); + if (Nflag) { + /* Remove domain qualifications */ + dotp = strchr(p->name, '.'); + if (dotp) + *dotp = '\0'; } + return (p->name); } } cp = inet_ntop(AF_INET6, &addr, ntop_buf, sizeof(ntop_buf)); @@ -325,7 +337,7 @@ lookup_emem(const u_char *ep) } /* - * Find the hash node that corresponds to the bytestring 'bs' + * Find the hash node that corresponds to the bytestring 'bs' * with length 'nlen' */ @@ -443,7 +455,7 @@ lookup_protoid(const u_char *pi) const char * etheraddr_string(register const u_char *ep) { - register u_int i, j; + register u_int i; register char *cp; register struct enamemem *tp; char buf[sizeof("00:00:00:00:00:00")]; @@ -453,21 +465,19 @@ etheraddr_string(register const u_char *ep) return (tp->e_name); #ifdef USE_ETHER_NTOHOST if (!nflag) { - char buf[128]; - if (ether_ntohost(buf, (const struct ether_addr *)ep) == 0) { - tp->e_name = strdup(buf); + char buf2[128]; + if (ether_ntohost(buf2, (const struct ether_addr *)ep) == 0) { + tp->e_name = strdup(buf2); return (tp->e_name); } } #endif cp = buf; - if ((j = *ep >> 4) != 0) - *cp++ = hex[j]; + *cp++ = hex[*ep >> 4 ]; *cp++ = hex[*ep++ & 0xf]; for (i = 5; (int)--i >= 0;) { *cp++ = ':'; - if ((j = *ep >> 4) != 0) - *cp++ = hex[j]; + *cp++ = hex[*ep >> 4 ]; *cp++ = hex[*ep++ & 0xf]; } *cp = '\0'; @@ -484,7 +494,7 @@ linkaddr_string(const u_char *ep, const unsigned int len) if (len == 6) /* XXX not totally correct... */ return etheraddr_string(ep); - + tp = lookup_bytestring(ep, len); if (tp->e_name) return (tp->e_name); @@ -641,6 +651,32 @@ udpport_string(register u_short port) return (tp->name); } +const char * +ipxsap_string(u_short port) +{ + register char *cp; + register struct hnamemem *tp; + register u_int32_t i = port; + char buf[sizeof("0000")]; + + for (tp = &ipxsaptable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) + if (tp->addr == i) + return (tp->name); + + tp->addr = i; + tp->nxt = newhnamemem(); + + cp = buf; + NTOHS(port); + *cp++ = hex[port >> 12 & 0xf]; + *cp++ = hex[port >> 8 & 0xf]; + *cp++ = hex[port >> 4 & 0xf]; + *cp++ = hex[port & 0xf]; + *cp++ = '\0'; + tp->name = strdup(buf); + return (tp->name); +} + static void init_servarray(void) { @@ -673,7 +709,11 @@ init_servarray(void) } /*XXX from libbpfc.a */ +#ifndef WIN32 extern struct eproto { +#else +__declspec( dllimport) struct eproto { +#endif char *s; u_short p; } eproto_db[]; @@ -685,12 +725,12 @@ init_eprotoarray(void) register struct hnamemem *table; for (i = 0; eproto_db[i].s; i++) { - int j = ntohs(eproto_db[i].p) & (HASHNAMESIZE-1); + int j = htons(eproto_db[i].p) & (HASHNAMESIZE-1); table = &eprototable[j]; while (table->name) table = table->nxt; table->name = eproto_db[i].s; - table->addr = ntohs(eproto_db[i].p); + table->addr = htons(eproto_db[i].p); table->nxt = newhnamemem(); } } @@ -836,6 +876,240 @@ init_llcsaparray(void) } } +static struct tok ipxsap_db[] = { + { 0x0000, "Unknown" }, + { 0x0001, "User" }, + { 0x0002, "User Group" }, + { 0x0003, "PrintQueue" }, + { 0x0004, "FileServer" }, + { 0x0005, "JobServer" }, + { 0x0006, "Gateway" }, + { 0x0007, "PrintServer" }, + { 0x0008, "ArchiveQueue" }, + { 0x0009, "ArchiveServer" }, + { 0x000a, "JobQueue" }, + { 0x000b, "Administration" }, + { 0x000F, "Novell TI-RPC" }, + { 0x0017, "Diagnostics" }, + { 0x0020, "NetBIOS" }, + { 0x0021, "NAS SNA Gateway" }, + { 0x0023, "NACS AsyncGateway" }, + { 0x0024, "RemoteBridge/RoutingService" }, + { 0x0026, "BridgeServer" }, + { 0x0027, "TCP/IP Gateway" }, + { 0x0028, "Point-to-point X.25 BridgeServer" }, + { 0x0029, "3270 Gateway" }, + { 0x002a, "CHI Corp" }, + { 0x002c, "PC Chalkboard" }, + { 0x002d, "TimeSynchServer" }, + { 0x002e, "ARCserve5.0/PalindromeBackup" }, + { 0x0045, "DI3270 Gateway" }, + { 0x0047, "AdvertisingPrintServer" }, + { 0x004a, "NetBlazerModems" }, + { 0x004b, "BtrieveVAP" }, + { 0x004c, "NetwareSQL" }, + { 0x004d, "XtreeNetwork" }, + { 0x0050, "BtrieveVAP4.11" }, + { 0x0052, "QuickLink" }, + { 0x0053, "PrintQueueUser" }, + { 0x0058, "Multipoint X.25 Router" }, + { 0x0060, "STLB/NLM" }, + { 0x0064, "ARCserve" }, + { 0x0066, "ARCserve3.0" }, + { 0x0072, "WAN CopyUtility" }, + { 0x007a, "TES-NetwareVMS" }, + { 0x0092, "WATCOM Debugger/EmeraldTapeBackupServer" }, + { 0x0095, "DDA OBGYN" }, + { 0x0098, "NetwareAccessServer" }, + { 0x009a, "Netware for VMS II/NamedPipeServer" }, + { 0x009b, "NetwareAccessServer" }, + { 0x009e, "PortableNetwareServer/SunLinkNVT" }, + { 0x00a1, "PowerchuteAPC UPS" }, + { 0x00aa, "LAWserve" }, + { 0x00ac, "CompaqIDA StatusMonitor" }, + { 0x0100, "PIPE STAIL" }, + { 0x0102, "LAN ProtectBindery" }, + { 0x0103, "OracleDataBaseServer" }, + { 0x0107, "Netware386/RSPX RemoteConsole" }, + { 0x010f, "NovellSNA Gateway" }, + { 0x0111, "TestServer" }, + { 0x0112, "HP PrintServer" }, + { 0x0114, "CSA MUX" }, + { 0x0115, "CSA LCA" }, + { 0x0116, "CSA CM" }, + { 0x0117, "CSA SMA" }, + { 0x0118, "CSA DBA" }, + { 0x0119, "CSA NMA" }, + { 0x011a, "CSA SSA" }, + { 0x011b, "CSA STATUS" }, + { 0x011e, "CSA APPC" }, + { 0x0126, "SNA TEST SSA Profile" }, + { 0x012a, "CSA TRACE" }, + { 0x012b, "NetwareSAA" }, + { 0x012e, "IKARUS VirusScan" }, + { 0x0130, "CommunicationsExecutive" }, + { 0x0133, "NNS DomainServer/NetwareNamingServicesDomain" }, + { 0x0135, "NetwareNamingServicesProfile" }, + { 0x0137, "Netware386 PrintQueue/NNS PrintQueue" }, + { 0x0141, "LAN SpoolServer" }, + { 0x0152, "IRMALAN Gateway" }, + { 0x0154, "NamedPipeServer" }, + { 0x0166, "NetWareManagement" }, + { 0x0168, "Intel PICKIT CommServer/Intel CAS TalkServer" }, + { 0x0173, "Compaq" }, + { 0x0174, "Compaq SNMP Agent" }, + { 0x0175, "Compaq" }, + { 0x0180, "XTreeServer/XTreeTools" }, + { 0x018A, "NASI ServicesBroadcastServer" }, + { 0x01b0, "GARP Gateway" }, + { 0x01b1, "Binfview" }, + { 0x01bf, "IntelLanDeskManager" }, + { 0x01ca, "AXTEC" }, + { 0x01cb, "ShivaNetModem/E" }, + { 0x01cc, "ShivaLanRover/E" }, + { 0x01cd, "ShivaLanRover/T" }, + { 0x01ce, "ShivaUniversal" }, + { 0x01d8, "CastelleFAXPressServer" }, + { 0x01da, "CastelleLANPressPrintServer" }, + { 0x01dc, "CastelleFAX/Xerox7033 FaxServer/ExcelLanFax" }, + { 0x01f0, "LEGATO" }, + { 0x01f5, "LEGATO" }, + { 0x0233, "NMS Agent/NetwareManagementAgent" }, + { 0x0237, "NMS IPX Discovery/LANternReadWriteChannel" }, + { 0x0238, "NMS IP Discovery/LANternTrapAlarmChannel" }, + { 0x023a, "LANtern" }, + { 0x023c, "MAVERICK" }, + { 0x023f, "NovellSMDR" }, + { 0x024e, "NetwareConnect" }, + { 0x024f, "NASI ServerBroadcast Cisco" }, + { 0x026a, "NMS ServiceConsole" }, + { 0x026b, "TimeSynchronizationServer Netware 4.x" }, + { 0x0278, "DirectoryServer Netware 4.x" }, + { 0x027b, "NetwareManagementAgent" }, + { 0x0280, "Novell File and Printer Sharing Service for PC" }, + { 0x0304, "NovellSAA Gateway" }, + { 0x0308, "COM/VERMED" }, + { 0x030a, "GalacticommWorldgroupServer" }, + { 0x030c, "IntelNetport2/HP JetDirect/HP Quicksilver" }, + { 0x0320, "AttachmateGateway" }, + { 0x0327, "MicrosoftDiagnostiocs" }, + { 0x0328, "WATCOM SQL Server" }, + { 0x0335, "MultiTechSystems MultisynchCommServer" }, + { 0x0343, "Xylogics RemoteAccessServer/LANModem" }, + { 0x0355, "ArcadaBackupExec" }, + { 0x0358, "MSLCD1" }, + { 0x0361, "NETINELO" }, + { 0x037e, "Powerchute UPS Monitoring" }, + { 0x037f, "ViruSafeNotify" }, + { 0x0386, "HP Bridge" }, + { 0x0387, "HP Hub" }, + { 0x0394, "NetWare SAA Gateway" }, + { 0x039b, "LotusNotes" }, + { 0x03b7, "CertusAntiVirus" }, + { 0x03c4, "ARCserve4.0" }, + { 0x03c7, "LANspool3.5" }, + { 0x03d7, "LexmarkPrinterServer" }, + { 0x03d8, "LexmarkXLE PrinterServer" }, + { 0x03dd, "BanyanENS NetwareClient" }, + { 0x03de, "GuptaSequelBaseServer/NetWareSQL" }, + { 0x03e1, "UnivelUnixware" }, + { 0x03e4, "UnivelUnixware" }, + { 0x03fc, "IntelNetport" }, + { 0x03fd, "PrintServerQueue" }, + { 0x040A, "ipnServer" }, + { 0x040D, "LVERRMAN" }, + { 0x040E, "LVLIC" }, + { 0x0414, "NET Silicon (DPI)/Kyocera" }, + { 0x0429, "SiteLockVirus" }, + { 0x0432, "UFHELPR???" }, + { 0x0433, "Synoptics281xAdvancedSNMPAgent" }, + { 0x0444, "MicrosoftNT SNA Server" }, + { 0x0448, "Oracle" }, + { 0x044c, "ARCserve5.01" }, + { 0x0457, "CanonGP55" }, + { 0x045a, "QMS Printers" }, + { 0x045b, "DellSCSI Array" }, + { 0x0491, "NetBlazerModems" }, + { 0x04ac, "OnTimeScheduler" }, + { 0x04b0, "CD-Net" }, + { 0x0513, "EmulexNQA" }, + { 0x0520, "SiteLockChecks" }, + { 0x0529, "SiteLockChecks" }, + { 0x052d, "CitrixOS2 AppServer" }, + { 0x0535, "Tektronix" }, + { 0x0536, "Milan" }, + { 0x055d, "Attachmate SNA gateway" }, + { 0x056b, "IBM8235 ModemServer" }, + { 0x056c, "ShivaLanRover/E PLUS" }, + { 0x056d, "ShivaLanRover/T PLUS" }, + { 0x0580, "McAfeeNetShield" }, + { 0x05B8, "NLM to workstation communication (Revelation Software)" }, + { 0x05BA, "CompatibleSystemsRouters" }, + { 0x05BE, "CheyenneHierarchicalStorageManager" }, + { 0x0606, "JCWatermarkImaging" }, + { 0x060c, "AXISNetworkPrinter" }, + { 0x0610, "AdaptecSCSIManagement" }, + { 0x0621, "IBM AntiVirus" }, + { 0x0640, "Windows95 RemoteRegistryService" }, + { 0x064e, "MicrosoftIIS" }, + { 0x067b, "Microsoft Win95/98 File and Print Sharing for NetWare" }, + { 0x067c, "Microsoft Win95/98 File and Print Sharing for NetWare" }, + { 0x076C, "Xerox" }, + { 0x079b, "ShivaLanRover/E 115" }, + { 0x079c, "ShivaLanRover/T 115" }, + { 0x07B4, "CubixWorldDesk" }, + { 0x07c2, "Quarterdeck IWare Connect V2.x NLM" }, + { 0x07c1, "Quarterdeck IWare Connect V3.x NLM" }, + { 0x0810, "ELAN License Server Demo" }, + { 0x0824, "ShivaLanRoverAccessSwitch/E" }, + { 0x086a, "ISSC Collector" }, + { 0x087f, "ISSC DAS AgentAIX" }, + { 0x0880, "Intel Netport PRO" }, + { 0x0881, "Intel Netport PRO" }, + { 0x0b29, "SiteLock" }, + { 0x0c29, "SiteLockApplications" }, + { 0x0c2c, "LicensingServer" }, + { 0x2101, "PerformanceTechnologyInstantInternet" }, + { 0x2380, "LAI SiteLock" }, + { 0x238c, "MeetingMaker" }, + { 0x4808, "SiteLockServer/SiteLockMetering" }, + { 0x5555, "SiteLockUser" }, + { 0x6312, "Tapeware" }, + { 0x6f00, "RabbitGateway" }, + { 0x7703, "MODEM" }, + { 0x8002, "NetPortPrinters" }, + { 0x8008, "WordPerfectNetworkVersion" }, + { 0x85BE, "Cisco EIGRP" }, + { 0x8888, "WordPerfectNetworkVersion/QuickNetworkManagement" }, + { 0x9000, "McAfeeNetShield" }, + { 0x9604, "CSA-NT_MON" }, + { 0xb6a8, "OceanIsleReachoutRemoteControl" }, + { 0xf11f, "SiteLockMetering" }, + { 0xf1ff, "SiteLock" }, + { 0xf503, "Microsoft SQL Server" }, + { 0xF905, "IBM TimeAndPlace" }, + { 0xfbfb, "TopCallIII FaxServer" }, + { 0xffff, "AnyService/Wildcard" }, + { 0, (char *)0 } +}; + +static void +init_ipxsaparray(void) +{ + register int i; + register struct hnamemem *table; + + for (i = 0; ipxsap_db[i].s != NULL; i++) { + int j = htons(ipxsap_db[i].v) & (HASHNAMESIZE-1); + table = &ipxsaptable[j]; + while (table->name) + table = table->nxt; + table->name = ipxsap_db[i].s; + table->addr = htons(ipxsap_db[i].v); + table->nxt = newhnamemem(); + } +} + /* * Initialize the address to name translation machinery. We map all * non-local IP addresses to numeric addresses if fflag is true (i.e., @@ -845,7 +1119,6 @@ init_llcsaparray(void) void init_addrtoname(u_int32_t localnet, u_int32_t mask) { - netmask = mask; if (fflag) { f_localnet = localnet; f_netmask = mask; @@ -861,6 +1134,7 @@ init_addrtoname(u_int32_t localnet, u_int32_t mask) init_eprotoarray(); init_llcsaparray(); init_protoidarray(); + init_ipxsaparray(); } const char * diff --git a/contrib/tcpdump/ethertype.h b/contrib/tcpdump/ethertype.h index caff25790a35..63c0c291e0f6 100644 --- a/contrib/tcpdump/ethertype.h +++ b/contrib/tcpdump/ethertype.h @@ -18,7 +18,7 @@ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * @(#) $Header: /tcpdump/master/tcpdump/ethertype.h,v 1.16 2001/06/21 17:56:02 itojun Exp $ (LBL) + * @(#) $Header: /tcpdump/master/tcpdump/ethertype.h,v 1.20 2003/07/01 19:10:26 guy Exp $ (LBL) * * $FreeBSD$ */ @@ -71,9 +71,6 @@ #ifndef ETHERTYPE_SCA #define ETHERTYPE_SCA 0x6007 #endif -#ifndef ETHERTYPE_REVARP -#define ETHERTYPE_REVARP 0x8035 -#endif #ifndef ETHERTYPE_LANBRIDGE #define ETHERTYPE_LANBRIDGE 0x8038 #endif @@ -128,3 +125,11 @@ #ifndef ETHERTYPE_LOOPBACK #define ETHERTYPE_LOOPBACK 0x9000 #endif +#ifndef ETHERTYPE_VMAN +#define ETHERTYPE_VMAN 0x9100 /* Extreme VMAN Protocol */ +#endif +#ifndef ETHERTYPE_ISO +#define ETHERTYPE_ISO 0xfefe /* nonstandard - used in Cisco HDLC encapsulation */ +#endif + +extern const struct tok ethertype_values[]; diff --git a/contrib/tcpdump/interface.h b/contrib/tcpdump/interface.h index ed1d53c52d16..a53e59fb37c6 100644 --- a/contrib/tcpdump/interface.h +++ b/contrib/tcpdump/interface.h @@ -18,7 +18,7 @@ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * @(#) $Header: /tcpdump/master/tcpdump/interface.h,v 1.178.4.2 2002/07/10 07:32:17 guy Exp $ (LBL) + * @(#) $Header: /tcpdump/master/tcpdump/interface.h,v 1.217.2.5 2004/03/17 19:47:48 guy Exp $ (LBL) * * $FreeBSD$ */ @@ -29,8 +29,6 @@ #ifdef HAVE_OS_PROTO_H #include "os-proto.h" #endif -#include <sys/types.h> -#include <sys/time.h> #ifndef HAVE___ATTRIBUTE__ #define __attribute__(x) @@ -61,6 +59,10 @@ extern size_t strlcpy(char *, const char *, size_t); extern char *strdup(const char *); #endif +#ifndef HAVE_STRSEP +extern char *strsep(char **, const char *); +#endif + struct tok { int v; /* value */ const char *s; /* string */ @@ -81,7 +83,7 @@ extern int uflag; /* Print undecoded NFS handles */ extern int vflag; /* verbose */ extern int xflag; /* print packet in hex */ extern int Xflag; /* print packet in hex/ascii */ - +extern int Aflag; /* print packet only in ascii observing TAB, LF, CR and SPACE as graphical chars */ extern char *espsecret; extern int packettype; /* as specified by -T */ @@ -92,6 +94,8 @@ extern int packettype; /* as specified by -T */ #define PT_RTCP 5 /* Real-Time Applications control protocol */ #define PT_SNMP 6 /* Simple Network Management Protocol */ #define PT_CNFP 7 /* Cisco NetFlow protocol */ +#define PT_TFTP 8 /* trivial file transfer protocol */ +#define PT_AODV 9 /* Ad-hoc On-demand Distance Vector Protocol */ #ifndef min #define min(a,b) ((a)>(b)?(b):(a)) @@ -131,8 +135,7 @@ extern char *program_name; /* used to generate self-identifying messages */ extern int32_t thiszone; /* seconds offset from gmt to local time */ extern int snaplen; -/* global pointers to beginning and end of current packet (during printing) */ -extern const u_char *packetp; +/* global pointer to end of current packet (during printing) */ extern const u_char *snapend; /* @@ -161,15 +164,13 @@ extern void relts_print(int); extern int fn_print(const u_char *, const u_char *); extern int fn_printn(const u_char *, u_int, const u_char *); extern const char *tok2str(const struct tok *, const char *, int); +extern int mask2plen(u_int32_t); +extern char *bittok2str(const struct tok *, const char *, int); extern const char *tok2strary_internal(const char **, int, const char *, int); #define tok2strary(a,f,i) tok2strary_internal(a, sizeof(a)/sizeof(a[0]),f,i) extern const char *dnaddr_string(u_short); -extern void info(int); -extern int infodelay; -extern int infoprint; - extern void error(const char *, ...) __attribute__((noreturn, format (printf, 1, 2))); extern void warning(const char *, ...) __attribute__ ((format (printf, 1, 2))); @@ -191,92 +192,101 @@ extern const char *dnnum_string(u_short); #include <pcap.h> -extern void ascii_print_with_offset(const u_char *, u_int, u_int); -extern void ascii_print(const u_char *, u_int); -extern void hex_print_with_offset(const u_char *, u_int, u_int); -extern void telnet_print(const u_char *, u_int); -extern void hex_print(const u_char *, u_int); +extern int print_unknown_data(const u_char *, const char *,int); +extern void ascii_print_with_offset(const u_char *, const u_char *, u_int, u_int); +extern void ascii_print(const u_char *, const u_char *, u_int); +extern void hex_print_with_offset(const u_char *, const u_char *, u_int, u_int); +extern void telnet_print(const u_char *, u_int); +extern void hex_print(const u_char *, const u_char *, u_int); extern int ether_encap_print(u_short, const u_char *, u_int, u_int, u_short *); extern int llc_print(const u_char *, u_int, u_int, const u_char *, const u_char *, u_short *); +extern int snap_print(const u_char *, u_int, u_int, u_short *, u_int32_t, + u_short, u_int); extern void aarp_print(const u_char *, u_int); +extern void aodv_print(const u_char *, u_int, int); extern void arp_print(const u_char *, u_int, u_int); extern void atalk_print(const u_char *, u_int); -extern void atm_if_print(u_char *, const struct pcap_pkthdr *, const u_char *); -extern void bootp_print(const u_char *, u_int, u_short, u_short); +extern void atm_print(u_int, u_int, u_int, const u_char *, u_int, u_int); +extern u_int atm_if_print(const struct pcap_pkthdr *, const u_char *); +extern u_int sunatm_if_print(const struct pcap_pkthdr *, const u_char *); +extern void bootp_print(const u_char *, u_int); extern void bgp_print(const u_char *, int); extern void beep_print(const u_char *, u_int); -extern void cnfp_print(const u_char *, u_int, const u_char *); +extern void cnfp_print(const u_char *, const u_char *); extern void decnet_print(const u_char *, u_int, u_int); extern void default_print(const u_char *, u_int); extern void default_print_unaligned(const u_char *, u_int); extern void dvmrp_print(const u_char *, u_int); -extern void egp_print(const u_char *, u_int, const u_char *); -extern void arcnet_if_print(u_char *, const struct pcap_pkthdr *, - const u_char *); -extern void ether_if_print(u_char *, const struct pcap_pkthdr *, - const u_char *); -extern void token_if_print(u_char *, const struct pcap_pkthdr *, - const u_char *); -extern void fddi_if_print(u_char *, const struct pcap_pkthdr *, const u_char *); -extern void ieee802_11_if_print(u_char *, const struct pcap_pkthdr *, +extern void egp_print(const u_char *); +extern u_int enc_if_print(const struct pcap_pkthdr *, const u_char *); +extern u_int pflog_if_print(const struct pcap_pkthdr *, const u_char *); +extern u_int arcnet_if_print(const struct pcap_pkthdr *, const u_char *); +extern u_int arcnet_linux_if_print(const struct pcap_pkthdr *, const u_char *); +extern void ether_print(const u_char *, u_int, u_int); +extern u_int ether_if_print(const struct pcap_pkthdr *, const u_char *); +extern u_int token_print(const u_char *, u_int, u_int); +extern u_int token_if_print(const struct pcap_pkthdr *, const u_char *); +extern void fddi_print(const u_char *, u_int, u_int); +extern u_int fddi_if_print(const struct pcap_pkthdr *, const u_char *); +extern u_int fr_if_print(const struct pcap_pkthdr *, const u_char *); +extern u_int ieee802_11_if_print(const struct pcap_pkthdr *, const u_char *); +extern u_int ieee802_11_radio_if_print(const struct pcap_pkthdr *, const u_char *); +extern u_int ap1394_if_print(const struct pcap_pkthdr *, const u_char *); extern void gre_print(const u_char *, u_int); -extern void icmp_print(const u_char *, u_int, const u_char *); +extern void icmp_print(const u_char *, u_int, const u_char *, int); extern void igmp_print(const u_char *, u_int); extern void igrp_print(const u_char *, u_int, const u_char *); extern void ip_print(const u_char *, u_int); extern void ipN_print(const u_char *, u_int); +extern u_int ipfc_if_print(const struct pcap_pkthdr *, const u_char *); extern void ipx_print(const u_char *, u_int); -extern void isoclns_print(const u_char *, u_int, u_int, const u_char *, - const u_char *); -extern void krb_print(const u_char *, u_int); -extern void llap_print(const u_char *, u_int); -extern void ltalk_if_print(u_char *, const struct pcap_pkthdr *, - const u_char *); +extern void isoclns_print(const u_char *, u_int, u_int); +extern void krb_print(const u_char *); +extern u_int llap_print(const u_char *, u_int); +extern u_int ltalk_if_print(const struct pcap_pkthdr *, const u_char *); extern void msdp_print(const unsigned char *, u_int); extern void nfsreply_print(const u_char *, u_int, const u_char *); extern void nfsreq_print(const u_char *, u_int, const u_char *); -extern void ns_print(const u_char *, u_int); +extern void ns_print(const u_char *, u_int, int); extern void ntp_print(const u_char *, u_int); -extern void null_if_print(u_char *, const struct pcap_pkthdr *, const u_char *); +extern u_int null_if_print(const struct pcap_pkthdr *, const u_char *); extern void ospf_print(const u_char *, u_int, const u_char *); extern void pimv1_print(const u_char *, u_int); extern void cisco_autorp_print(const u_char *, u_int); +extern void rsvp_print(const u_char *, u_int); +extern void ldp_print(const u_char *, u_int); extern void mobile_print(const u_char *, u_int); extern void pim_print(const u_char *, u_int); -extern void pppoe_print(const u_char *, u_int); -extern void ppp_print(register const u_char *, u_int); -extern void ppp_if_print(u_char *, const struct pcap_pkthdr *, const u_char *); -extern void ppp_hdlc_if_print(u_char *, const struct pcap_pkthdr *, - const u_char *); -extern void ppp_bsdos_if_print(u_char *, const struct pcap_pkthdr *, - const u_char *); -extern void pppoe_if_print(u_char *, const struct pcap_pkthdr *, - const u_char *); -extern int vjc_print(register const char *, register u_int, u_short); -extern void raw_if_print(u_char *, const struct pcap_pkthdr *, const u_char *); +extern u_int pppoe_print(const u_char *, u_int); +extern u_int ppp_print(register const u_char *, u_int); +extern u_int ppp_if_print(const struct pcap_pkthdr *, const u_char *); +extern u_int ppp_hdlc_if_print(const struct pcap_pkthdr *, const u_char *); +extern u_int ppp_bsdos_if_print(const struct pcap_pkthdr *, const u_char *); +extern u_int pppoe_if_print(const struct pcap_pkthdr *, const u_char *); +extern u_int prism_if_print(const struct pcap_pkthdr *, const u_char *); +extern int vjc_print(register const char *, u_short); +extern u_int raw_if_print(const struct pcap_pkthdr *, const u_char *); extern void rip_print(const u_char *, u_int); -extern void sl_if_print(u_char *, const struct pcap_pkthdr *, const u_char *); -extern void lane_if_print(u_char *, const struct pcap_pkthdr *,const u_char *); -extern void cip_if_print(u_char *, const struct pcap_pkthdr *,const u_char *); -extern void sl_bsdos_if_print(u_char *, const struct pcap_pkthdr *, - const u_char *); -extern void chdlc_if_print(u_char *, const struct pcap_pkthdr *, - const u_char *); -extern void chdlc_print(register const u_char *, u_int, u_int); -extern void sll_if_print(u_char *, const struct pcap_pkthdr *, const u_char *); +extern u_int sl_if_print(const struct pcap_pkthdr *, const u_char *); +extern void lane_print(const u_char *, u_int, u_int); +extern u_int lane_if_print(const struct pcap_pkthdr *, const u_char *); +extern u_int cip_if_print(const struct pcap_pkthdr *, const u_char *); +extern u_int sl_bsdos_if_print(const struct pcap_pkthdr *, const u_char *); +extern u_int chdlc_if_print(const struct pcap_pkthdr *, const u_char *); +extern u_int sll_if_print(const struct pcap_pkthdr *, const u_char *); extern void snmp_print(const u_char *, u_int); extern void sunrpcrequest_print(const u_char *, u_int, const u_char *); extern void tcp_print(const u_char *, u_int, const u_char *, int); extern void tftp_print(const u_char *, u_int); -extern void timed_print(const u_char *, u_int); +extern void timed_print(const u_char *); extern void udp_print(const u_char *, u_int, const u_char *, int); extern void wb_print(const void *, u_int); -extern int ah_print(register const u_char *, register const u_char *); +extern int ah_print(register const u_char *); extern int esp_print(register const u_char *, register const u_char *, int *, int *); extern void isakmp_print(const u_char *, u_int, const u_char *); -extern int ipcomp_print(register const u_char *, register const u_char *, int *); +extern int ipcomp_print(register const u_char *, int *); extern void rx_print(register const u_char *, int, int, int, u_char *); extern void netbeui_print(u_short, const u_char *, int); extern void ipx_netbios_print(const u_char *, u_int); @@ -286,18 +296,18 @@ extern void nbt_udp138_print(const u_char *, int); extern char *smb_errstr(int, int); extern void print_data(const unsigned char *, int); extern void l2tp_print(const u_char *, u_int); -extern void lcp_print(const u_char *, u_int); extern void vrrp_print(const u_char *, u_int, int); -extern void cdp_print(const u_char *, u_int, u_int, const u_char *, - const u_char *); +extern void cdp_print(const u_char *, u_int, u_int); extern void stp_print(const u_char *, u_int); extern void radius_print(const u_char *, u_int); extern void lwres_print(const u_char *, u_int); -extern void pptp_print(const u_char *, u_int); +extern void pptp_print(const u_char *); extern void sctp_print(const u_char *, const u_char *, u_int); extern void mpls_print(const u_char *, u_int); +extern void mpls_lsp_ping_print(const u_char *, u_int); extern void zephyr_print(const u_char *, int); extern void hsrp_print(const u_char *, u_int); +extern void bfd_print(const u_char *, u_int, u_int); #ifdef INET6 extern void ip6_print(const u_char *, u_int); @@ -305,13 +315,15 @@ extern void ip6_opt_print(const u_char *, int); extern int hbhopt_print(const u_char *); extern int dstopt_print(const u_char *); extern int frag6_print(const u_char *, const u_char *); -extern void icmp6_print(const u_char *, const u_char *); +extern int mobility_print(const u_char *, const u_char *); +extern void icmp6_print(const u_char *, u_int, const u_char *, int); extern void ripng_print(const u_char *, unsigned 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_int16_t, u_int16_t); +extern void dhcp6_print(const u_char *, u_int); #endif /*INET6*/ extern u_short in_cksum(const u_short *, register u_int, int); +extern u_int16_t in_cksum_shouldbe(u_int16_t, u_int16_t); #ifndef HAVE_BPF_DUMP struct bpf_program; diff --git a/contrib/tcpdump/nfs.h b/contrib/tcpdump/nfs.h index 074d5ee86b7a..82c8dd3f1f95 100644 --- a/contrib/tcpdump/nfs.h +++ b/contrib/tcpdump/nfs.h @@ -1,3 +1,4 @@ +/* @(#) $Header: /tcpdump/master/tcpdump/nfs.h,v 1.7 2002/12/11 07:13:55 guy Exp $ (LBL) */ /* $NetBSD: nfs.h,v 1.1 1996/05/23 22:49:53 fvdl Exp $ */ /* diff --git a/contrib/tcpdump/nfsfh.h b/contrib/tcpdump/nfsfh.h index 6b6a3953f4a1..8a337ba156ec 100644 --- a/contrib/tcpdump/nfsfh.h +++ b/contrib/tcpdump/nfsfh.h @@ -1,4 +1,4 @@ -/* @(#) $Header: /tcpdump/master/tcpdump/nfsfh.h,v 1.12 2001/09/17 21:57:52 fenner Exp $ (LBL) */ +/* @(#) $Header: /tcpdump/master/tcpdump/nfsfh.h,v 1.13 2002/04/24 06:27:05 guy Exp $ (LBL) */ /* * Copyright (c) 1993, 1994 Jeffrey C. Mogul, Digital Equipment Corporation, @@ -67,4 +67,4 @@ typedef struct { #define fsid_eq(a,b) ((a.fsid_code == b.fsid_code) &&\ dev_eq(a.Fsid_dev, b.Fsid_dev)) -extern void Parse_fh(caddr_t *, int, my_fsid *, ino_t *, const char **, const char **, int); +extern void Parse_fh(const unsigned char *, int, my_fsid *, ino_t *, const char **, const char **, int); diff --git a/contrib/tcpdump/parsenfsfh.c b/contrib/tcpdump/parsenfsfh.c index f93321f703e6..c81803251cca 100644 --- a/contrib/tcpdump/parsenfsfh.c +++ b/contrib/tcpdump/parsenfsfh.c @@ -43,18 +43,16 @@ */ #ifndef lint -static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/parsenfsfh.c,v 1.23 2001/09/17 21:57:53 fenner Exp $ (LBL)"; +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/parsenfsfh.c,v 1.25.2.2 2003/11/16 08:51:07 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include <sys/types.h> -#include <sys/time.h> +#include <tcpdump-stdinc.h> -#include <ctype.h> #include <stdio.h> #include <string.h> @@ -110,11 +108,11 @@ static const char rcsid[] = ((lsb) + ((e)<<8) + ((d)<<16) + ((c)<<24)) #endif -static int is_UCX(unsigned char *); +static int is_UCX(const unsigned char *); void Parse_fh(fh, len, fsidp, inop, osnamep, fsnamep, ourself) -register caddr_t *fh; +register const unsigned char *fh; int len; my_fsid *fsidp; ino_t *inop; @@ -122,7 +120,7 @@ const char **osnamep; /* if non-NULL, return OS name here */ const char **fsnamep; /* if non-NULL, return server fs name here (for VMS) */ int ourself; /* true if file handle was generated on this host */ { - register unsigned char *fhp = (unsigned char *)fh; + register const unsigned char *fhp = fh; u_int32_t temp; int fhtype = FHT_UNKNOWN; int i; @@ -438,7 +436,7 @@ int ourself; /* true if file handle was generated on this host */ */ static int is_UCX(fhp) -unsigned char *fhp; +const unsigned char *fhp; { register int i; int seen_null = 0; diff --git a/contrib/tcpdump/ppp.h b/contrib/tcpdump/ppp.h index 6c7262d55eb5..6c69ce83eba4 100644 --- a/contrib/tcpdump/ppp.h +++ b/contrib/tcpdump/ppp.h @@ -1,4 +1,4 @@ -/* @(#) $Header: /tcpdump/master/tcpdump/ppp.h,v 1.12 2001/02/04 02:17:55 fenner Exp $ (LBL) */ +/* @(#) $Header: /tcpdump/master/tcpdump/ppp.h,v 1.14 2003/05/22 15:29:22 hannes Exp $ (LBL) */ /* * Point to Point Protocol (PPP) RFC1331 * @@ -46,6 +46,8 @@ #define PPP_HELLO 0x0201 /* 802.1d Hello Packets */ #define PPP_LUXCOM 0x0231 /* Luxcom */ #define PPP_SNS 0x0233 /* Sigma Network Systems */ +#define PPP_MPLS_UCAST 0x0281 /* rfc 3032 */ +#define PPP_MPLS_MCAST 0x0283 /* rfc 3022 */ #define PPP_IPCP 0x8021 /* IP Control Protocol */ #define PPP_OSICP 0x8023 /* OSI Network Layer Control Protocol */ @@ -57,13 +59,17 @@ #define PPP_VINESCP 0x8035 /* Banyan Vines Control Protocol */ #define PPP_IPV6CP 0x8057 /* IPv6 Control Protocol */ #define PPP_CCP 0x80fd /* Compress Control Protocol */ +#define PPP_MPLSCP 0x8281 /* rfc 3022 */ #define PPP_LCP 0xc021 /* Link Control Protocol */ #define PPP_PAP 0xc023 /* Password Authentication Protocol */ #define PPP_LQM 0xc025 /* Link Quality Monitoring */ +#define PPP_SPAP 0xc027 #define PPP_CHAP 0xc223 /* Challenge Handshake Authentication Protocol */ #define PPP_BACP 0xc02b /* Bandwidth Allocation Control Protocol */ #define PPP_BAP 0xc02d /* BAP */ #define PPP_MP 0xc03d /* Multi-Link */ +#define PPP_SPAP_OLD 0xc123 +#define PPP_EAP 0xc227 extern struct tok ppptype2str[]; diff --git a/contrib/tcpdump/print-arp.c b/contrib/tcpdump/print-arp.c index a3aec16159c3..e56df75eeaa4 100644 --- a/contrib/tcpdump/print-arp.c +++ b/contrib/tcpdump/print-arp.c @@ -22,18 +22,15 @@ */ #ifndef lint -static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/print-arp.c,v 1.51.4.2 2002/07/10 07:09:53 guy Exp $ (LBL)"; +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-arp.c,v 1.61.2.2 2003/11/16 08:51:10 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include <sys/param.h> -#include <sys/time.h> - -#include <netinet/in.h> +#include <tcpdump-stdinc.h> #include <stdio.h> #include <string.h> @@ -90,18 +87,169 @@ struct arp_pkthdr { #define ARP_HDRLEN 8 -#define HRD(ap) ((ap)->ar_hrd) +#define HRD(ap) EXTRACT_16BITS(&(ap)->ar_hrd) #define HLN(ap) ((ap)->ar_hln) #define PLN(ap) ((ap)->ar_pln) -#define OP(ap) ((ap)->ar_op) -#define PRO(ap) ((ap)->ar_pro) +#define OP(ap) EXTRACT_16BITS(&(ap)->ar_op) +#define PRO(ap) EXTRACT_16BITS(&(ap)->ar_pro) #define SHA(ap) (ar_sha(ap)) #define SPA(ap) (ar_spa(ap)) #define THA(ap) (ar_tha(ap)) #define TPA(ap) (ar_tpa(ap)) +/* + * ATM Address Resolution Protocol. + * + * See RFC 2225 for protocol description. ATMARP packets are similar + * to ARP packets, except that there are no length fields for the + * protocol address - instead, there are type/length fields for + * the ATM number and subaddress - and the hardware addresses consist + * of an ATM number and an ATM subaddress. + */ +struct atmarp_pkthdr { + u_short aar_hrd; /* format of hardware address */ +#define ARPHRD_ATM2225 19 /* ATM (RFC 2225) */ + u_short aar_pro; /* format of protocol address */ + u_char aar_shtl; /* length of source ATM number */ + u_char aar_sstl; /* length of source ATM subaddress */ +#define ATMARP_IS_E164 0x40 /* bit in type/length for E.164 format */ +#define ATMARP_LEN_MASK 0x3F /* length of {sub}address in type/length */ + u_short aar_op; /* same as regular ARP */ +#define ATMARPOP_NAK 10 /* NAK */ + u_char aar_spln; /* length of source protocol address */ + u_char aar_thtl; /* length of target ATM number */ + u_char aar_tstl; /* length of target ATM subaddress */ + u_char aar_tpln; /* length of target protocol address */ +/* + * The remaining fields are variable in size, + * according to the sizes above. + */ +#ifdef COMMENT_ONLY + u_char aar_sha[]; /* source ATM number */ + u_char aar_ssa[]; /* source ATM subaddress */ + u_char aar_spa[]; /* sender protocol address */ + u_char aar_tha[]; /* target ATM number */ + u_char aar_tsa[]; /* target ATM subaddress */ + u_char aar_tpa[]; /* target protocol address */ +#endif + +#define ATMHRD(ap) EXTRACT_16BITS(&(ap)->aar_hrd) +#define ATMSHLN(ap) ((ap)->aar_shtl & ATMARP_LEN_MASK) +#define ATMSSLN(ap) ((ap)->aar_sstl & ATMARP_LEN_MASK) +#define ATMSPLN(ap) ((ap)->aar_spln) +#define ATMOP(ap) EXTRACT_16BITS(&(ap)->aar_op) +#define ATMPRO(ap) EXTRACT_16BITS(&(ap)->aar_pro) +#define ATMTHLN(ap) ((ap)->aar_thtl & ATMARP_LEN_MASK) +#define ATMTSLN(ap) ((ap)->aar_tstl & ATMARP_LEN_MASK) +#define ATMTPLN(ap) ((ap)->aar_tpln) +#define aar_sha(ap) ((const u_char *)((ap)+1)) +#define aar_ssa(ap) (aar_sha(ap) + ATMSHLN(ap)) +#define aar_spa(ap) (aar_ssa(ap) + ATMSSLN(ap)) +#define aar_tha(ap) (aar_spa(ap) + ATMSPLN(ap)) +#define aar_tsa(ap) (aar_tha(ap) + ATMTHLN(ap)) +#define aar_tpa(ap) (aar_tsa(ap) + ATMTSLN(ap)) +}; + +#define ATMSHA(ap) (aar_sha(ap)) +#define ATMSSA(ap) (aar_ssa(ap)) +#define ATMSPA(ap) (aar_spa(ap)) +#define ATMTHA(ap) (aar_tha(ap)) +#define ATMTSA(ap) (aar_tsa(ap)) +#define ATMTPA(ap) (aar_tpa(ap)) + static u_char ezero[6]; +static void +atmarp_addr_print(const u_char *ha, u_int ha_len, const u_char *srca, + u_int srca_len) +{ + if (ha_len == 0) + (void)printf("<No address>"); + else { + (void)printf("%s", linkaddr_string(ha, ha_len)); + if (srca_len != 0) + (void)printf(",%s", linkaddr_string(srca, srca_len)); + } +} + +static void +atmarp_print(const u_char *bp, u_int length, u_int caplen) +{ + const struct atmarp_pkthdr *ap; + u_short pro, hrd, op; + + ap = (const struct atmarp_pkthdr *)bp; + TCHECK(*ap); + + hrd = ATMHRD(ap); + pro = ATMPRO(ap); + op = ATMOP(ap); + + if (!TTEST2(*aar_tpa(ap), ATMTPLN(ap))) { + (void)printf("truncated-atmarp"); + default_print((const u_char *)ap, length); + return; + } + + if ((pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL) || + ATMSPLN(ap) != 4 || ATMTPLN(ap) != 4) { + (void)printf("atmarp-#%d for proto #%d (%d/%d) hardware #%d", + op, pro, ATMSPLN(ap), ATMTPLN(ap), hrd); + return; + } + if (pro == ETHERTYPE_TRAIL) + (void)printf("trailer-"); + switch (op) { + + case ARPOP_REQUEST: + (void)printf("arp who-has %s", ipaddr_string(ATMTPA(ap))); + if (ATMTHLN(ap) != 0) { + (void)printf(" ("); + atmarp_addr_print(ATMTHA(ap), ATMTHLN(ap), + ATMTSA(ap), ATMTSLN(ap)); + (void)printf(")"); + } + (void)printf(" tell %s", ipaddr_string(ATMSPA(ap))); + break; + + case ARPOP_REPLY: + (void)printf("arp reply %s", ipaddr_string(ATMSPA(ap))); + (void)printf(" is-at "); + atmarp_addr_print(ATMSHA(ap), ATMSHLN(ap), ATMSSA(ap), + ATMSSLN(ap)); + break; + + case ARPOP_INVREQUEST: + (void)printf("invarp who-is "); + atmarp_addr_print(ATMTHA(ap), ATMTHLN(ap), ATMTSA(ap), + ATMTSLN(ap)); + (void)printf(" tell "); + atmarp_addr_print(ATMSHA(ap), ATMSHLN(ap), ATMSSA(ap), + ATMSSLN(ap)); + break; + + case ARPOP_INVREPLY: + (void)printf("invarp reply "); + atmarp_addr_print(ATMSHA(ap), ATMSHLN(ap), ATMSSA(ap), + ATMSSLN(ap)); + (void)printf(" at %s", ipaddr_string(ATMSPA(ap))); + break; + + case ATMARPOP_NAK: + (void)printf("nak reply for %s", + ipaddr_string(ATMSPA(ap))); + break; + + default: + (void)printf("atmarp-#%d", op); + default_print((const u_char *)ap, caplen); + return; + } + return; +trunc: + (void)printf("[|atmarp]"); +} + void arp_print(const u_char *bp, u_int length, u_int caplen) { @@ -110,17 +258,22 @@ arp_print(const u_char *bp, u_int length, u_int caplen) ap = (const struct arp_pkthdr *)bp; TCHECK(*ap); - if ((const u_char *)(ar_tpa(ap) + PLN(ap)) > snapend) { + hrd = HRD(ap); + if (hrd == ARPHRD_ATM2225) { + atmarp_print(bp, length, caplen); + return; + } + pro = PRO(ap); + op = OP(ap); + + if (!TTEST2(*ar_tpa(ap), PLN(ap))) { (void)printf("truncated-arp"); default_print((const u_char *)ap, length); return; } - pro = EXTRACT_16BITS(&PRO(ap)); - hrd = EXTRACT_16BITS(&HRD(ap)); - op = EXTRACT_16BITS(&OP(ap)); - - if (pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL) { + if ((pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL) || + PLN(ap) != 4 || HLN(ap) == 0) { (void)printf("arp-#%d for proto #%d (%d) hardware #%d (%d)", op, pro, PLN(ap), hrd, HLN(ap)); return; @@ -154,6 +307,18 @@ arp_print(const u_char *bp, u_int length, u_int caplen) ipaddr_string(TPA(ap))); break; + case ARPOP_INVREQUEST: + (void)printf("invarp who-is %s tell %s", + linkaddr_string(THA(ap), HLN(ap)), + linkaddr_string(SHA(ap), HLN(ap))); + break; + + case ARPOP_INVREPLY: + (void)printf("invarp reply %s at %s", + linkaddr_string(THA(ap), HLN(ap)), + ipaddr_string(TPA(ap))); + break; + default: (void)printf("arp-#%d", op); default_print((const u_char *)ap, caplen); diff --git a/contrib/tcpdump/print-atalk.c b/contrib/tcpdump/print-atalk.c index 3b1104f12daf..ce6178ad90dd 100644 --- a/contrib/tcpdump/print-atalk.c +++ b/contrib/tcpdump/print-atalk.c @@ -24,24 +24,19 @@ */ #ifndef lint -static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/print-atalk.c,v 1.70.2.1 2002/02/05 10:04:18 guy Exp $ (LBL)"; +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-atalk.c,v 1.78.2.2 2003/11/16 08:51:11 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include <sys/param.h> -#include <sys/time.h> -#include <sys/socket.h> - -#include <netinet/in.h> +#include <tcpdump-stdinc.h> #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <netdb.h> /* for MAXHOSTNAMELEN on some platforms */ #include <pcap.h> #include "interface.h" @@ -88,31 +83,23 @@ static const char *ddpskt_string(int); /* * Print LLAP packets received on a physical LocalTalk interface. */ -void -ltalk_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) +u_int +ltalk_if_print(const struct pcap_pkthdr *h, const u_char *p) { - snapend = p + h->caplen; - ++infodelay; - ts_print(&h->ts); - llap_print(p, h->caplen); - if(xflag) - default_print(p, h->caplen); - putchar('\n'); - --infodelay; - if (infoprint) - info(0); + return (llap_print(p, h->caplen)); } /* * Print AppleTalk LLAP packets. */ -void +u_int llap_print(register const u_char *bp, u_int length) { register const struct LAP *lp; register const struct atDDP *dp; register const struct atShortDDP *sdp; u_short snet; + u_int hdrlen; #if 0 /* @@ -132,12 +119,13 @@ llap_print(register const u_char *bp, u_int length) lp = &lp_; } #endif + hdrlen = sizeof(*lp); switch (lp->type) { case lapShortDDP: if (length < ddpSSize) { (void)printf(" [|sddp %d]", length); - return; + return (length); } sdp = (const struct atShortDDP *)bp; printf("%s.%s", @@ -146,13 +134,14 @@ llap_print(register const u_char *bp, u_int length) ataddr_string(0, lp->dst), ddpskt_string(sdp->dstSkt)); bp += ddpSSize; length -= ddpSSize; + hdrlen += ddpSSize; ddp_print(bp, length, sdp->type, 0, lp->src, sdp->srcSkt); break; case lapDDP: if (length < ddpSize) { (void)printf(" [|ddp %d]", length); - return; + return (length); } dp = (const struct atDDP *)bp; snet = EXTRACT_16BITS(&dp->srcNet); @@ -163,6 +152,7 @@ llap_print(register const u_char *bp, u_int length) ddpskt_string(dp->dstSkt)); bp += ddpSize; length -= ddpSize; + hdrlen += ddpSize; ddp_print(bp, length, dp->type, snet, dp->srcNode, dp->srcSkt); break; @@ -177,6 +167,7 @@ llap_print(register const u_char *bp, u_int length) lp->src, lp->dst, lp->type, length); break; } + return (hdrlen); } /* @@ -203,21 +194,6 @@ atalk_print(register const u_char *bp, u_int length) ddpskt_string(dp->dstSkt)); bp += ddpSize; length -= ddpSize; -#ifdef LBL_ALIGN - if ((long)bp & 3) { - static u_char *abuf = NULL; - - if (abuf == NULL) { - abuf = (u_char *)malloc(snaplen); - if (abuf == NULL) - error("atalk_print: malloc"); - } - memcpy((char *)abuf, (char *)bp, min(length, snaplen)); - snapend += abuf - (u_char *)bp; - packetp = abuf; - bp = abuf; - } -#endif ddp_print(bp, length, dp->type, snet, dp->srcNode, dp->srcSkt); } @@ -231,9 +207,10 @@ aarp_print(register const u_char *bp, u_int length) printf("aarp "); ap = (const struct aarp *)bp; - if (ntohs(ap->htype) == 1 && ntohs(ap->ptype) == ETHERTYPE_ATALK && + if (EXTRACT_16BITS(&ap->htype) == 1 && + EXTRACT_16BITS(&ap->ptype) == ETHERTYPE_ATALK && ap->halen == 6 && ap->palen == 4 ) - switch (ntohs(ap->op)) { + switch (EXTRACT_16BITS(&ap->op)) { case 1: /* request */ (void)printf("who-has %s tell %s", @@ -251,8 +228,8 @@ aarp_print(register const u_char *bp, u_int length) return; } (void)printf("len %u op %u htype %u ptype %#x halen %u palen %u", - length, ntohs(ap->op), ntohs(ap->htype), ntohs(ap->ptype), - ap->halen, ap->palen); + length, EXTRACT_16BITS(&ap->op), EXTRACT_16BITS(&ap->htype), + EXTRACT_16BITS(&ap->ptype), ap->halen, ap->palen); } /* diff --git a/contrib/tcpdump/print-atm.c b/contrib/tcpdump/print-atm.c index 2090267f091f..549af0e8c6b7 100644 --- a/contrib/tcpdump/print-atm.c +++ b/contrib/tcpdump/print-atm.c @@ -21,144 +21,224 @@ * $FreeBSD$ */ #ifndef lint -static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/print-atm.c,v 1.21 2001/07/05 18:54:14 guy Exp $ (LBL)"; +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-atm.c,v 1.33.2.2 2003/11/16 08:51:11 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include <sys/param.h> -#include <sys/time.h> -#include <sys/socket.h> - -#include <netinet/in.h> +#include <tcpdump-stdinc.h> #include <stdio.h> #include <pcap.h> +#include <string.h> #include "interface.h" +#include "extract.h" #include "addrtoname.h" #include "ethertype.h" +#include "atm.h" +#include "atmuni31.h" +#include "llc.h" + +#include "ether.h" /* - * This is the top level routine of the printer. 'p' is the points - * to the LLC/SNAP header of the packet, 'tvp' is the timestamp, - * 'length' is the length of the packet off the wire, and 'caplen' + * Print an RFC 1483 LLC-encapsulated ATM frame. + */ +static void +atm_llc_print(const u_char *p, int length, int caplen) +{ + u_short extracted_ethertype; + + if (!llc_print(p, length, caplen, NULL, NULL, + &extracted_ethertype)) { + /* ether_type not known, print raw packet */ + if (extracted_ethertype) { + printf("(LLC %s) ", + etherproto_string(htons(extracted_ethertype))); + } + if (!xflag && !qflag) + default_print(p, caplen); + } +} + +/* + * Given a SAP value, generate the LLC header value for a UI packet + * with that SAP as the source and destination SAP. + */ +#define LLC_UI_HDR(sap) ((sap)<<16 | (sap<<8) | 0x03) + +/* + * This is the top level routine of the printer. 'p' points + * to the LLC/SNAP header of the packet, 'h->ts' is the timestamp, + * 'h->length' is the length of the packet off the wire, and 'h->caplen' * is the number of bytes actually captured. */ -void -atm_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) +u_int +atm_if_print(const struct pcap_pkthdr *h, const u_char *p) { u_int caplen = h->caplen; u_int length = h->len; - u_short ethertype, extracted_ethertype; - - ++infodelay; - ts_print(&h->ts); + u_int32_t llchdr; + u_int hdrlen = 0; if (caplen < 8) { printf("[|atm]"); - goto out; + return (caplen); } - - if (p[4] == 0xaa || p[5] == 0xaa || p[6] == 0x03) { - /* if first 4 bytes are cookie/vpci */ - if (eflag) { - printf("%04x ", - p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]); - } - p += 4; - length -= 4; - caplen -= 4; - } - else if (p[0] != 0xaa || p[1] != 0xaa || p[2] != 0x03) { - /*XXX assume 802.6 MAC header from fore driver */ + /* + * Extract the presumed LLC header into a variable, for quick + * testing. + * Then check for a header that's neither a header for a SNAP + * packet nor an RFC 2684 routed NLPID-formatted PDU nor + * an 802.2-but-no-SNAP IP packet. + */ + llchdr = EXTRACT_24BITS(p); + if (llchdr != LLC_UI_HDR(LLCSAP_SNAP) && + llchdr != LLC_UI_HDR(LLCSAP_ISONS) && + llchdr != LLC_UI_HDR(LLCSAP_IP)) { + /* + * XXX - assume 802.6 MAC header from Fore driver. + * + * Unfortunately, the above list doesn't check for + * all known SAPs, doesn't check for headers where + * the source and destination SAP aren't the same, + * and doesn't check for non-UI frames. It also + * runs the risk of an 802.6 MAC header that happens + * to begin with one of those values being + * incorrectly treated as an 802.2 header. + * + * So is that Fore driver still around? And, if so, + * is it still putting 802.6 MAC headers on ATM + * packets? If so, could it be changed to use a + * new DLT_IEEE802_6 value if we added it? + */ if (eflag) - printf("%04x%04x %04x%04x ", - p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3], - p[4] << 24 | p[5] << 16 | p[6] << 8 | p[7], - p[8] << 24 | p[9] << 16 | p[10] << 8 | p[11], - p[12] << 24 | p[13] << 16 | p[14] << 8 | p[15]); + printf("%08x%08x %08x%08x ", + EXTRACT_32BITS(p), + EXTRACT_32BITS(p+4), + EXTRACT_32BITS(p+8), + EXTRACT_32BITS(p+12)); p += 20; length -= 20; caplen -= 20; + hdrlen += 20; + } + atm_llc_print(p, length, caplen); + return (hdrlen); +} + +/* + * ATM signalling. + */ +static struct tok msgtype2str[] = { + { CALL_PROCEED, "Call_proceeding" }, + { CONNECT, "Connect" }, + { CONNECT_ACK, "Connect_ack" }, + { SETUP, "Setup" }, + { RELEASE, "Release" }, + { RELEASE_DONE, "Release_complete" }, + { RESTART, "Restart" }, + { RESTART_ACK, "Restart_ack" }, + { STATUS, "Status" }, + { STATUS_ENQ, "Status_enquiry" }, + { ADD_PARTY, "Add_party" }, + { ADD_PARTY_ACK, "Add_party_ack" }, + { ADD_PARTY_REJ, "Add_party_reject" }, + { DROP_PARTY, "Drop_party" }, + { DROP_PARTY_ACK, "Drop_party_ack" }, + { 0, NULL } +}; + +static void +sig_print(const u_char *p, int caplen) +{ + bpf_u_int32 call_ref; + + if (caplen < PROTO_POS) { + printf("[|atm]"); + return; } - ethertype = p[6] << 8 | p[7]; + if (p[PROTO_POS] == Q2931) { + /* + * protocol:Q.2931 for User to Network Interface + * (UNI 3.1) signalling + */ + printf("Q.2931"); + if (caplen < MSG_TYPE_POS) { + printf(" [|atm]"); + return; + } + printf(":%s ", + tok2str(msgtype2str, "msgtype#%d", p[MSG_TYPE_POS])); + + if (caplen < CALL_REF_POS+3) { + printf("[|atm]"); + return; + } + call_ref = EXTRACT_24BITS(&p[CALL_REF_POS]); + printf("CALL_REF:0x%06x", call_ref); + } else { + /* SCCOP with some unknown protocol atop it */ + printf("SSCOP, proto %d ", p[PROTO_POS]); + } +} + +/* + * Print an ATM PDU (such as an AAL5 PDU). + */ +void +atm_print(u_int vpi, u_int vci, u_int traftype, const u_char *p, u_int length, + u_int caplen) +{ if (eflag) - printf("%02x %02x %02x %02x-%02x-%02x %04x: ", - p[0], p[1], p[2], /* dsap/ssap/ctrl */ - p[3], p[4], p[5], /* manufacturer's code */ - ethertype); + printf("VPI:%u VCI:%u ", vpi, vci); - /* - * Some printers want to get back at the ethernet addresses, - * and/or check that they're not walking off the end of the packet. - * Rather than pass them all the way down, we set these globals. - */ - packetp = p; - snapend = p + caplen; + if (vpi == 0) { + switch (vci) { - length -= 8; - caplen -= 8; - p += 8; + case PPC: + sig_print(p, caplen); + return; - switch (ethertype) { + case BCC: + printf("broadcast sig: "); + return; - case ETHERTYPE_IP: - ip_print(p, length); - break; + case OAMF4SC: + printf("oamF4(segment): "); + return; -#ifdef INET6 - case ETHERTYPE_IPV6: - ip6_print(p, length); - break; -#endif /*INET6*/ + case OAMF4EC: + printf("oamF4(end): "); + return; - /*XXX this probably isn't right */ - case ETHERTYPE_ARP: - case ETHERTYPE_REVARP: - arp_print(p, length, caplen); - break; -#ifdef notyet - case ETHERTYPE_DN: - decnet_print(p, length, caplen); - break; + case METAC: + printf("meta: "); + return; - case ETHERTYPE_ATALK: - if (vflag) - fputs("et1 ", stdout); - atalk_print(p, length); - break; + case ILMIC: + printf("ilmi: "); + snmp_print(p, length); + return; + } + } - case ETHERTYPE_AARP: - aarp_print(p, length); - break; + switch (traftype) { - case ETHERTYPE_LAT: - case ETHERTYPE_MOPRC: - case ETHERTYPE_MOPDL: - /* default_print for now */ -#endif + case ATM_LLC: default: - /* ether_type not known, forward it to llc_print */ - if (!eflag) - printf("%02x %02x %02x %02x-%02x-%02x %04x: ", - packetp[0], packetp[1], packetp[2], /* dsap/ssap/ctrl */ - packetp[3], packetp[4], packetp[5], /* manufacturer's code */ - ethertype); - if (!xflag && !qflag) { - extracted_ethertype = 0; - /* default_print(p, caplen); */ - llc_print(p-8,length+8,caplen+8,"000000","000000", &extracted_ethertype); - } + /* + * Assumes traffic is LLC if unknown. + */ + atm_llc_print(p, length, caplen); + break; + + case ATM_LANE: + lane_print(p, length, caplen); + break; } - if (xflag) - default_print(p, caplen); - out: - putchar('\n'); - --infodelay; - if (infoprint) - info(0); } diff --git a/contrib/tcpdump/print-bootp.c b/contrib/tcpdump/print-bootp.c index c80ccd74d83c..aedda0cff946 100644 --- a/contrib/tcpdump/print-bootp.c +++ b/contrib/tcpdump/print-bootp.c @@ -23,21 +23,16 @@ * $FreeBSD$ */ #ifndef lint -static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/print-bootp.c,v 1.60.4.2 2002/06/01 23:51:11 guy Exp $ (LBL)"; +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-bootp.c,v 1.75.2.3 2004/03/02 07:45:13 hannes Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include <sys/param.h> -#include <sys/time.h> -#include <sys/socket.h> +#include <tcpdump-stdinc.h> -#include <netinet/in.h> - -#include <ctype.h> #include <stdio.h> #include <string.h> @@ -52,12 +47,22 @@ static void cmu_print(const u_char *); static char tstr[] = " [|bootp]"; +static const struct tok bootp_flag_values[] = { + { 0x8000, "Broadcast" }, + { 0, NULL} +}; + +static const struct tok bootp_op_values[] = { + { BOOTPREQUEST, "Request" }, + { BOOTPREPLY, "Reply" }, + { 0, NULL} +}; + /* * Print bootp requests */ void -bootp_print(register const u_char *cp, u_int length, - u_short sport, u_short dport) +bootp_print(register const u_char *cp, u_int length) { register const struct bootp *bp; static const u_char vm_cmu[4] = VM_CMU; @@ -65,84 +70,72 @@ bootp_print(register const u_char *cp, u_int length, bp = (const struct bootp *)cp; TCHECK(bp->bp_op); - switch (bp->bp_op) { - - case BOOTREQUEST: - /* Usually, a request goes from a client to a server */ - if (sport != IPPORT_BOOTPC || dport != IPPORT_BOOTPS) - printf(" (request)"); - break; - - case BOOTREPLY: - /* Usually, a reply goes from a server to a client */ - if (sport != IPPORT_BOOTPS || dport != IPPORT_BOOTPC) - printf(" (reply)"); - break; - - default: - printf(" bootp-#%d", bp->bp_op); + + printf("BOOTP/DHCP, %s", + tok2str(bootp_op_values, "unknown (0x%02x)", bp->bp_op)); + + if (bp->bp_htype == 1 && bp->bp_hlen == 6 && bp->bp_op == BOOTPREQUEST) { + TCHECK2(bp->bp_chaddr[0], 6); + printf(" from %s", etheraddr_string(bp->bp_chaddr)); } + printf(", length: %u", length); + + if (!vflag) + return; + TCHECK(bp->bp_secs); /* The usual hardware address type is 1 (10Mb Ethernet) */ if (bp->bp_htype != 1) - printf(" htype-#%d", bp->bp_htype); + printf(", htype-#%d", bp->bp_htype); /* The usual length for 10Mb Ethernet address is 6 bytes */ if (bp->bp_htype != 1 || bp->bp_hlen != 6) - printf(" hlen:%d", bp->bp_hlen); + printf(", hlen:%d", bp->bp_hlen); /* Only print interesting fields */ if (bp->bp_hops) - printf(" hops:%d", bp->bp_hops); + printf(", hops:%d", bp->bp_hops); if (bp->bp_xid) - printf(" xid:0x%x", (u_int32_t)ntohl(bp->bp_xid)); + printf(", xid:0x%x", EXTRACT_32BITS(&bp->bp_xid)); if (bp->bp_secs) - printf(" secs:%d", ntohs(bp->bp_secs)); - if (bp->bp_flags) - printf(" flags:0x%x", ntohs(bp->bp_flags)); + printf(", secs:%d", EXTRACT_16BITS(&bp->bp_secs)); + + printf(", flags: [%s]", + bittok2str(bootp_flag_values, "none", EXTRACT_16BITS(&bp->bp_flags))); + if (vflag>1) + printf( " (0x%04x)", EXTRACT_16BITS(&bp->bp_flags)); /* Client's ip address */ TCHECK(bp->bp_ciaddr); if (bp->bp_ciaddr.s_addr) - printf(" C:%s", ipaddr_string(&bp->bp_ciaddr)); + printf("\n\t Client IP: %s", ipaddr_string(&bp->bp_ciaddr)); /* 'your' ip address (bootp client) */ TCHECK(bp->bp_yiaddr); if (bp->bp_yiaddr.s_addr) - printf(" Y:%s", ipaddr_string(&bp->bp_yiaddr)); + printf("\n\t Your IP: %s", ipaddr_string(&bp->bp_yiaddr)); /* Server's ip address */ TCHECK(bp->bp_siaddr); if (bp->bp_siaddr.s_addr) - printf(" S:%s", ipaddr_string(&bp->bp_siaddr)); + printf("\n\t Server IP: %s", ipaddr_string(&bp->bp_siaddr)); /* Gateway's ip address */ TCHECK(bp->bp_giaddr); if (bp->bp_giaddr.s_addr) - printf(" G:%s", ipaddr_string(&bp->bp_giaddr)); + printf("\n\t Gateway IP: %s", ipaddr_string(&bp->bp_giaddr)); /* Client's Ethernet address */ if (bp->bp_htype == 1 && bp->bp_hlen == 6) { - register const struct ether_header *eh; - register const char *e; - TCHECK2(bp->bp_chaddr[0], 6); - eh = (const struct ether_header *)packetp; - if (bp->bp_op == BOOTREQUEST) - e = (const char *)ESRC(eh); - else if (bp->bp_op == BOOTREPLY) - e = (const char *)EDST(eh); - else - e = 0; - if (e == 0 || memcmp((const char *)bp->bp_chaddr, e, 6) != 0) - printf(" ether %s", etheraddr_string(bp->bp_chaddr)); + printf("\n\t Client Ethernet Address: %s", etheraddr_string(bp->bp_chaddr)); } TCHECK2(bp->bp_sname[0], 1); /* check first char only */ if (*bp->bp_sname) { - printf(" sname \""); + printf("\n\t sname \""); if (fn_print(bp->bp_sname, snapend)) { putchar('"'); fputs(tstr + 1, stdout); @@ -150,9 +143,9 @@ bootp_print(register const u_char *cp, u_int length, } putchar('"'); } - TCHECK2(bp->bp_sname[0], 1); /* check first char only */ + TCHECK2(bp->bp_file[0], 1); /* check first char only */ if (*bp->bp_file) { - printf(" file \""); + printf("\n\t file \""); if (fn_print(bp->bp_file, snapend)) { putchar('"'); fputs(tstr + 1, stdout); @@ -174,7 +167,7 @@ bootp_print(register const u_char *cp, u_int length, ul = EXTRACT_32BITS(&bp->bp_vend); if (ul != 0) - printf("vend-#0x%x", ul); + printf("\n\t Vendor-#0x%x", ul); } return; @@ -286,7 +279,7 @@ static struct tok tag2str[] = { { TAG_NS_SEARCH, "sNSSEARCH" }, /* XXX 's' */ /* RFC 3011 */ { TAG_IP4_SUBNET_SELECT, "iSUBNET" }, -/* ftp://ftp.isi.edu/.../assignments/bootp-dhcp-extensions */ +/* http://www.iana.org/assignments/bootp-dhcp-extensions/index.htm */ { TAG_USER_CLASS, "aCLASS" }, { TAG_SLP_NAMING_AUTH, "aSLP-NA" }, { TAG_CLIENT_FQDN, "$FQDN" }, @@ -357,7 +350,7 @@ rfc1048_print(register const u_char *bp) u_int16_t us; u_int8_t uc; - printf(" vend-rfc1048"); + printf("\n\t Vendor-rfc1048:"); /* Step over magic cookie */ bp += sizeof(int32_t); @@ -380,7 +373,7 @@ rfc1048_print(register const u_char *bp) } else cp = tok2str(tag2str, "?T%u", tag); c = *cp++; - printf(" %s:", cp); + printf("\n\t %s:", cp); /* Get the length; check for truncation */ if (bp + 1 >= snapend) { @@ -389,7 +382,7 @@ rfc1048_print(register const u_char *bp) } len = *bp++; if (bp + len >= snapend) { - fputs(tstr, stdout); + printf("[|bootp %u]", len); return; } @@ -565,6 +558,10 @@ rfc1048_print(register const u_char *bp) break; case TAG_CLIENT_FQDN: + /* option 81 should be at least 4 bytes long */ + if (len < 4) + printf("ERROR: options 81 len %u < 4 bytes", len); + break; if (*bp++) printf("[svrreg]"); if (*bp) @@ -582,8 +579,10 @@ rfc1048_print(register const u_char *bp) size--; if (type == 0) { putchar('"'); - (void)fn_printn(bp, size, NULL); + (void)fn_printn(bp, size, NULL); putchar('"'); + bp += size; + size = 0; break; } else { printf("[%s]", tok2str(arp2str, "type-%d", type)); @@ -609,8 +608,10 @@ rfc1048_print(register const u_char *bp) break; } /* Data left over? */ - if (size) + if (size) { printf("[len %u]", len); + bp += size; + } } return; trunc: diff --git a/contrib/tcpdump/print-domain.c b/contrib/tcpdump/print-domain.c index caabb1ac5619..0aaef01b6739 100644 --- a/contrib/tcpdump/print-domain.c +++ b/contrib/tcpdump/print-domain.c @@ -22,18 +22,15 @@ */ #ifndef lint -static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/print-domain.c,v 1.78 2001/10/19 09:00:48 guy Exp $ (LBL)"; +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-domain.c,v 1.86.2.3 2004/03/28 20:54:00 fenner Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include <sys/param.h> -#include <sys/time.h> - -#include <netinet/in.h> +#include <tcpdump-stdinc.h> #include "nameser.h" @@ -59,15 +56,16 @@ static const char *ns_resp[] = { /* skip over a domain name */ static const u_char * -ns_nskip(register const u_char *cp, register const u_char *bp) +ns_nskip(register const u_char *cp) { register u_char i; if (!TTEST2(*cp, 1)) return (NULL); - if (((i = *cp++) & INDIR_MASK) == INDIR_MASK) - return (cp + 1); + i = *cp++; while (i) { + if ((i & INDIR_MASK) == INDIR_MASK) + return (cp + 1); if ((i & INDIR_MASK) == EDNS0_MASK) { int bitlen, bytelen; @@ -93,7 +91,6 @@ static const u_char * blabel_print(const u_char *cp) { int bitlen, slen, b; - int truncated = 0; const u_char *bitp, *lim; char tc; @@ -102,27 +99,28 @@ blabel_print(const u_char *cp) if ((bitlen = *cp) == 0) bitlen = 256; slen = (bitlen + 3) / 4; - if ((lim = cp + 1 + slen) > snapend) { - truncated = 1; - lim = snapend; - } + lim = cp + 1 + slen; /* print the bit string as a hex string */ printf("\\[x"); - for (bitp = cp + 1, b = bitlen; bitp < lim && b > 7; b -= 8, bitp++) + for (bitp = cp + 1, b = bitlen; bitp < lim && b > 7; b -= 8, bitp++) { + TCHECK(*bitp); printf("%02x", *bitp); - if (bitp == lim) - printf("..."); - else if (b > 4) { + } + if (b > 4) { + TCHECK(*bitp); tc = *bitp++; printf("%02x", tc & (0xff << (8 - b))); } else if (b > 0) { + TCHECK(*bitp); tc = *bitp++; printf("%1x", ((tc >> 4) & 0x0f) & (0x0f << (4 - b))); } printf("/%d]", bitlen); - - return(truncated ? NULL : lim); + return lim; +trunc: + printf(".../%d]", bitlen); + return NULL; } static int @@ -157,7 +155,7 @@ ns_nprint(register const u_char *cp, register const u_char *bp) int elt; int data_size = snapend - bp; - if ((l = labellen(cp)) < 0) + if ((l = labellen(cp)) == (u_int)-1) return(NULL); if (!TTEST2(*cp, 1)) return(NULL); @@ -177,7 +175,7 @@ ns_nprint(register const u_char *cp, register const u_char *bp) if (!TTEST2(*cp, 1)) return(NULL); cp = bp + (((i << 8) | *cp) & 0x3fff); - if ((l = labellen(cp)) < 0) + if ((l = labellen(cp)) == (u_int)-1) return(NULL); if (!TTEST2(*cp, 1)) return(NULL); @@ -216,7 +214,7 @@ ns_nprint(register const u_char *cp, register const u_char *bp) cp += l; chars_processed += l; putchar('.'); - if ((l = labellen(cp)) < 0) + if ((l = labellen(cp)) == (u_int)-1) return(NULL); if (!TTEST2(*cp, 1)) return(NULL); @@ -232,7 +230,7 @@ ns_nprint(register const u_char *cp, register const u_char *bp) /* print a <character-string> */ static const u_char * -ns_cprint(register const u_char *cp, register const u_char *bp) +ns_cprint(register const u_char *cp) { register u_int i; @@ -244,56 +242,57 @@ ns_cprint(register const u_char *cp, register const u_char *bp) return (cp + i); } +/* http://www.iana.org/assignments/dns-parameters */ struct tok ns_type2str[] = { - { T_A, "A" }, - { T_NS, "NS" }, - { T_MD, "MD" }, - { T_MF, "MF" }, - { T_CNAME, "CNAME" }, - { T_SOA, "SOA" }, - { T_MB, "MB" }, - { T_MG, "MG" }, - { T_MR, "MR" }, - { T_NULL, "NULL" }, - { T_WKS, "WKS" }, - { T_PTR, "PTR" }, - { T_HINFO, "HINFO" }, - { T_MINFO, "MINFO" }, - { T_MX, "MX" }, - { T_TXT, "TXT" }, - { T_RP, "RP" }, - { T_AFSDB, "AFSDB" }, - { T_X25, "X25" }, - { T_ISDN, "ISDN" }, - { T_RT, "RT" }, - { T_NSAP, "NSAP" }, + { T_A, "A" }, /* RFC 1035 */ + { T_NS, "NS" }, /* RFC 1035 */ + { T_MD, "MD" }, /* RFC 1035 */ + { T_MF, "MF" }, /* RFC 1035 */ + { T_CNAME, "CNAME" }, /* RFC 1035 */ + { T_SOA, "SOA" }, /* RFC 1035 */ + { T_MB, "MB" }, /* RFC 1035 */ + { T_MG, "MG" }, /* RFC 1035 */ + { T_MR, "MR" }, /* RFC 1035 */ + { T_NULL, "NULL" }, /* RFC 1035 */ + { T_WKS, "WKS" }, /* RFC 1035 */ + { T_PTR, "PTR" }, /* RFC 1035 */ + { T_HINFO, "HINFO" }, /* RFC 1035 */ + { T_MINFO, "MINFO" }, /* RFC 1035 */ + { T_MX, "MX" }, /* RFC 1035 */ + { T_TXT, "TXT" }, /* RFC 1035 */ + { T_RP, "RP" }, /* RFC 1183 */ + { T_AFSDB, "AFSDB" }, /* RFC 1183 */ + { T_X25, "X25" }, /* RFC 1183 */ + { T_ISDN, "ISDN" }, /* RFC 1183 */ + { T_RT, "RT" }, /* RFC 1183 */ + { T_NSAP, "NSAP" }, /* RFC 1706 */ { T_NSAP_PTR, "NSAP_PTR" }, - { T_SIG, "SIG" }, - { T_KEY, "KEY" }, - { T_PX, "PX" }, - { T_GPOS, "GPOS" }, - { T_AAAA, "AAAA" }, - { T_LOC, "LOC" }, - { T_NXT, "NXT" }, - { T_EID, "EID" }, - { T_NIMLOC, "NIMLOC" }, - { T_SRV, "SRV" }, - { T_ATMA, "ATMA" }, - { T_NAPTR, "NAPTR" }, - { T_A6, "A6" }, - { T_DNAME, "DNAME" }, - { T_OPT, "OPT" }, + { T_SIG, "SIG" }, /* RFC 2535 */ + { T_KEY, "KEY" }, /* RFC 2535 */ + { T_PX, "PX" }, /* RFC 2163 */ + { T_GPOS, "GPOS" }, /* RFC 1712 */ + { T_AAAA, "AAAA" }, /* RFC 1886 */ + { T_LOC, "LOC" }, /* RFC 1876 */ + { T_NXT, "NXT" }, /* RFC 2535 */ + { T_EID, "EID" }, /* Nimrod */ + { T_NIMLOC, "NIMLOC" }, /* Nimrod */ + { T_SRV, "SRV" }, /* RFC 2782 */ + { T_ATMA, "ATMA" }, /* ATM Forum */ + { T_NAPTR, "NAPTR" }, /* RFC 2168, RFC 2915 */ + { T_A6, "A6" }, /* RFC 2874 */ + { T_DNAME, "DNAME" }, /* RFC 2672 */ + { T_OPT, "OPT" }, /* RFC 2671 */ { T_UINFO, "UINFO" }, { T_UID, "UID" }, { T_GID, "GID" }, { T_UNSPEC, "UNSPEC" }, { T_UNSPECA, "UNSPECA" }, - { T_TKEY, "TKEY" }, - { T_TSIG, "TSIG" }, - { T_IXFR, "IXFR" }, - { T_AXFR, "AXFR" }, - { T_MAILB, "MAILB" }, - { T_MAILA, "MAILA" }, + { T_TKEY, "TKEY" }, /* RFC 2930 */ + { T_TSIG, "TSIG" }, /* RFC 2845 */ + { T_IXFR, "IXFR" }, /* RFC 1995 */ + { T_AXFR, "AXFR" }, /* RFC 1035 */ + { T_MAILB, "MAILB" }, /* RFC 1035 */ + { T_MAILA, "MAILA" }, /* RFC 1035 */ { T_ANY, "ANY" }, { 0, NULL } }; @@ -308,23 +307,25 @@ struct tok ns_class2str[] = { /* print a query */ static const u_char * -ns_qprint(register const u_char *cp, register const u_char *bp) +ns_qprint(register const u_char *cp, register const u_char *bp, int is_mdns) { register const u_char *np = cp; register u_int i; - cp = ns_nskip(cp, bp); + cp = ns_nskip(cp); if (cp == NULL || !TTEST2(*cp, 4)) return(NULL); /* print the qtype and qclass (if it's not IN) */ - i = *cp++ << 8; - i |= *cp++; + i = EXTRACT_16BITS(cp); + cp += 2; printf(" %s", tok2str(ns_type2str, "Type%d", i)); - i = *cp++ << 8; - i |= *cp++; - if (i != C_IN) + i = EXTRACT_16BITS(cp); + cp += 2; + if (is_mdns && i == (C_IN|C_CACHE_FLUSH)) + printf(" (Cache flush)"); + else if (i != C_IN) printf(" %s", tok2str(ns_class2str, "(Class %d)", i)); fputs("? ", stdout); @@ -334,7 +335,7 @@ ns_qprint(register const u_char *cp, register const u_char *bp) /* print a reply */ static const u_char * -ns_rprint(register const u_char *cp, register const u_char *bp) +ns_rprint(register const u_char *cp, register const u_char *bp, int is_mdns) { register u_int class; register u_short typ, len; @@ -345,24 +346,26 @@ ns_rprint(register const u_char *cp, register const u_char *bp) if ((cp = ns_nprint(cp, bp)) == NULL) return NULL; } else - cp = ns_nskip(cp, bp); + cp = ns_nskip(cp); if (cp == NULL || !TTEST2(*cp, 10)) return (snapend); /* print the type/qtype and class (if it's not IN) */ - typ = *cp++ << 8; - typ |= *cp++; - class = *cp++ << 8; - class |= *cp++; - if (class != C_IN && typ != T_OPT) + typ = EXTRACT_16BITS(cp); + cp += 2; + class = EXTRACT_16BITS(cp); + cp += 2; + if (is_mdns && class == (C_IN|C_CACHE_FLUSH)) + printf(" (Cache flush)"); + else if (class != C_IN && typ != T_OPT) printf(" %s", tok2str(ns_class2str, "(Class %d)", class)); /* ignore ttl */ cp += 4; - len = *cp++ << 8; - len |= *cp++; + len = EXTRACT_16BITS(cp); + cp += 2; rp = cp + len; @@ -420,8 +423,23 @@ ns_rprint(register const u_char *cp, register const u_char *bp) break; case T_TXT: + while (cp < rp) { + printf(" \""); + cp = ns_cprint(cp); + if (cp == NULL) + return(NULL); + putchar('"'); + } + break; + + case T_SRV: putchar(' '); - (void)ns_cprint(cp, bp); + if (!TTEST2(*cp, 6)) + return(NULL); + if (ns_nprint(cp + 6, bp) == NULL) + return(NULL); + printf(":%d %d %d", EXTRACT_16BITS(cp + 4), + EXTRACT_16BITS(cp), EXTRACT_16BITS(cp + 2)); break; #ifdef INET6 @@ -506,55 +524,56 @@ ns_rprint(register const u_char *cp, register const u_char *bp) } void -ns_print(register const u_char *bp, u_int length) +ns_print(register const u_char *bp, u_int length, int is_mdns) { register const HEADER *np; register int qdcount, ancount, nscount, arcount; register const u_char *cp; + u_int16_t b2; np = (const HEADER *)bp; TCHECK(*np); /* get the byte-order right */ - qdcount = ntohs(np->qdcount); - ancount = ntohs(np->ancount); - nscount = ntohs(np->nscount); - arcount = ntohs(np->arcount); + qdcount = EXTRACT_16BITS(&np->qdcount); + ancount = EXTRACT_16BITS(&np->ancount); + nscount = EXTRACT_16BITS(&np->nscount); + arcount = EXTRACT_16BITS(&np->arcount); if (DNS_QR(np)) { /* this is a response */ printf(" %d%s%s%s%s%s%s", - ntohs(np->id), + EXTRACT_16BITS(&np->id), ns_ops[DNS_OPCODE(np)], ns_resp[DNS_RCODE(np)], DNS_AA(np)? "*" : "", DNS_RA(np)? "" : "-", DNS_TC(np)? "|" : "", - DNS_CD(np)? "%" : ""); + DNS_AD(np)? "$" : ""); if (qdcount != 1) printf(" [%dq]", qdcount); /* Print QUESTION section on -vv */ cp = (const u_char *)(np + 1); while (qdcount--) { - if (qdcount < ntohs(np->qdcount) - 1) + if (qdcount < EXTRACT_16BITS(&np->qdcount) - 1) putchar(','); if (vflag > 1) { fputs(" q:", stdout); - if ((cp = ns_qprint(cp, bp)) == NULL) + if ((cp = ns_qprint(cp, bp, is_mdns)) == NULL) goto trunc; } else { - if ((cp = ns_nskip(cp, bp)) == NULL) + if ((cp = ns_nskip(cp)) == NULL) goto trunc; cp += 4; /* skip QTYPE and QCLASS */ } } printf(" %d/%d/%d", ancount, nscount, arcount); if (ancount--) { - if ((cp = ns_rprint(cp, bp)) == NULL) + if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) goto trunc; while (cp < snapend && ancount--) { putchar(','); - if ((cp = ns_rprint(cp, bp)) == NULL) + if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) goto trunc; } } @@ -564,11 +583,11 @@ ns_print(register const u_char *bp, u_int length) if (vflag > 1) { if (cp < snapend && nscount--) { fputs(" ns:", stdout); - if ((cp = ns_rprint(cp, bp)) == NULL) + if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) goto trunc; while (cp < snapend && nscount--) { putchar(','); - if ((cp = ns_rprint(cp, bp)) == NULL) + if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) goto trunc; } } @@ -576,11 +595,11 @@ ns_print(register const u_char *bp, u_int length) goto trunc; if (cp < snapend && arcount--) { fputs(" ar:", stdout); - if ((cp = ns_rprint(cp, bp)) == NULL) + if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) goto trunc; while (cp < snapend && arcount--) { putchar(','); - if ((cp = ns_rprint(cp, bp)) == NULL) + if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) goto trunc; } } @@ -590,13 +609,14 @@ ns_print(register const u_char *bp, u_int length) } else { /* this is a request */ - printf(" %d%s%s%s", ntohs(np->id), ns_ops[DNS_OPCODE(np)], + printf(" %d%s%s%s", EXTRACT_16BITS(&np->id), ns_ops[DNS_OPCODE(np)], DNS_RD(np) ? "+" : "", - DNS_AD(np) ? "$" : ""); + DNS_CD(np) ? "%" : ""); /* any weirdness? */ - if (*(((u_short *)np)+1) & htons(0x6cf)) - printf(" [b2&3=0x%x]", ntohs(*(((u_short *)np)+1))); + b2 = EXTRACT_16BITS(((u_short *)np)+1); + if (b2 & 0x6cf) + printf(" [b2&3=0x%x]", b2); if (DNS_OPCODE(np) == IQUERY) { if (qdcount) @@ -617,12 +637,13 @@ ns_print(register const u_char *bp, u_int length) cp = (const u_char *)(np + 1); if (qdcount--) { - cp = ns_qprint(cp, (const u_char *)np); + cp = ns_qprint(cp, (const u_char *)np, is_mdns); if (!cp) goto trunc; while (cp < snapend && qdcount--) { cp = ns_qprint((const u_char *)cp, - (const u_char *)np); + (const u_char *)np, + is_mdns); if (!cp) goto trunc; } @@ -633,11 +654,11 @@ ns_print(register const u_char *bp, u_int length) /* Print remaining sections on -vv */ if (vflag > 1) { if (ancount--) { - if ((cp = ns_rprint(cp, bp)) == NULL) + if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) goto trunc; while (cp < snapend && ancount--) { putchar(','); - if ((cp = ns_rprint(cp, bp)) == NULL) + if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) goto trunc; } } @@ -645,11 +666,11 @@ ns_print(register const u_char *bp, u_int length) goto trunc; if (cp < snapend && nscount--) { fputs(" ns:", stdout); - if ((cp = ns_rprint(cp, bp)) == NULL) + if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) goto trunc; while (nscount-- && cp < snapend) { putchar(','); - if ((cp = ns_rprint(cp, bp)) == NULL) + if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) goto trunc; } } @@ -657,11 +678,11 @@ ns_print(register const u_char *bp, u_int length) goto trunc; if (cp < snapend && arcount--) { fputs(" ar:", stdout); - if ((cp = ns_rprint(cp, bp)) == NULL) + if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) goto trunc; while (cp < snapend && arcount--) { putchar(','); - if ((cp = ns_rprint(cp, bp)) == NULL) + if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL) goto trunc; } } diff --git a/contrib/tcpdump/print-ether.c b/contrib/tcpdump/print-ether.c index a70642e34a95..223a08588e37 100644 --- a/contrib/tcpdump/print-ether.c +++ b/contrib/tcpdump/print-ether.c @@ -21,19 +21,15 @@ * $FreeBSD$ */ #ifndef lint -static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/print-ether.c,v 1.65.4.1 2002/06/01 23:51:12 guy Exp $ (LBL)"; +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-ether.c,v 1.82.2.3 2003/12/29 22:42:21 hannes Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include <sys/param.h> -#include <sys/time.h> -#include <sys/socket.h> - -#include <netinet/in.h> +#include <tcpdump-stdinc.h> #include <stdio.h> #include <pcap.h> @@ -44,61 +40,82 @@ static const char rcsid[] = #include "ether.h" -const u_char *packetp; const u_char *snapend; +const struct tok ethertype_values[] = { + { ETHERTYPE_IP, "IPv4" }, + { ETHERTYPE_MPLS, "MPLS unicast" }, + { ETHERTYPE_MPLS_MULTI, "MPLS multicast" }, + { ETHERTYPE_IPV6, "IPv6" }, + { ETHERTYPE_8021Q, "802.1Q" }, + { ETHERTYPE_VMAN, "VMAN" }, + { ETHERTYPE_PUP, "PUP" }, + { ETHERTYPE_ARP, "ARP"}, + { ETHERTYPE_REVARP , "Reverse ARP"}, + { ETHERTYPE_NS, "NS" }, + { ETHERTYPE_SPRITE, "Sprite" }, + { ETHERTYPE_TRAIL, "Trail" }, + { ETHERTYPE_MOPDL, "MOP DL" }, + { ETHERTYPE_MOPRC, "MOP RC" }, + { ETHERTYPE_DN, "DN" }, + { ETHERTYPE_LAT, "LAT" }, + { ETHERTYPE_SCA, "SCA" }, + { ETHERTYPE_LANBRIDGE, "Lanbridge" }, + { ETHERTYPE_DECDNS, "DEC DNS" }, + { ETHERTYPE_DECDTS, "DEC DTS" }, + { ETHERTYPE_VEXP, "VEXP" }, + { ETHERTYPE_VPROD, "VPROD" }, + { ETHERTYPE_ATALK, "Appletalk" }, + { ETHERTYPE_AARP, "Appletalk ARP" }, + { ETHERTYPE_IPX, "IPX" }, + { ETHERTYPE_PPP, "PPP" }, + { ETHERTYPE_PPPOED, "PPPoE D" }, + { ETHERTYPE_PPPOES, "PPPoE S" }, + { ETHERTYPE_LOOPBACK, "Loopback" }, + { 0, NULL} +}; + static inline void -ether_print(register const u_char *bp, u_int length) +ether_hdr_print(register const u_char *bp, u_int length) { register const struct ether_header *ep; - ep = (const struct ether_header *)bp; - if (qflag) - (void)printf("%s %s %d: ", - etheraddr_string(ESRC(ep)), - etheraddr_string(EDST(ep)), - length); - else - (void)printf("%s %s %s %d: ", - etheraddr_string(ESRC(ep)), - etheraddr_string(EDST(ep)), - etherproto_string(ep->ether_type), - length); + + (void)printf("%s > %s", + etheraddr_string(ESRC(ep)), + etheraddr_string(EDST(ep))); + + if (!qflag) { + if (ntohs(ep->ether_type) <= ETHERMTU) + (void)printf(", 802.3"); + else + (void)printf(", ethertype %s (0x%04x)", + tok2str(ethertype_values,"Unknown", ntohs(ep->ether_type)), + ntohs(ep->ether_type)); + } else { + if (ntohs(ep->ether_type) <= ETHERMTU) + (void)printf(", 802.3"); + else + (void)printf(", %s", tok2str(ethertype_values,"Unknown Ethertype (0x%04x)", ntohs(ep->ether_type))); + } + + (void)printf(", length %u: ", length); } -/* - * This is the top level routine of the printer. 'p' is the points - * to the ether header of the packet, 'h->tv' is the timestamp, - * 'h->length' is the length of the packet off the wire, and 'h->caplen' - * is the number of bytes actually captured. - */ void -ether_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) +ether_print(const u_char *p, u_int length, u_int caplen) { - u_int caplen = h->caplen; - u_int length = h->len; struct ether_header *ep; u_short ether_type; - u_short extracted_ethertype; - - ++infodelay; - ts_print(&h->ts); + u_short extracted_ether_type; if (caplen < ETHER_HDRLEN) { printf("[|ether]"); - goto out; + return; } if (eflag) - ether_print(p, length); - - /* - * Some printers want to get back at the ethernet addresses, - * and/or check that they're not walking off the end of the packet. - * Rather than pass them all the way down, we set these globals. - */ - packetp = p; - snapend = p + caplen; + ether_hdr_print(p, length); length -= ETHER_HDRLEN; caplen -= ETHER_HDRLEN; @@ -110,36 +127,41 @@ ether_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) /* * Is it (gag) an 802.3 encapsulation? */ - extracted_ethertype = 0; + extracted_ether_type = 0; if (ether_type <= ETHERMTU) { /* Try to print the LLC-layer header & higher layers */ if (llc_print(p, length, caplen, ESRC(ep), EDST(ep), - &extracted_ethertype) == 0) { + &extracted_ether_type) == 0) { /* ether_type not known, print raw packet */ if (!eflag) - ether_print((u_char *)ep, length + ETHER_HDRLEN); - if (extracted_ethertype) { - printf("(LLC %s) ", - etherproto_string(htons(extracted_ethertype))); - } + ether_hdr_print((u_char *)ep, length + ETHER_HDRLEN); + if (!xflag && !qflag) default_print(p, caplen); } } else if (ether_encap_print(ether_type, p, length, caplen, - &extracted_ethertype) == 0) { + &extracted_ether_type) == 0) { /* ether_type not known, print raw packet */ if (!eflag) - ether_print((u_char *)ep, length + ETHER_HDRLEN); + ether_hdr_print((u_char *)ep, length + ETHER_HDRLEN); + if (!xflag && !qflag) default_print(p, caplen); - } - if (xflag) - default_print(p, caplen); - out: - putchar('\n'); - --infodelay; - if (infoprint) - info(0); + } +} + +/* + * This is the top level routine of the printer. 'p' points + * to the ether header of the packet, 'h->ts' is the timestamp, + * 'h->length' is the length of the packet off the wire, and 'h->caplen' + * is the number of bytes actually captured. + */ +u_int +ether_if_print(const struct pcap_pkthdr *h, const u_char *p) +{ + ether_print(p, h->len, h->caplen); + + return (ETHER_HDRLEN); } /* @@ -155,13 +177,13 @@ ether_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) */ int -ether_encap_print(u_short ethertype, const u_char *p, - u_int length, u_int caplen, u_short *extracted_ethertype) +ether_encap_print(u_short ether_type, const u_char *p, + u_int length, u_int caplen, u_short *extracted_ether_type) { recurse: - *extracted_ethertype = ethertype; + *extracted_ether_type = ether_type; - switch (ethertype) { + switch (ether_type) { case ETHERTYPE_IP: ip_print(p, length); @@ -193,35 +215,39 @@ ether_encap_print(u_short ethertype, const u_char *p, return (1); case ETHERTYPE_IPX: + printf("(NOV-ETHII) "); ipx_print(p, length); return (1); case ETHERTYPE_8021Q: - printf("802.1Q vlan#%d P%d%s ", - ntohs(*(u_int16_t *)p) & 0xfff, - ntohs(*(u_int16_t *)p) >> 13, - (ntohs(*(u_int16_t *)p) & 0x1000) ? " CFI" : ""); - ethertype = ntohs(*(u_int16_t *)(p + 2)); + if (eflag) + printf("vlan %u, p %u%s, ", + ntohs(*(u_int16_t *)p) & 0xfff, + ntohs(*(u_int16_t *)p) >> 13, + (ntohs(*(u_int16_t *)p) & 0x1000) ? ", CFI" : ""); + + ether_type = ntohs(*(u_int16_t *)(p + 2)); p += 4; length -= 4; caplen -= 4; - if (ethertype > ETHERMTU) + + if (ether_type > ETHERMTU) { + if (eflag) + printf("ethertype %s, ", + tok2str(ethertype_values,"0x%04x", ether_type)); goto recurse; + } - *extracted_ethertype = 0; + *extracted_ether_type = 0; if (llc_print(p, length, caplen, p - 18, p - 12, - extracted_ethertype) == 0) { - /* ether_type not known, print raw packet */ - if (!eflag) - ether_print(p - 18, length + 4); - if (*extracted_ethertype) { - printf("(LLC %s) ", - etherproto_string(htons(*extracted_ethertype))); - } - if (!xflag && !qflag) - default_print(p - 18, caplen + 4); + extracted_ether_type) == 0) { + ether_hdr_print(p - 18, length + 4); } + + if (!xflag && !qflag) + default_print(p - 18, caplen + 4); + return (1); case ETHERTYPE_PPPOED: @@ -229,16 +255,18 @@ ether_encap_print(u_short ethertype, const u_char *p, case ETHERTYPE_PPPOED2: case ETHERTYPE_PPPOES2: pppoe_print(p, length); - return (1); - + return (1); + case ETHERTYPE_PPP: - printf("ppp"); if (length) { printf(": "); ppp_print(p, length); } return (1); + case ETHERTYPE_LOOPBACK: + return (0); + case ETHERTYPE_MPLS: case ETHERTYPE_MPLS_MULTI: mpls_print(p, length); diff --git a/contrib/tcpdump/print-fddi.c b/contrib/tcpdump/print-fddi.c index 6a0bf86423c4..e9aedddabc96 100644 --- a/contrib/tcpdump/print-fddi.c +++ b/contrib/tcpdump/print-fddi.c @@ -22,22 +22,16 @@ */ #ifndef lint -static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/print-fddi.c,v 1.53.2.1 2002/06/01 23:51:13 guy Exp $ (LBL)"; +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-fddi.c,v 1.61.2.2 2003/11/16 08:51:20 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include <sys/param.h> -#include <sys/time.h> -#include <sys/socket.h> +#include <tcpdump-stdinc.h> -#include <netinet/in.h> - -#include <ctype.h> -#include <netdb.h> #include <pcap.h> #include <stdio.h> #include <string.h> @@ -219,7 +213,7 @@ extract_fddi_addrs(const struct fddi_header *fddip, char *fsrc, char *fdst) * Print the FDDI MAC header */ static inline void -fddi_print(register const struct fddi_header *fddip, register u_int length, +fddi_hdr_print(register const struct fddi_header *fddip, register u_int length, register const u_char *fsrc, register const u_char *fdst) { const char *srcname, *dstname; @@ -241,54 +235,30 @@ fddi_print(register const struct fddi_header *fddip, register u_int length, } static inline void -fddi_smt_print(const u_char *p, u_int length) +fddi_smt_print(const u_char *p _U_, u_int length _U_) { printf("<SMT printer not yet implemented>"); } -/* - * This is the top level routine of the printer. 'sp' is the points - * to the FDDI header of the packet, 'tvp' is the timestamp, - * 'length' is the length of the packet off the wire, and 'caplen' - * is the number of bytes actually captured. - */ void -fddi_if_print(u_char *pcap, const struct pcap_pkthdr *h, - register const u_char *p) +fddi_print(const u_char *p, u_int length, u_int caplen) { - u_int caplen = h->caplen; - u_int length = h->len; const struct fddi_header *fddip = (const struct fddi_header *)p; struct ether_header ehdr; u_short extracted_ethertype; - ++infodelay; - ts_print(&h->ts); - if (caplen < FDDI_HDRLEN) { printf("[|fddi]"); - goto out; + return; } + /* * Get the FDDI addresses into a canonical form */ extract_fddi_addrs(fddip, (char *)ESRC(&ehdr), (char *)EDST(&ehdr)); - /* - * Some printers want to get back at the link level addresses, - * and/or check that they're not walking off the end of the packet. - * Rather than pass them all the way down, we set these globals. - */ - snapend = p + caplen; - /* - * Actually, the only printers that use packetp are print-arp.c - * and print-bootp.c, and they assume that packetp points to an - * Ethernet header. The right thing to do is to fix them to know - * which link type is in use when they excavate. XXX - */ - packetp = (u_char *)&ehdr; if (eflag) - fddi_print(fddip, length, ESRC(&ehdr), EDST(&ehdr)); + fddi_hdr_print(fddip, length, ESRC(&ehdr), EDST(&ehdr)); /* Skip over FDDI MAC header */ length -= FDDI_HDRLEN; @@ -306,7 +276,7 @@ fddi_if_print(u_char *pcap, const struct pcap_pkthdr *h, * handle intelligently */ if (!eflag) - fddi_print(fddip, length + FDDI_HDRLEN, + fddi_hdr_print(fddip, length + FDDI_HDRLEN, ESRC(&ehdr), EDST(&ehdr)); if (extracted_ethertype) { printf("(LLC %s) ", @@ -320,16 +290,23 @@ fddi_if_print(u_char *pcap, const struct pcap_pkthdr *h, else { /* Some kinds of FDDI packet we cannot handle intelligently */ if (!eflag) - fddi_print(fddip, length + FDDI_HDRLEN, ESRC(&ehdr), + fddi_hdr_print(fddip, length + FDDI_HDRLEN, ESRC(&ehdr), EDST(&ehdr)); if (!xflag && !qflag) default_print(p, caplen); } - if (xflag) - default_print(p, caplen); -out: - putchar('\n'); - --infodelay; - if (infoprint) - info(0); +} + +/* + * This is the top level routine of the printer. 'p' points + * to the FDDI header of the packet, 'h->ts' is the timestamp, + * 'h->length' is the length of the packet off the wire, and 'h->caplen' + * is the number of bytes actually captured. + */ +u_int +fddi_if_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + fddi_print(p, h->len, h->caplen); + + return (FDDI_HDRLEN); } diff --git a/contrib/tcpdump/print-fr.c b/contrib/tcpdump/print-fr.c index 70393387f210..4e568b1e16f4 100644 --- a/contrib/tcpdump/print-fr.c +++ b/contrib/tcpdump/print-fr.c @@ -260,8 +260,8 @@ out: #include <stdio.h> #include "interface.h" -void -fr_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) +u_int +fr_if_print(const struct pcap_pkthdr *h, const u_char *p) { error("not configured for ppp"); /* NOTREACHED */ diff --git a/contrib/tcpdump/print-icmp.c b/contrib/tcpdump/print-icmp.c index 34b6c3296c36..ddaf2803d635 100644 --- a/contrib/tcpdump/print-icmp.c +++ b/contrib/tcpdump/print-icmp.c @@ -22,23 +22,18 @@ */ #ifndef lint -static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/print-icmp.c,v 1.62.4.1 2002/06/01 23:51:13 guy Exp $ (LBL)"; +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-icmp.c,v 1.73.2.3 2004/03/24 00:56:34 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include <sys/param.h> -#include <sys/time.h> -#include <sys/socket.h> - -#include <netinet/in.h> +#include <tcpdump-stdinc.h> #include <stdio.h> #include <string.h> -#include <netdb.h> /* for MAXHOSTNAMELEN on some platforms */ #include "interface.h" #include "addrtoname.h" @@ -46,6 +41,7 @@ static const char rcsid[] = #include "ip.h" #include "udp.h" +#include "ipproto.h" /* * Interface Control Message Protocol Definitions. @@ -70,7 +66,7 @@ struct icmp { /* ICMP_UNREACH_NEEDFRAG -- Path MTU Discovery (RFC1191) */ struct ih_pmtu { - u_int16_t ipm_void; + u_int16_t ipm_void; u_int16_t ipm_nextmtu; } ih_pmtu; } icmp_hun; @@ -267,7 +263,7 @@ struct id_rdiscovery { }; void -icmp_print(const u_char *bp, u_int plen, const u_char *bp2) +icmp_print(const u_char *bp, u_int plen, const u_char *bp2, int fragmented) { char *cp; const struct icmp *dp; @@ -285,6 +281,15 @@ icmp_print(const u_char *bp, u_int plen, const u_char *bp2) TCHECK(dp->icmp_code); switch (dp->icmp_type) { + case ICMP_ECHO: + case ICMP_ECHOREPLY: + TCHECK(dp->icmp_seq); + (void)snprintf(buf, sizeof(buf), "echo %s seq %u", + dp->icmp_type == ICMP_ECHO ? + "request" : "reply", + EXTRACT_16BITS(&dp->icmp_seq)); + break; + case ICMP_UNREACH: TCHECK(dp->icmp_ip.ip_dst); switch (dp->icmp_code) { @@ -302,7 +307,8 @@ icmp_print(const u_char *bp, u_int plen, const u_char *bp2) oip = &dp->icmp_ip; hlen = IP_HL(oip) * 4; ouh = (struct udphdr *)(((u_char *)oip) + hlen); - dport = ntohs(ouh->uh_dport); + TCHECK(ouh->uh_dport); + dport = EXTRACT_16BITS(&ouh->uh_dport); switch (oip->ip_p) { case IPPROTO_TCP: @@ -447,46 +453,52 @@ icmp_print(const u_char *bp, u_int plen, const u_char *bp2) case ICMP_MASKREPLY: TCHECK(dp->icmp_mask); (void)snprintf(buf, sizeof(buf), "address mask is 0x%08x", - (unsigned)ntohl(dp->icmp_mask)); + EXTRACT_32BITS(&dp->icmp_mask)); break; case ICMP_TSTAMP: TCHECK(dp->icmp_seq); (void)snprintf(buf, sizeof(buf), "time stamp query id %u seq %u", - (unsigned)ntohs(dp->icmp_id), - (unsigned)ntohs(dp->icmp_seq)); + EXTRACT_16BITS(&dp->icmp_id), + EXTRACT_16BITS(&dp->icmp_seq)); break; case ICMP_TSTAMPREPLY: TCHECK(dp->icmp_ttime); (void)snprintf(buf, sizeof(buf), - "time stamp reply id %u seq %u : org 0x%lx recv 0x%lx xmit 0x%lx", - (unsigned)ntohs(dp->icmp_id), - (unsigned)ntohs(dp->icmp_seq), - (unsigned long)ntohl(dp->icmp_otime), - (unsigned long)ntohl(dp->icmp_rtime), - (unsigned long)ntohl(dp->icmp_ttime)); + "time stamp reply id %u seq %u : org 0x%x recv 0x%x xmit 0x%x", + EXTRACT_16BITS(&dp->icmp_id), + EXTRACT_16BITS(&dp->icmp_seq), + EXTRACT_32BITS(&dp->icmp_otime), + EXTRACT_32BITS(&dp->icmp_rtime), + EXTRACT_32BITS(&dp->icmp_ttime)); break; default: str = tok2str(icmp2str, "type-#%d", dp->icmp_type); break; } - (void)printf("icmp: %s", str); - if (vflag) { + (void)printf("icmp %d: %s", plen, str); + if (vflag && !fragmented) { /* don't attempt checksumming if this is a frag */ + u_int16_t sum, icmp_sum; if (TTEST2(*bp, plen)) { - if (in_cksum((u_short*)dp, plen, 0)) - printf(" (wrong icmp csum)"); + sum = in_cksum((u_short*)dp, plen, 0); + if (sum != 0) { + icmp_sum = EXTRACT_16BITS(&dp->icmp_cksum); + (void)printf(" (wrong icmp cksum %x (->%x)!)", + icmp_sum, + in_cksum_shouldbe(icmp_sum, sum)); + } } } - if (vflag > 1 && !ICMP_INFOTYPE(dp->icmp_type)) { - bp += 8; - (void)printf(" for "); - ip = (struct ip *)bp; - snaplen = snapend - bp; - ip_print(bp, ntohs(ip->ip_len)); - } + if (vflag > 1 && !ICMP_INFOTYPE(dp->icmp_type)) { + bp += 8; + (void)printf(" for "); + ip = (struct ip *)bp; + snaplen = snapend - bp; + ip_print(bp, EXTRACT_16BITS(&ip->ip_len)); + } return; trunc: fputs("[|icmp]", stdout); diff --git a/contrib/tcpdump/print-ip.c b/contrib/tcpdump/print-ip.c index 6e614e12af82..ca4c96d0f4a1 100644 --- a/contrib/tcpdump/print-ip.c +++ b/contrib/tcpdump/print-ip.c @@ -22,36 +22,26 @@ */ #ifndef lint -static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/print-ip.c,v 1.100.4.1 2002/01/25 05:39:54 guy Exp $ (LBL)"; +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-ip.c,v 1.128.2.6 2004/03/24 09:01:39 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include <sys/param.h> -#include <sys/time.h> -#include <sys/socket.h> +#include <tcpdump-stdinc.h> -#include <netinet/in.h> - -#include <netdb.h> #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <unistd.h> #include "addrtoname.h" #include "interface.h" #include "extract.h" /* must come after interface.h */ #include "ip.h" - -/* Compatibility */ -#ifndef IPPROTO_ND -#define IPPROTO_ND 77 -#endif +#include "ipproto.h" /* * print the recorded route in an IP RR, LSRR or SSRR option. @@ -59,14 +49,19 @@ static const char rcsid[] = static void ip_printroute(const char *type, register const u_char *cp, u_int length) { - register u_int ptr = cp[2] - 1; + register u_int ptr; register u_int len; + if (length < 3) { + printf(" [bad length %u]", length); + return; + } printf(" %s{", type); if ((length + 1) & 3) - printf(" [bad length %d]", length); + printf(" [bad length %u]", length); + ptr = cp[2] - 1; if (ptr < 3 || ((ptr + 1) & 3) || ptr > length + 1) - printf(" [bad ptr %d]", cp[2]); + printf(" [bad ptr %u]", cp[2]); type = ""; for (len = 3; len < length; len += 4) { @@ -78,18 +73,73 @@ ip_printroute(const char *type, register const u_char *cp, u_int length) printf("%s}", ptr == len? "#" : ""); } +/* + * If source-routing is present, return the final destination. + * Otherwise, return IP destination. + * + * This is used for UDP and TCP pseudo-header in the checksum + * calculation. + */ +u_int32_t +ip_finddst(const struct ip *ip) +{ + int length; + int len; + const u_char *cp; + u_int32_t retval; + + cp = (const u_char *)(ip + 1); + length = (IP_HL(ip) << 2) - sizeof(struct ip); + + for (; length > 0; cp += len, length -= len) { + int tt; + + TCHECK(*cp); + tt = *cp; + if (tt == IPOPT_NOP || tt == IPOPT_EOL) + len = 1; + else { + TCHECK(cp[1]); + len = cp[1]; + } + if (len < 2) { + return 0; + } + TCHECK2(*cp, len); + switch (tt) { + + case IPOPT_SSRR: + case IPOPT_LSRR: + if (len < 7) + return 0; + memcpy(&retval, cp + len - 4, 4); + return retval; + } + } + return ip->ip_dst.s_addr; + +trunc: + return 0; +} + static void ip_printts(register const u_char *cp, u_int length) { - register u_int ptr = cp[2] - 1; - register u_int len = 0; + register u_int ptr; + register u_int len; int hoplen; - char *type; + const char *type; + if (length < 4) { + printf("[bad length %d]", length); + return; + } printf(" TS{"); hoplen = ((cp[3]&0xF) != IPOPT_TS_TSONLY) ? 8 : 4; if ((length - 4) & (hoplen-1)) printf("[bad length %d]", length); + ptr = cp[2] - 1; + len = 0; if (ptr < 4 || ((ptr - 4) & (hoplen-1)) || ptr > length + 1) printf("[bad ptr %d]", cp[2]); switch (cp[3]&0xF) { @@ -111,7 +161,7 @@ ip_printts(register const u_char *cp, u_int length) case 3: /* IPOPT_TS_PRESPEC */ printf("PRESPEC"); break; - default: + default: printf("[bad ts type %d]", cp[3]&0xF); goto done; } @@ -143,24 +193,20 @@ ip_optprint(register const u_char *cp, u_int length) register u_int len; for (; length > 0; cp += len, length -= len) { - int tt = *cp; + int tt; + TCHECK(*cp); + tt = *cp; if (tt == IPOPT_NOP || tt == IPOPT_EOL) len = 1; else { - if (&cp[1] >= snapend) { - printf("[|ip]"); + TCHECK(cp[1]); + len = cp[1]; + if (len < 2) { + printf("[|ip op len %d]", len); return; } - len = cp[1]; - } - if (len <= 0) { - printf("[|ip op len %d]", len); - return; - } - if (&cp[1] >= snapend || cp + len > snapend) { - printf("[|ip]"); - return; + TCHECK2(*cp, len); } switch (tt) { @@ -204,8 +250,11 @@ ip_optprint(register const u_char *cp, u_int length) printf(" RA"); if (len != 4) printf("{%d}", len); - else if (cp[2] || cp[3]) - printf("%d.%d", cp[2], cp[3]); + else { + TCHECK(cp[3]); + if (cp[2] || cp[3]) + printf("%d.%d", cp[2], cp[3]); + } break; default: @@ -213,6 +262,10 @@ ip_optprint(register const u_char *cp, u_int length) break; } } + return; + +trunc: + printf("[|ip]"); } /* @@ -227,12 +280,12 @@ in_cksum(const u_short *addr, register u_int len, int csum) u_short answer; int sum = csum; - /* + /* * Our algorithm is simple, using a 32 bit accumulator (sum), * we add sequential 16 bit words to it, and at the end, fold * back all the carry bits from the top 16 bits into the lower * 16 bits. - */ + */ while (nleft > 1) { sum += *w++; nleft -= 2; @@ -250,6 +303,73 @@ in_cksum(const u_short *addr, register u_int len, int csum) } /* + * Given the host-byte-order value of the checksum field in a packet + * header, and the network-byte-order computed checksum of the data + * that the checksum covers (including the checksum itself), compute + * what the checksum field *should* have been. + */ +u_int16_t +in_cksum_shouldbe(u_int16_t sum, u_int16_t computed_sum) +{ + u_int32_t shouldbe; + + /* + * The value that should have gone into the checksum field + * is the negative of the value gotten by summing up everything + * *but* the checksum field. + * + * We can compute that by subtracting the value of the checksum + * field from the sum of all the data in the packet, and then + * computing the negative of that value. + * + * "sum" is the value of the checksum field, and "computed_sum" + * is the negative of the sum of all the data in the packets, + * so that's -(-computed_sum - sum), or (sum + computed_sum). + * + * All the arithmetic in question is one's complement, so the + * addition must include an end-around carry; we do this by + * doing the arithmetic in 32 bits (with no sign-extension), + * and then adding the upper 16 bits of the sum, which contain + * the carry, to the lower 16 bits of the sum, and then do it + * again in case *that* sum produced a carry. + * + * As RFC 1071 notes, the checksum can be computed without + * byte-swapping the 16-bit words; summing 16-bit words + * on a big-endian machine gives a big-endian checksum, which + * can be directly stuffed into the big-endian checksum fields + * in protocol headers, and summing words on a little-endian + * machine gives a little-endian checksum, which must be + * byte-swapped before being stuffed into a big-endian checksum + * field. + * + * "computed_sum" is a network-byte-order value, so we must put + * it in host byte order before subtracting it from the + * host-byte-order value from the header; the adjusted checksum + * will be in host byte order, which is what we'll return. + */ + shouldbe = sum; + shouldbe += ntohs(computed_sum); + shouldbe = (shouldbe & 0xFFFF) + (shouldbe >> 16); + shouldbe = (shouldbe & 0xFFFF) + (shouldbe >> 16); + return shouldbe; +} + +#ifndef IP_MF +#define IP_MF 0x2000 +#endif /* IP_MF */ +#ifndef IP_DF +#define IP_DF 0x4000 +#endif /* IP_DF */ +#define IP_RES 0x8000 + +static struct tok ip_frag_values[] = { + { IP_MF, "+" }, + { IP_DF, "DF" }, + { IP_RES, "rsvd" }, /* The RFC3514 evil ;-) bit */ + { 0, NULL } +}; + +/* * print an IP datagram. */ void @@ -257,36 +377,22 @@ ip_print(register const u_char *bp, register u_int length) { register const struct ip *ip; register u_int hlen, len, len0, off; + const u_char *ipend; register const u_char *cp; u_char nh; int advance; struct protoent *proto; + u_int16_t sum, ip_sum; ip = (const struct ip *)bp; -#ifdef LBL_ALIGN - /* - * If the IP header is not aligned, copy into abuf. - */ - if ((long)ip & 3) { - static u_char *abuf = NULL; - static int didwarn = 0; - - if (abuf == NULL) { - abuf = (u_char *)malloc(snaplen); - if (abuf == NULL) - error("ip_print: malloc"); - } - memcpy((char *)abuf, (char *)ip, min(length, snaplen)); - snapend += abuf - (u_char *)ip; - packetp = abuf; - ip = (struct ip *)abuf; - /* We really want libpcap to give us aligned packets */ - if (!didwarn) { - warning("compensating for unaligned libpcap packets"); - ++didwarn; - } + if (IP_V(ip) != 4) { /* print version if != 4 */ + printf("IP%u ", IP_V(ip)); + if (IP_V(ip) == 6) + printf(", wrong link-layer encapsulation"); } -#endif + else + printf("IP "); + if ((u_char *)(ip + 1) > snapend) { printf("[|ip]"); return; @@ -297,29 +403,89 @@ ip_print(register const u_char *bp, register u_int length) } hlen = IP_HL(ip) * 4; if (hlen < sizeof (struct ip)) { - (void)printf("bad-hlen %d", hlen); + (void)printf("bad-hlen %u", hlen); return; } - len = ntohs(ip->ip_len); + len = EXTRACT_16BITS(&ip->ip_len); if (length < len) - (void)printf("truncated-ip - %d bytes missing! ", + (void)printf("truncated-ip - %u bytes missing! ", len - length); + if (len < hlen) { + (void)printf("bad-len %u", len); + return; + } + + /* + * Cut off the snapshot length to the end of the IP payload. + */ + ipend = bp + len; + if (ipend < snapend) + snapend = ipend; + len -= hlen; len0 = len; + off = EXTRACT_16BITS(&ip->ip_off); + + if (vflag) { + (void)printf("(tos 0x%x", (int)ip->ip_tos); + /* ECN bits */ + if (ip->ip_tos & 0x03) { + switch (ip->ip_tos & 0x03) { + case 1: + (void)printf(",ECT(1)"); + break; + case 2: + (void)printf(",ECT(0)"); + break; + case 3: + (void)printf(",CE"); + } + } + + if (ip->ip_ttl >= 1) + (void)printf(", ttl %3u", ip->ip_ttl); + + /* + * for the firewall guys, print id, offset. + * On all but the last stick a "+" in the flags portion. + * For unfragmented datagrams, note the don't fragment flag. + */ + + (void)printf(", id %u, offset %u, flags [%s]", + EXTRACT_16BITS(&ip->ip_id), + (off & 0x1fff) * 8, + bittok2str(ip_frag_values, "none", off & 0xe000 )); + + (void)printf(", length: %u", EXTRACT_16BITS(&ip->ip_len)); + + if ((hlen - sizeof(struct ip)) > 0) { + (void)printf(", optlength: %u (", hlen - (u_int)sizeof(struct ip)); + ip_optprint((u_char *)(ip + 1), hlen - sizeof(struct ip)); + printf(" )"); + } + + if ((u_char *)ip + hlen <= snapend) { + sum = in_cksum((const u_short *)ip, hlen, 0); + if (sum != 0) { + ip_sum = EXTRACT_16BITS(&ip->ip_sum); + (void)printf(", bad cksum %x (->%x)!", ip_sum, + in_cksum_shouldbe(ip_sum, sum)); + } + } + + printf(") "); + } + /* * If this is fragment zero, hand it to the next higher * level protocol. */ - off = ntohs(ip->ip_off); if ((off & 0x1fff) == 0) { cp = (const u_char *)ip + hlen; nh = ip->ip_p; -#ifndef IPPROTO_SCTP -#define IPPROTO_SCTP 132 -#endif if (nh != IPPROTO_TCP && nh != IPPROTO_UDP && nh != IPPROTO_SCTP) { (void)printf("%s > %s: ", ipaddr_string(&ip->ip_src), @@ -328,48 +494,41 @@ ip_print(register const u_char *bp, register u_int length) again: switch (nh) { -#ifndef IPPROTO_AH -#define IPPROTO_AH 51 -#endif case IPPROTO_AH: nh = *cp; - advance = ah_print(cp, (const u_char *)ip); + advance = ah_print(cp); + if (advance <= 0) + break; cp += advance; len -= advance; goto again; -#ifndef IPPROTO_ESP -#define IPPROTO_ESP 50 -#endif case IPPROTO_ESP: { int enh, padlen; advance = esp_print(cp, (const u_char *)ip, &enh, &padlen); + if (advance <= 0) + break; cp += advance; len -= advance + padlen; - if (enh < 0) - break; nh = enh & 0xff; goto again; } -#ifndef IPPROTO_IPCOMP -#define IPPROTO_IPCOMP 108 -#endif case IPPROTO_IPCOMP: { int enh; - advance = ipcomp_print(cp, (const u_char *)ip, &enh); + advance = ipcomp_print(cp, &enh); + if (advance <= 0) + break; cp += advance; len -= advance; - if (enh < 0) - break; nh = enh & 0xff; goto again; } case IPPROTO_SCTP: - sctp_print(cp, (const u_char *)ip, len); + sctp_print(cp, (const u_char *)ip, len); break; case IPPROTO_TCP: @@ -381,12 +540,10 @@ again: break; case IPPROTO_ICMP: - icmp_print(cp, len, (const u_char *)ip); + /* pass on the MF bit plus the offset to detect fragments */ + icmp_print(cp, len, (const u_char *)ip, (off & 0x3fff)); break; -#ifndef IPPROTO_IGRP -#define IPPROTO_IGRP 9 -#endif case IPPROTO_IGRP: igrp_print(cp, len, (const u_char *)ip); break; @@ -396,24 +553,18 @@ again: break; case IPPROTO_EGP: - egp_print(cp, len, (const u_char *)ip); + egp_print(cp); break; -#ifndef IPPROTO_OSPF -#define IPPROTO_OSPF 89 -#endif case IPPROTO_OSPF: ospf_print(cp, len, (const u_char *)ip); break; -#ifndef IPPROTO_IGMP -#define IPPROTO_IGMP 2 -#endif case IPPROTO_IGMP: igmp_print(cp, len); break; - case 4: + case IPPROTO_IPV4: /* DVMRP multicast tunnel (ip-in-ip encapsulation) */ ip_print(cp, len); if (! vflag) { @@ -423,41 +574,29 @@ again: break; #ifdef INET6 -#ifndef IP6PROTO_ENCAP -#define IP6PROTO_ENCAP 41 -#endif - case IP6PROTO_ENCAP: + case IPPROTO_IPV6: /* ip6-in-ip encapsulation */ ip6_print(cp, len); break; #endif /*INET6*/ + case IPPROTO_RSVP: + rsvp_print(cp, len); + break; -#ifndef IPPROTO_GRE -#define IPPROTO_GRE 47 -#endif case IPPROTO_GRE: /* do it */ gre_print(cp, len); break; -#ifndef IPPROTO_MOBILE -#define IPPROTO_MOBILE 55 -#endif case IPPROTO_MOBILE: mobile_print(cp, len); break; -#ifndef IPPROTO_PIM -#define IPPROTO_PIM 103 -#endif case IPPROTO_PIM: pim_print(cp, len); break; -#ifndef IPPROTO_VRRP -#define IPPROTO_VRRP 112 -#endif case IPPROTO_VRRP: vrrp_print(cp, len, ip->ip_ttl); break; @@ -470,95 +609,23 @@ again: printf(" %d", len); break; } - } - - /* Ultra quiet now means that all this stuff should be suppressed */ - /* res 3-Nov-98 */ - if (qflag > 1) return; - - - /* - * for fragmented datagrams, print id:size@offset. On all - * but the last stick a "+". For unfragmented datagrams, note - * the don't fragment flag. - */ - len = len0; /* get the original length */ - if (off & 0x3fff) { - /* - * if this isn't the first frag, we're missing the - * next level protocol header. print the ip addr - * and the protocol. - */ - if (off & 0x1fff) { - (void)printf("%s > %s:", ipaddr_string(&ip->ip_src), - ipaddr_string(&ip->ip_dst)); - if ((proto = getprotobynumber(ip->ip_p)) != NULL) - (void)printf(" %s", proto->p_name); - else - (void)printf(" ip-proto-%d", ip->ip_p); - } -#ifndef IP_MF -#define IP_MF 0x2000 -#endif /* IP_MF */ -#ifndef IP_DF -#define IP_DF 0x4000 -#endif /* IP_DF */ - (void)printf(" (frag %d:%u@%d%s)", ntohs(ip->ip_id), len, - (off & 0x1fff) * 8, - (off & IP_MF)? "+" : ""); - - } else if (off & IP_DF) - (void)printf(" (DF)"); - - if (ip->ip_tos) { - (void)printf(" [tos 0x%x", (int)ip->ip_tos); - /* ECN bits */ - if (ip->ip_tos & 0x03) { - switch (ip->ip_tos & 0x03) { - case 1: - (void)printf(",ECT(1)"); - break; - case 2: - (void)printf(",ECT(0)"); - break; - case 3: - (void)printf(",CE"); - } - } - (void)printf("] "); - } - - if (ip->ip_ttl <= 1) - (void)printf(" [ttl %d]", (int)ip->ip_ttl); - - if (vflag) { - int sum; - char *sep = ""; - - printf(" ("); - if (ip->ip_ttl > 1) { - (void)printf("%sttl %d", sep, (int)ip->ip_ttl); - sep = ", "; - } - if ((off & 0x3fff) == 0) { - (void)printf("%sid %d", sep, (int)ntohs(ip->ip_id)); - sep = ", "; - } - (void)printf("%slen %d", sep, (int)ntohs(ip->ip_len)); - sep = ", "; - if ((u_char *)ip + hlen <= snapend) { - sum = in_cksum((const u_short *)ip, hlen, 0); - if (sum != 0) { - (void)printf("%sbad cksum %x!", sep, - ntohs(ip->ip_sum)); - sep = ", "; - } - } - if ((hlen -= sizeof(struct ip)) > 0) { - (void)printf("%soptlen=%d", sep, hlen); - ip_optprint((u_char *)(ip + 1), hlen); - } - printf(")"); + } else { + /* Ultra quiet now means that all this stuff should be suppressed */ + if (qflag > 1) return; + + /* + * if this isn't the first frag, we're missing the + * next level protocol header. print the ip addr + * and the protocol. + */ + if (off & 0x1fff) { + (void)printf("%s > %s:", ipaddr_string(&ip->ip_src), + ipaddr_string(&ip->ip_dst)); + if ((proto = getprotobynumber(ip->ip_p)) != NULL) + (void)printf(" %s", proto->p_name); + else + (void)printf(" ip-proto-%d", ip->ip_p); + } } } @@ -587,3 +654,6 @@ ipN_print(register const u_char *bp, register u_int length) return; } } + + + diff --git a/contrib/tcpdump/print-ip6.c b/contrib/tcpdump/print-ip6.c index 0e8bf025e435..58a0f268d785 100644 --- a/contrib/tcpdump/print-ip6.c +++ b/contrib/tcpdump/print-ip6.c @@ -22,8 +22,8 @@ */ #ifndef lint -static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/print-ip6.c,v 1.21 2001/11/16 02:17:36 itojun Exp $"; +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-ip6.c,v 1.32.2.8 2003/11/24 20:31:22 guy Exp $"; #endif #ifdef HAVE_CONFIG_H @@ -32,22 +32,18 @@ static const char rcsid[] = #ifdef INET6 -#include <sys/param.h> -#include <sys/time.h> -#include <sys/types.h> -#include <sys/socket.h> - -#include <netinet/in.h> +#include <tcpdump-stdinc.h> #include <stdio.h> #include <stdlib.h> -#include <unistd.h> #include <string.h> #include "interface.h" #include "addrtoname.h" +#include "extract.h" #include "ip6.h" +#include "ipproto.h" /* * print an IP6 datagram. @@ -57,52 +53,45 @@ ip6_print(register const u_char *bp, register u_int length) { register const struct ip6_hdr *ip6; register int advance; - register u_int len; + u_int len; + const u_char *ipend; register const u_char *cp; + register u_int payload_len; int nh; int fragmented = 0; u_int flow; - - ip6 = (const struct ip6_hdr *)bp; -#ifdef LBL_ALIGN - /* - * The IP6 header is not 16-byte aligned, so copy into abuf. - */ - if ((u_long)ip6 & 15) { - static u_char *abuf; + ip6 = (const struct ip6_hdr *)bp; - if (abuf == NULL) { - abuf = malloc(snaplen); - if (abuf == NULL) - error("ip6_print: malloc"); - } - memcpy(abuf, ip6, min(length, snaplen)); - snapend += abuf - (u_char *)ip6; - packetp = abuf; - ip6 = (struct ip6_hdr *)abuf; - bp = abuf; - } -#endif TCHECK(*ip6); if (length < sizeof (struct ip6_hdr)) { (void)printf("truncated-ip6 %d", length); return; } - advance = sizeof(struct ip6_hdr); - len = ntohs(ip6->ip6_plen); - if (length < len + advance) + payload_len = EXTRACT_16BITS(&ip6->ip6_plen); + len = payload_len + sizeof(struct ip6_hdr); + if (length < len) (void)printf("truncated-ip6 - %d bytes missing!", - len + advance - length); + len - length); + + /* + * Cut off the snapshot length to the end of the IP payload. + */ + ipend = bp + len; + if (ipend < snapend) + snapend = ipend; cp = (const u_char *)ip6; + advance = sizeof(struct ip6_hdr); nh = ip6->ip6_nxt; - while (cp < snapend) { + while (cp < snapend && advance > 0) { cp += advance; + len -= advance; - if (cp == (const u_char *)(ip6 + 1) - && nh != IPPROTO_TCP && nh != IPPROTO_UDP) { + if (cp == (const u_char *)(ip6 + 1) && + nh != IPPROTO_TCP && nh != IPPROTO_UDP && + nh != IPPROTO_SCTP) { (void)printf("%s > %s: ", ip6addr_string(&ip6->ip6_src), ip6addr_string(&ip6->ip6_dst)); } @@ -123,69 +112,73 @@ ip6_print(register const u_char *bp, register u_int length) nh = *cp; fragmented = 1; break; + + case IPPROTO_MOBILITY_OLD: + case IPPROTO_MOBILITY: + /* + * XXX - we don't use "advance"; the current + * "Mobility Support in IPv6" draft + * (draft-ietf-mobileip-ipv6-24) says that + * the next header field in a mobility header + * should be IPPROTO_NONE, but speaks of + * the possiblity of a future extension in + * which payload can be piggybacked atop a + * mobility header. + */ + advance = mobility_print(cp, (const u_char *)ip6); + nh = *cp; + goto end; case IPPROTO_ROUTING: advance = rt6_print(cp, (const u_char *)ip6); nh = *cp; break; + case IPPROTO_SCTP: + sctp_print(cp, (const u_char *)ip6, len); + goto end; case IPPROTO_TCP: - tcp_print(cp, len + sizeof(struct ip6_hdr) - (cp - bp), - (const u_char *)ip6, fragmented); + tcp_print(cp, len, (const u_char *)ip6, fragmented); goto end; case IPPROTO_UDP: - udp_print(cp, len + sizeof(struct ip6_hdr) - (cp - bp), - (const u_char *)ip6, fragmented); + udp_print(cp, len, (const u_char *)ip6, fragmented); goto end; case IPPROTO_ICMPV6: - icmp6_print(cp, (const u_char *)ip6); + icmp6_print(cp, len, (const u_char *)ip6, fragmented); goto end; case IPPROTO_AH: - advance = ah_print(cp, (const u_char *)ip6); + advance = ah_print(cp); nh = *cp; break; case IPPROTO_ESP: { int enh, padlen; advance = esp_print(cp, (const u_char *)ip6, &enh, &padlen); - if (enh < 0) - goto end; nh = enh & 0xff; len -= padlen; break; } -#ifndef IPPROTO_IPCOMP -#define IPPROTO_IPCOMP 108 -#endif case IPPROTO_IPCOMP: { int enh; - advance = ipcomp_print(cp, (const u_char *)ip6, &enh); - if (enh < 0) - goto end; + advance = ipcomp_print(cp, &enh); nh = enh & 0xff; break; } -#ifndef IPPROTO_PIM -#define IPPROTO_PIM 103 -#endif case IPPROTO_PIM: pim_print(cp, len); goto end; -#ifndef IPPROTO_OSPF -#define IPPROTO_OSPF 89 -#endif case IPPROTO_OSPF: ospf6_print(cp, len); goto end; + case IPPROTO_IPV6: ip6_print(cp, len); goto end; -#ifndef IPPROTO_IPV4 -#define IPPROTO_IPV4 4 -#endif + case IPPROTO_IPV4: ip_print(cp, len); goto end; + case IPPROTO_NONE: (void)printf("no next header"); goto end; @@ -197,8 +190,8 @@ ip6_print(register const u_char *bp, register u_int length) } end: - - flow = ntohl(ip6->ip6_flow); + + flow = EXTRACT_32BITS(&ip6->ip6_flow); #if 0 /* rfc1883 */ if (flow & 0x0f000000) @@ -214,11 +207,11 @@ ip6_print(register const u_char *bp, register u_int length) #endif if (ip6->ip6_hlim <= 1) - (void)printf(" [hlim %d]", (int)ip6->ip6_hlim); + (void)printf(" [hlim %u]", ip6->ip6_hlim); if (vflag) { printf(" ("); - (void)printf("len %d", len); + (void)printf("len %u", payload_len); if (ip6->ip6_hlim > 1) (void)printf(", hlim %d", (int)ip6->ip6_hlim); printf(")"); diff --git a/contrib/tcpdump/print-ipx.c b/contrib/tcpdump/print-ipx.c index 9a4f60a3515b..6a6dfb9a5163 100644 --- a/contrib/tcpdump/print-ipx.c +++ b/contrib/tcpdump/print-ipx.c @@ -25,19 +25,15 @@ */ #ifndef lint -static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/print-ipx.c,v 1.32 2001/10/08 21:25:20 fenner Exp $"; +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-ipx.c,v 1.34.2.2 2003/11/16 08:51:28 guy Exp $"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include <sys/param.h> -#include <sys/time.h> -#include <sys/socket.h> - -#include <netinet/in.h> +#include <tcpdump-stdinc.h> #include <stdlib.h> #include <stdio.h> @@ -63,11 +59,11 @@ ipx_print(const u_char *p, u_int length) const struct ipxHdr *ipx = (const struct ipxHdr *)p; TCHECK(ipx->srcSkt); - (void)printf("%s.%x > ", + (void)printf("%s.%04x > ", ipxaddr_string(EXTRACT_32BITS(ipx->srcNet), ipx->srcNode), EXTRACT_16BITS(&ipx->srcSkt)); - (void)printf("%s.%x:", + (void)printf("%s.%04x:", ipxaddr_string(EXTRACT_32BITS(ipx->dstNet), ipx->dstNode), EXTRACT_16BITS(&ipx->dstSkt)); @@ -86,7 +82,7 @@ ipxaddr_string(u_int32_t net, const u_char *node) { static char line[256]; - snprintf(line, sizeof(line), "%x.%02x:%02x:%02x:%02x:%02x:%02x", + snprintf(line, sizeof(line), "%08x.%02x:%02x:%02x:%02x:%02x:%02x", net, node[0], node[1], node[2], node[3], node[4], node[5]); return line; @@ -151,7 +147,7 @@ ipx_sap_print(const u_short *ipx, u_int length) (void)printf("ipx-sap-nearest-req"); TCHECK(ipx[0]); - (void)printf(" %x", EXTRACT_16BITS(&ipx[0])); + (void)printf(" %s", ipxsap_string(htons(EXTRACT_16BITS(&ipx[0])))); break; case 2: @@ -163,7 +159,7 @@ ipx_sap_print(const u_short *ipx, u_int length) for (i = 0; i < 8 && length > 0; i++) { TCHECK2(ipx[25], 10); - (void)printf(" %x '", EXTRACT_16BITS(&ipx[0])); + (void)printf(" %s '", ipxsap_string(htons(EXTRACT_16BITS(&ipx[0])))); fn_print((u_char *)&ipx[1], (u_char *)&ipx[1] + 48); printf("' addr %s", ipxaddr_string(EXTRACT_32BITS(&ipx[25]), (u_char *)&ipx[27])); @@ -218,4 +214,3 @@ ipx_rip_print(const u_short *ipx, u_int length) trunc: printf("[|ipx %d]", length); } - diff --git a/contrib/tcpdump/print-isoclns.c b/contrib/tcpdump/print-isoclns.c index edc8190a974c..5dc660f1eee3 100644 --- a/contrib/tcpdump/print-isoclns.c +++ b/contrib/tcpdump/print-isoclns.c @@ -27,19 +27,15 @@ */ #ifndef lint -static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/print-isoclns.c,v 1.36.2.2 2002/06/29 04:28:44 guy Exp $ (LBL)"; +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-isoclns.c,v 1.106.2.5 2004/03/24 01:45:26 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include <sys/types.h> -#include <sys/time.h> -#include <sys/socket.h> - -#include <netinet/in.h> +#include <tcpdump-stdinc.h> #include <stdio.h> #include <string.h> @@ -49,19 +45,26 @@ static const char rcsid[] = #include "ethertype.h" #include "ether.h" #include "extract.h" +#include "gmpls.h" #define NLPID_CLNS 129 /* 0x81 */ #define NLPID_ESIS 130 /* 0x82 */ #define NLPID_ISIS 131 /* 0x83 */ #define NLPID_IP6 0x8e -#define NLPID_IP 0xcc +#define NLPID_IP 0xcc #define NLPID_NULLNS 0 +#define IPV4 1 /* AFI value */ +#define IPV6 2 /* AFI value */ + /* * IS-IS is defined in ISO 10589. Look there for protocol definitions. */ #define SYSTEM_ID_LEN ETHER_ADDR_LEN +#define NODE_ID_LEN SYSTEM_ID_LEN+1 +#define LSP_ID_LEN SYSTEM_ID_LEN+2 + #define ISIS_VERSION 1 #define PDU_TYPE_MASK 0x1F #define PRIORITY_MASK 0x7F @@ -76,52 +79,176 @@ static const char rcsid[] = #define L1_PSNP 26 #define L2_PSNP 27 +static struct tok isis_pdu_values[] = { + { L1_LAN_IIH, "L1 Lan IIH"}, + { L2_LAN_IIH, "L2 Lan IIH"}, + { PTP_IIH, "p2p IIH"}, + { L1_LSP, "L1 LSP"}, + { L2_LSP, "L2 LSP"}, + { L1_CSNP, "L1 CSNP"}, + { L2_CSNP, "L2 CSNP"}, + { L1_PSNP, "L1 PSNP"}, + { L2_PSNP, "L2 PSNP"}, + { 0, NULL} +}; /* * A TLV is a tuple of a type, length and a value and is normally used for * encoding information in all sorts of places. This is an enumeration of * the well known types. + * + * list taken from rfc3359 plus some memory from veterans ;-) */ -#define TLV_AREA_ADDR 1 -#define TLV_IS_REACH 2 -#define TLV_ES_REACH 3 -#define TLV_SUMMARY 5 -#define TLV_ISNEIGH 6 -#define TLV_PADDING 8 -#define TLV_LSP 9 -#define TLV_AUTH 10 -#define TLV_CHECKSUM 12 -#define TLV_EXT_IS_REACH 22 -#define TLV_IP_REACH 128 -#define TLV_PROTOCOLS 129 -#define TLV_IP_REACH_EXT 130 -#define TLV_IDRP_INFO 131 -#define TLV_IPADDR 132 -#define TLV_IPAUTH 133 -#define TLV_TE_ROUTER_ID 134 -#define TLV_EXT_IP_REACH 135 -#define TLV_HOSTNAME 137 -#define TLV_RESTART_SIGNALING 211 -#define TLV_MT_IS_REACH 222 -#define TLV_MT_SUPPORTED 229 -#define TLV_IP6ADDR 232 -#define TLV_MT_REACH 235 -#define TLV_IP6_REACH 236 -#define TLV_PTP_ADJ 240 - -#define SUBTLV_EXT_IS_REACH_ADMIN_GROUP 3 -#define SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR 6 -#define SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR 8 -#define SUBTLV_EXT_IS_REACH_MAX_LINK_BW 9 -#define SUBTLV_EXT_IS_REACH_RESERVABLE_BW 10 -#define SUBTLV_EXT_IS_REACH_UNRESERVED_BW 11 -#define SUBTLV_EXT_IS_REACH_TE_METRIC 18 - -#define SUBTLV_AUTH_SIMPLE 1 -#define SUBTLV_AUTH_MD5 54 - -#define ISIS_MASK_LEVEL_BITS(x) ((x)&0x1) +#define TLV_AREA_ADDR 1 /* iso10589 */ +#define TLV_IS_REACH 2 /* iso10589 */ +#define TLV_ESNEIGH 3 /* iso10589 */ +#define TLV_PART_DIS 4 /* iso10589 */ +#define TLV_PREFIX_NEIGH 5 /* iso10589 */ +#define TLV_ISNEIGH 6 /* iso10589 */ +#define TLV_ISNEIGH_VARLEN 7 /* iso10589 */ +#define TLV_PADDING 8 /* iso10589 */ +#define TLV_LSP 9 /* iso10589 */ +#define TLV_AUTH 10 /* iso10589, rfc3567 */ +#define TLV_CHECKSUM 12 /* rfc3358 */ +#define TLV_LSP_BUFFERSIZE 14 /* iso10589 rev2 */ +#define TLV_EXT_IS_REACH 22 /* draft-ietf-isis-traffic-05 */ +#define TLV_IS_ALIAS_ID 24 /* draft-ietf-isis-ext-lsp-frags-02 */ +#define TLV_DECNET_PHASE4 42 +#define TLV_LUCENT_PRIVATE 66 +#define TLV_INT_IP_REACH 128 /* rfc1195, rfc2966 */ +#define TLV_PROTOCOLS 129 /* rfc1195 */ +#define TLV_EXT_IP_REACH 130 /* rfc1195, rfc2966 */ +#define TLV_IDRP_INFO 131 /* rfc1195 */ +#define TLV_IPADDR 132 /* rfc1195 */ +#define TLV_IPAUTH 133 /* rfc1195 */ +#define TLV_TE_ROUTER_ID 134 /* draft-ietf-isis-traffic-05 */ +#define TLV_EXTD_IP_REACH 135 /* draft-ietf-isis-traffic-05 */ +#define TLV_HOSTNAME 137 /* rfc2763 */ +#define TLV_SHARED_RISK_GROUP 138 /* draft-ietf-isis-gmpls-extensions */ +#define TLV_NORTEL_PRIVATE1 176 +#define TLV_NORTEL_PRIVATE2 177 +#define TLV_HOLDTIME 198 /* ES-IS */ +#define TLV_RESTART_SIGNALING 211 /* draft-ietf-isis-restart-01 */ +#define TLV_MT_IS_REACH 222 /* draft-ietf-isis-wg-multi-topology-05 */ +#define TLV_MT_SUPPORTED 229 /* draft-ietf-isis-wg-multi-topology-05 */ +#define TLV_IP6ADDR 232 /* draft-ietf-isis-ipv6-02 */ +#define TLV_MT_IP_REACH 235 /* draft-ietf-isis-wg-multi-topology-05 */ +#define TLV_IP6_REACH 236 /* draft-ietf-isis-ipv6-02 */ +#define TLV_MT_IP6_REACH 237 /* draft-ietf-isis-wg-multi-topology-05 */ +#define TLV_PTP_ADJ 240 /* rfc3373 */ +#define TLV_IIH_SEQNR 241 /* draft-shen-isis-iih-sequence-00 */ +#define TLV_VENDOR_PRIVATE 250 /* draft-ietf-isis-proprietary-tlv-00 */ + +static struct tok isis_tlv_values[] = { + { TLV_AREA_ADDR, "Area address(es)"}, + { TLV_IS_REACH, "IS Reachability"}, + { TLV_ESNEIGH, "ES Neighbor(s)"}, + { TLV_PART_DIS, "Partition DIS"}, + { TLV_PREFIX_NEIGH, "Prefix Neighbors"}, + { TLV_ISNEIGH, "IS Neighbor(s)"}, + { TLV_ISNEIGH_VARLEN, "IS Neighbor(s) (variable length)"}, + { TLV_PADDING, "Padding"}, + { TLV_LSP, "LSP entries"}, + { TLV_AUTH, "Authentication"}, + { TLV_CHECKSUM, "Checksum"}, + { TLV_LSP_BUFFERSIZE, "LSP Buffersize"}, + { TLV_EXT_IS_REACH, "Extended IS Reachability"}, + { TLV_IS_ALIAS_ID, "IS Alias ID"}, + { TLV_DECNET_PHASE4, "DECnet Phase IV"}, + { TLV_LUCENT_PRIVATE, "Lucent Proprietary"}, + { TLV_INT_IP_REACH, "IPv4 Internal Reachability"}, + { TLV_PROTOCOLS, "Protocols supported"}, + { TLV_EXT_IP_REACH, "IPv4 External Reachability"}, + { TLV_IDRP_INFO, "Inter-Domain Information Type"}, + { TLV_IPADDR, "IPv4 Interface address(es)"}, + { TLV_IPAUTH, "IPv4 authentication (deprecated)"}, + { TLV_TE_ROUTER_ID, "Traffic Engineering Router ID"}, + { TLV_EXTD_IP_REACH, "Extended IPv4 Reachability"}, + { TLV_HOSTNAME, "Hostname"}, + { TLV_SHARED_RISK_GROUP, "Shared Risk Link Group"}, + { TLV_NORTEL_PRIVATE1, "Nortel Proprietary"}, + { TLV_NORTEL_PRIVATE2, "Nortel Proprietary"}, + { TLV_HOLDTIME, "Holdtime"}, + { TLV_RESTART_SIGNALING, "Restart Signaling"}, + { TLV_MT_IS_REACH, "Multi Topology IS Reachability"}, + { TLV_MT_SUPPORTED, "Multi Topology"}, + { TLV_IP6ADDR, "IPv6 Interface address(es)"}, + { TLV_MT_IP_REACH, "Multi-Topology IPv4 Reachability"}, + { TLV_IP6_REACH, "IPv6 reachability"}, + { TLV_MT_IP6_REACH, "Multi-Topology IP6 Reachability"}, + { TLV_PTP_ADJ, "Point-to-point Adjacency State"}, + { TLV_IIH_SEQNR, "Hello PDU Sequence Number"}, + { TLV_VENDOR_PRIVATE, "Vendor Private"}, + { 0, NULL } +}; + +#define SUBTLV_EXT_IS_REACH_ADMIN_GROUP 3 /* draft-ietf-isis-traffic-05 */ +#define SUBTLV_EXT_IS_REACH_LINK_LOCAL_REMOTE_ID 4 /* draft-ietf-isis-gmpls-extensions */ +#define SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID 5 /* draft-ietf-isis-traffic-05 */ +#define SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR 6 /* draft-ietf-isis-traffic-05 */ +#define SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR 8 /* draft-ietf-isis-traffic-05 */ +#define SUBTLV_EXT_IS_REACH_MAX_LINK_BW 9 /* draft-ietf-isis-traffic-05 */ +#define SUBTLV_EXT_IS_REACH_RESERVABLE_BW 10 /* draft-ietf-isis-traffic-05 */ +#define SUBTLV_EXT_IS_REACH_UNRESERVED_BW 11 /* draft-ietf-isis-traffic-05 */ +#define SUBTLV_EXT_IS_REACH_TE_METRIC 18 /* draft-ietf-isis-traffic-05 */ +#define SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE 20 /* draft-ietf-isis-gmpls-extensions */ +#define SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR 21 /* draft-ietf-isis-gmpls-extensions */ + +static struct tok isis_ext_is_reach_subtlv_values[] = { + { SUBTLV_EXT_IS_REACH_ADMIN_GROUP, "Administrative groups" }, + { SUBTLV_EXT_IS_REACH_LINK_LOCAL_REMOTE_ID, "Link Local/Remote Identifier" }, + { SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID, "Link Remote Identifier" }, + { SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR, "IPv4 interface address" }, + { SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR, "IPv4 neighbor address" }, + { SUBTLV_EXT_IS_REACH_MAX_LINK_BW, "Maximum link bandwidth" }, + { SUBTLV_EXT_IS_REACH_RESERVABLE_BW, "Reservable link bandwidth" }, + { SUBTLV_EXT_IS_REACH_UNRESERVED_BW, "Unreserved bandwidth" }, + { SUBTLV_EXT_IS_REACH_TE_METRIC, "Traffic Engineering Metric" }, + { SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE, "Link Protection Type" }, + { SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR, "Interface Switching Capability" }, + { 250, "Reserved for cisco specific extensions" }, + { 251, "Reserved for cisco specific extensions" }, + { 252, "Reserved for cisco specific extensions" }, + { 253, "Reserved for cisco specific extensions" }, + { 254, "Reserved for cisco specific extensions" }, + { 255, "Reserved for future expansion" }, + { 0, NULL } +}; + +#define SUBTLV_EXTD_IP_REACH_ADMIN_TAG32 1 +#define SUBTLV_EXTD_IP_REACH_ADMIN_TAG64 2 + +static struct tok isis_ext_ip_reach_subtlv_values[] = { + { SUBTLV_EXTD_IP_REACH_ADMIN_TAG32, "32-Bit Administrative tag" }, + { SUBTLV_EXTD_IP_REACH_ADMIN_TAG64, "64-Bit Administrative tag" }, + { 0, NULL } +}; + +#define SUBTLV_AUTH_SIMPLE 1 +#define SUBTLV_AUTH_MD5 54 +#define SUBTLV_AUTH_MD5_LEN 16 +#define SUBTLV_AUTH_PRIVATE 255 + +static struct tok isis_subtlv_auth_values[] = { + { SUBTLV_AUTH_SIMPLE, "simple text password"}, + { SUBTLV_AUTH_MD5, "HMAC-MD5 password"}, + { SUBTLV_AUTH_PRIVATE, "Routing Domain private password"}, + { 0, NULL } +}; + +#define SUBTLV_IDRP_RES 0 +#define SUBTLV_IDRP_LOCAL 1 +#define SUBTLV_IDRP_ASN 2 + +static struct tok isis_subtlv_idrp_values[] = { + { SUBTLV_IDRP_RES, "Reserved"}, + { SUBTLV_IDRP_LOCAL, "Routing-Domain Specific"}, + { SUBTLV_IDRP_ASN, "AS Number Tag"}, + { 0, NULL} +}; + +#define ISIS_8BIT_MASK(x) ((x)&0xff) #define ISIS_MASK_LSP_OL_BIT(x) ((x)&0x4) #define ISIS_MASK_LSP_ISTYPE_BITS(x) ((x)&0x3) @@ -132,39 +259,62 @@ static const char rcsid[] = #define ISIS_MASK_LSP_ATT_DELAY_BIT(x) ((x)&0x10) #define ISIS_MASK_LSP_ATT_DEFAULT_BIT(x) ((x)&0x8) -#define ISIS_MASK_TLV_EXT_IP_UPDOWN(x) ((x)&0x80) -#define ISIS_MASK_TLV_EXT_IP_SUBTLV(x) ((x)&0x40) +#define ISIS_MASK_MTID(x) ((x)&0x0fff) +#define ISIS_MASK_MTFLAGS(x) ((x)&0xf000) -#define ISIS_MASK_TLV_IP6_UPDOWN(x) ((x)&0x80) -#define ISIS_MASK_TLV_IP6_IE(x) ((x)&0x40) -#define ISIS_MASK_TLV_IP6_SUBTLV(x) ((x)&0x20) +static struct tok isis_mt_flag_values[] = { + { 0x4000, "sub-TLVs present"}, + { 0x8000, "ATT bit set"}, + { 0, NULL} +}; + +#define ISIS_MASK_TLV_EXTD_IP_UPDOWN(x) ((x)&0x80) +#define ISIS_MASK_TLV_EXTD_IP_SUBTLV(x) ((x)&0x40) -#define ISIS_MASK_RESTART_RR(x) ((x)&0x1) -#define ISIS_MASK_RESTART_RA(x) ((x)&0x2) +#define ISIS_MASK_TLV_EXTD_IP6_IE(x) ((x)&0x40) +#define ISIS_MASK_TLV_EXTD_IP6_SUBTLV(x) ((x)&0x20) #define ISIS_LSP_TLV_METRIC_SUPPORTED(x) ((x)&0x80) #define ISIS_LSP_TLV_METRIC_IE(x) ((x)&0x40) #define ISIS_LSP_TLV_METRIC_UPDOWN(x) ((x)&0x80) #define ISIS_LSP_TLV_METRIC_VALUE(x) ((x)&0x3f) +#define ISIS_MASK_TLV_SHARED_RISK_GROUP(x) ((x)&0x1) + +static struct tok isis_mt_values[] = { + { 0, "IPv4 unicast"}, + { 1, "In-Band Management"}, + { 2, "IPv6 unicast"}, + { 3, "Multicast"}, + { 4095, "Development, Experimental or Proprietary"}, + { 0, NULL } +}; + +static struct tok isis_iih_circuit_type_values[] = { + { 1, "Level 1 only"}, + { 2, "Level 2 only"}, + { 3, "Level 1, Level 2"}, + { 0, NULL} +}; + #define ISIS_LSP_TYPE_UNUSED0 0 #define ISIS_LSP_TYPE_LEVEL_1 1 #define ISIS_LSP_TYPE_UNUSED2 2 #define ISIS_LSP_TYPE_LEVEL_2 3 static struct tok isis_lsp_istype_values[] = { - { ISIS_LSP_TYPE_UNUSED0, "Unused 0x0 (invalid)"}, - { ISIS_LSP_TYPE_LEVEL_1, "L1 IS"}, - { ISIS_LSP_TYPE_UNUSED2, "Unused 0x2 (invalid)"}, - { ISIS_LSP_TYPE_LEVEL_2, "L1L2 IS"}, - { 0, NULL } + { ISIS_LSP_TYPE_UNUSED0, "Unused 0x0 (invalid)"}, + { ISIS_LSP_TYPE_LEVEL_1, "L1 IS"}, + { ISIS_LSP_TYPE_UNUSED2, "Unused 0x2 (invalid)"}, + { ISIS_LSP_TYPE_LEVEL_2, "L1L2 IS"}, + { 0, NULL } }; -static struct tok isis_nlpid_values[] = { - { NLPID_CLNS, "CLNS"}, - { NLPID_IP, "IPv4"}, - { NLPID_IP6, "IPv6"}, - { 0, "unknown" } +static struct tok osi_nlpid_values[] = { + { NLPID_CLNS, "CLNS"}, + { NLPID_IP, "IPv4"}, + { NLPID_IP6, "IPv6"}, + { 0, NULL } }; /* @@ -176,98 +326,145 @@ static struct tok isis_nlpid_values[] = { #define ISIS_PTP_ADJ_INIT 1 #define ISIS_PTP_ADJ_DOWN 2 -static int osi_cksum(const u_char *, u_int, u_char *); -static void esis_print(const u_char *, u_int); -static int isis_print(const u_char *, u_int); - static struct tok isis_ptp_adjancey_values[] = { - { ISIS_PTP_ADJ_UP, "Up" }, - { ISIS_PTP_ADJ_INIT, "Initializing" }, - { ISIS_PTP_ADJ_DOWN, "Down" } + { ISIS_PTP_ADJ_UP, "Up" }, + { ISIS_PTP_ADJ_INIT, "Initializing" }, + { ISIS_PTP_ADJ_DOWN, "Down" }, + { 0, NULL} }; struct isis_tlv_ptp_adj { - u_char adjacency_state; - u_char ext_local_circuit_id[4]; - u_char neighbor_sysid[SYSTEM_ID_LEN]; - u_char neighbor_ext_local_circuit_id[4]; + u_int8_t adjacency_state; + u_int8_t extd_local_circuit_id[4]; + u_int8_t neighbor_sysid[SYSTEM_ID_LEN]; + u_int8_t neighbor_extd_local_circuit_id[4]; }; -struct isis_tlv_ip_reach { - u_char metric_default; - u_char metric_delay; - u_char metric_expense; - u_char metric_error; - u_char prefix[4]; - u_char mask[4]; +static int osi_cksum(const u_int8_t *, u_int); +static void esis_print(const u_int8_t *, u_int); +static int isis_print(const u_int8_t *, u_int); + +struct isis_metric_block { + u_int8_t metric_default; + u_int8_t metric_delay; + u_int8_t metric_expense; + u_int8_t metric_error; }; struct isis_tlv_is_reach { - u_char metric_default; - u_char metric_delay; - u_char metric_expense; - u_char metric_error; - u_char neighbor_nodeid[SYSTEM_ID_LEN+1]; + struct isis_metric_block isis_metric_block; + u_int8_t neighbor_nodeid[NODE_ID_LEN]; +}; + +struct isis_tlv_es_reach { + struct isis_metric_block isis_metric_block; + u_int8_t neighbor_sysid[SYSTEM_ID_LEN]; }; +struct isis_tlv_ip_reach { + struct isis_metric_block isis_metric_block; + u_int8_t prefix[4]; + u_int8_t mask[4]; +}; + +static struct tok isis_is_reach_virtual_values[] = { + { 0, "IsNotVirtual"}, + { 1, "IsVirtual"}, + { 0, NULL } +}; + +static struct tok isis_restart_flag_values[] = { + { 0x1, "Restart Request"}, + { 0x2, "Restart Acknowledgement"}, + { 0, NULL } +}; struct isis_common_header { - u_char nlpid; - u_char fixed_len; - u_char version; /* Protocol version? */ - u_char id_length; - u_char pdu_type; /* 3 MSbs are reserved */ - u_char pkt_version; /* Packet format version? */ - u_char reserved; - u_char max_area; + u_int8_t nlpid; + u_int8_t fixed_len; + u_int8_t version; /* Protocol version */ + u_int8_t id_length; + u_int8_t pdu_type; /* 3 MSbits are reserved */ + u_int8_t pdu_version; /* Packet format version */ + u_int8_t reserved; + u_int8_t max_area; }; struct isis_iih_lan_header { - u_char circuit_type; - u_char source_id[SYSTEM_ID_LEN]; - u_char holding_time[2]; - u_char pdu_len[2]; - u_char priority; - u_char lan_id[SYSTEM_ID_LEN+1]; + u_int8_t circuit_type; + u_int8_t source_id[SYSTEM_ID_LEN]; + u_int8_t holding_time[2]; + u_int8_t pdu_len[2]; + u_int8_t priority; + u_int8_t lan_id[NODE_ID_LEN]; }; struct isis_iih_ptp_header { - u_char circuit_type; - u_char source_id[SYSTEM_ID_LEN]; - u_char holding_time[2]; - u_char pdu_len[2]; - u_char circuit_id; + u_int8_t circuit_type; + u_int8_t source_id[SYSTEM_ID_LEN]; + u_int8_t holding_time[2]; + u_int8_t pdu_len[2]; + u_int8_t circuit_id; }; struct isis_lsp_header { - u_char pdu_len[2]; - u_char remaining_lifetime[2]; - u_char lsp_id[SYSTEM_ID_LEN+2]; - u_char sequence_number[4]; - u_char checksum[2]; - u_char typeblock; + u_int8_t pdu_len[2]; + u_int8_t remaining_lifetime[2]; + u_int8_t lsp_id[LSP_ID_LEN]; + u_int8_t sequence_number[4]; + u_int8_t checksum[2]; + u_int8_t typeblock; }; struct isis_csnp_header { - u_char pdu_len[2]; - u_char source_id[SYSTEM_ID_LEN+1]; - u_char start_lsp_id[SYSTEM_ID_LEN+2]; - u_char end_lsp_id[SYSTEM_ID_LEN+2]; + u_int8_t pdu_len[2]; + u_int8_t source_id[NODE_ID_LEN]; + u_int8_t start_lsp_id[LSP_ID_LEN]; + u_int8_t end_lsp_id[LSP_ID_LEN]; }; struct isis_psnp_header { - u_char pdu_len[2]; - u_char source_id[SYSTEM_ID_LEN+1]; + u_int8_t pdu_len[2]; + u_int8_t source_id[NODE_ID_LEN]; }; struct isis_tlv_lsp { - u_char remaining_lifetime[2]; - u_char lsp_id[SYSTEM_ID_LEN+2]; - u_char sequence_number[4]; - u_char checksum[2]; + u_int8_t remaining_lifetime[2]; + u_int8_t lsp_id[LSP_ID_LEN]; + u_int8_t sequence_number[4]; + u_int8_t checksum[2]; }; - + +static char * +print_nsap(register const u_int8_t *pptr, register int nsap_length) +{ + int nsap_idx; + static char nsap_ascii_output[sizeof("xx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xx")]; + char *junk_buf = nsap_ascii_output; + + if (nsap_length < 1 || nsap_length > 20) { + snprintf(nsap_ascii_output, sizeof(nsap_ascii_output), + "illegal length"); + return (nsap_ascii_output); + } + + for (nsap_idx = 0; nsap_idx < nsap_length; nsap_idx++) { + if (!TTEST2(*pptr, 1)) + return (0); + snprintf(junk_buf, + sizeof(nsap_ascii_output) - (junk_buf - nsap_ascii_output), + "%02x", *pptr++); + junk_buf += strlen(junk_buf); + if (((nsap_idx & 1) == 0) && + (nsap_idx + 1 < nsap_length)) { + *junk_buf++ = '.'; + } + } + *(junk_buf) = '\0'; + return (nsap_ascii_output); +} + #define ISIS_COMMON_HEADER_SIZE (sizeof(struct isis_common_header)) #define ISIS_IIH_LAN_HEADER_SIZE (sizeof(struct isis_iih_lan_header)) #define ISIS_IIH_PTP_HEADER_SIZE (sizeof(struct isis_iih_ptp_header)) @@ -275,69 +472,40 @@ struct isis_tlv_lsp { #define ISIS_CSNP_HEADER_SIZE (sizeof(struct isis_csnp_header)) #define ISIS_PSNP_HEADER_SIZE (sizeof(struct isis_psnp_header)) -void isoclns_print(const u_char *p, u_int length, u_int caplen, - const u_char *esrc, const u_char *edst) +void isoclns_print(const u_int8_t *p, u_int length, u_int caplen) { - u_char pdu_type; const struct isis_common_header *header; - + header = (const struct isis_common_header *)p; - pdu_type = header->pdu_type & PDU_TYPE_MASK; - - if (caplen < 1) { - printf("[|iso-clns] "); - if (!eflag && esrc != NULL && edst != NULL) - printf("%s > %s", - etheraddr_string(esrc), - etheraddr_string(edst)); - return; - } + + printf("%sOSI", caplen < 1 ? "|" : ""); + + if (caplen < 1) /* enough bytes on the wire ? */ + return; switch (*p) { case NLPID_CLNS: - (void)printf("CLNS(%d)", length); - if (!eflag && esrc != NULL && edst != NULL) - (void)printf(", %s > %s", - etheraddr_string(esrc), - etheraddr_string(edst)); + (void)printf(", CLNS, length %u", length); break; case NLPID_ESIS: - (void)printf("ESIS"); - if (!eflag && esrc != NULL && edst != NULL) - (void)printf(", %s > %s", - etheraddr_string(esrc), - etheraddr_string(edst)); esis_print(p, length); return; case NLPID_ISIS: - (void)printf("ISIS(%d)", length); - if (!eflag && esrc != NULL && edst != NULL) - (void)printf(", %s > %s", - etheraddr_string(esrc), - etheraddr_string(edst)); if (!isis_print(p, length)) - default_print_unaligned(p, caplen); + print_unknown_data(p,"\n\t",caplen); break; case NLPID_NULLNS: - (void)printf("ISO NULLNS(%d)", length); - if (!eflag && esrc != NULL && edst != NULL) - (void)printf(", %s > %s", - etheraddr_string(esrc), - etheraddr_string(edst)); + (void)printf(", ISO NULLNS, length: %u", length); break; default: - (void)printf("CLNS %02x(%d)", p[0], length); - if (!eflag && esrc != NULL && edst != NULL) - (void)printf(", %s > %s", - etheraddr_string(esrc), - etheraddr_string(edst)); + (void)printf(", Unknown NLPID 0x%02x, length: %u", p[0], length); if (caplen > 1) - default_print_unaligned(p, caplen); + print_unknown_data(p,"\n\t",caplen); break; } } @@ -346,21 +514,27 @@ void isoclns_print(const u_char *p, u_int length, u_int caplen, #define ESIS_ESH 2 #define ESIS_ISH 4 +static struct tok esis_values[] = { + { ESIS_REDIRECT, "redirect"}, + { ESIS_ESH, "ESH"}, + { ESIS_ISH, "ISH"}, + { 0, NULL } +}; + struct esis_hdr { - u_char version; - u_char reserved; - u_char type; - u_char tmo[2]; - u_char cksum[2]; + u_int8_t version; + u_int8_t reserved; + u_int8_t type; + u_int8_t tmo[2]; + u_int8_t cksum[2]; }; static void -esis_print(const u_char *p, u_int length) +esis_print(const u_int8_t *p, u_int length) { - const u_char *ep; + const u_int8_t *ep; u_int li; const struct esis_hdr *eh; - u_char off[2]; if (length <= 2) { if (qflag) @@ -389,28 +563,16 @@ esis_print(const u_char *p, u_int length) } return; } - switch (eh->type & 0x1f) { - case ESIS_REDIRECT: - printf(" redirect"); - break; - - case ESIS_ESH: - printf(" esh"); - break; + printf(", ES-IS, %s, length %u", + tok2str(esis_values,"unknown type: %u",eh->type & 0x1f), + length); - case ESIS_ISH: - printf(" ish"); - break; + if(vflag < 1) + return; - default: - printf(" type %d", eh->type & 0x1f); - break; - } - off[0] = eh->cksum[0]; - off[1] = eh->cksum[1]; - if (vflag && osi_cksum(p, li, off)) { - printf(" bad cksum (got %02x%02x)", + if (vflag && osi_cksum(p, li)) { + printf(" bad cksum (got 0x%02x%02x)", eh->cksum[1], eh->cksum[0]); default_print(p, length); return; @@ -424,12 +586,12 @@ esis_print(const u_char *p, u_int length) switch (eh->type & 0x1f) { case ESIS_REDIRECT: { - const u_char *dst, *snpa, *is; + const u_int8_t *dst, *snpa, *is; dst = p; p += *p + 1; if (p > snapend) return; - printf("\n\t\t\t %s", isonsap_string(dst)); + printf("\n\t\t %s", isonsap_string(dst)); snpa = p; p += *p + 1; is = p; p += *p + 1; if (p > snapend) @@ -445,13 +607,12 @@ esis_print(const u_char *p, u_int length) li = ep - p; break; } -#if 0 + case ESIS_ESH: - printf(" esh"); break; -#endif + case ESIS_ISH: { - const u_char *is; + const u_int8_t *is; is = p; p += *p + 1; if (p > ep) { @@ -461,196 +622,166 @@ esis_print(const u_char *p, u_int length) if (p > snapend) return; if (!qflag) - printf("\n\t\t\t %s", isonsap_string(is)); + printf("\n\tNET: %s", print_nsap(is+1,*is)); li = ep - p; break; } default: - (void)printf(" len=%d", length); - if (length && p < snapend) { - length = snapend - p; - default_print(p, length); - } - return; + if (vflag <= 1) { + if (p < snapend) + print_unknown_data(p,"\n\t ",snapend-p); + } + return; } + + /* hexdump - FIXME ? */ + if (vflag > 1) { + if (p < snapend) + print_unknown_data(p,"\n\t ",snapend-p); + } if (vflag) while (p < ep && li) { u_int op, opli; - const u_char *q; + const u_int8_t *q; if (snapend - p < 2) return; if (li < 2) { - printf(" bad opts/li"); + printf(", bad opts/li"); return; } op = *p++; opli = *p++; li -= 2; if (opli > li) { - printf(" opt (%d) too long", op); + printf(", opt (%d) too long", op); return; } li -= opli; q = p; p += opli; + if (snapend < p) return; - if (op == 198 && opli == 2) { - printf(" tmo=%d", q[0] * 256 + q[1]); + + if (op == TLV_HOLDTIME && opli == 2) { + printf("\n\tholdtime: %us", EXTRACT_16BITS(q)); continue; } - printf (" %d:<", op); - while (opli-- > 0) - printf("%02x", *q++); - printf (">"); - } -} -/* - * print_nsap - * Print out an NSAP. - */ -static int -print_nsap(register const u_char *cp, register int length) -{ - int i; + if (op == TLV_PROTOCOLS && opli >= 1) { + printf("\n\t%s (length: %u): %s", + tok2str(isis_tlv_values, "unknown", op), + opli, + tok2str(osi_nlpid_values,"Unknown 0x%02x",*q)); + continue; + } - for (i = 0; i < length; i++) { - if (!TTEST2(*cp, 1)) - return (0); - printf("%02x", *cp++); - if (((i & 1) == 0) && (i + 1 < length)) { - printf("."); + print_unknown_data(q,"\n\t ",opli); } - } - return (1); } -static int -isis_print_sysid(const u_char *cp) +/* shared routine for printing system, node and lsp-ids */ +static char * +isis_print_id(const u_int8_t *cp, int id_len) { - int i; - - for (i = 1; i <= 6; i++) { - if (!TTEST2(*cp, 1)) - return (0); - printf("%02x", *cp++); - if ((i==2)^(i==4)) { - printf("."); - } + int i; + static char id[sizeof("xxxx.xxxx.xxxx.yy-zz")]; + char *pos = id; + + for (i = 1; i <= SYSTEM_ID_LEN; i++) { + snprintf(pos, sizeof(id) - (pos - id), "%02x", *cp++); + pos += strlen(pos); + if (i == 2 || i == 4) + *pos++ = '.'; } - return (1); + if (id_len >= NODE_ID_LEN) { + snprintf(pos, sizeof(id) - (pos - id), ".%02x", *cp++); + pos += strlen(pos); + } + if (id_len == LSP_ID_LEN) + snprintf(pos, sizeof(id) - (pos - id), "-%02x", *cp); + return (id); } +/* print the 4-byte metric block which is common found in the old-style TLVs */ static int -isis_print_nodeid(const u_char *cp) -{ - int i; - - for (i = 1; i <= 7; i++) { - if (!TTEST2(*cp, 1)) - return (0); - printf("%02x", *cp++); - if ((i & 1) == 0) { - printf("."); - } - } - return (1); -} - -static void -isis_print_lspid(const u_char *cp) +isis_print_metric_block (const struct isis_metric_block *isis_metric_block) { - int i; - - for (i = 1; i <= 7; i++) { - printf("%02x", *cp++); - if ((i & 1) == 0) - printf("."); - } - printf("-%02x", *cp); + printf(", Default Metric: %d, %s", + ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_default), + ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_default) ? "External" : "Internal"); + if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block->metric_delay)) + printf("\n\t\t Delay Metric: %d, %s", + ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_delay), + ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_delay) ? "External" : "Internal"); + if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block->metric_expense)) + printf("\n\t\t Expense Metric: %d, %s", + ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_expense), + ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_expense) ? "External" : "Internal"); + if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block->metric_error)) + printf("\n\t\t Error Metric: %d, %s", + ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_error), + ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_error) ? "External" : "Internal"); + + return(1); /* everything is ok */ } static int -isis_print_tlv_ip_reach (const u_char *cp, int length) +isis_print_tlv_ip_reach (const u_int8_t *cp, const char *ident, int length) { - u_int bitmasks[33] = { - 0x00000000, - 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000, - 0xf8000000, 0xfc000000, 0xfe000000, 0xff000000, - 0xff800000, 0xffc00000, 0xffe00000, 0xfff00000, - 0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000, - 0xffff8000, 0xffffc000, 0xffffe000, 0xfffff000, - 0xfffff800, 0xfffffc00, 0xfffffe00, 0xffffff00, - 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0, - 0xfffffff8, 0xfffffffc, 0xfffffffe, 0xffffffff - }; - u_int mask; int prefix_len; const struct isis_tlv_ip_reach *tlv_ip_reach; tlv_ip_reach = (const struct isis_tlv_ip_reach *)cp; while (length > 0) { - if (length < sizeof(*tlv_ip_reach)) { - printf("short IP reachability (%d vs %lu)", length, - (unsigned long)sizeof(*tlv_ip_reach)); + if ((size_t)length < sizeof(*tlv_ip_reach)) { + printf("short IPv4 Reachability (%d vs %lu)", + length, + (unsigned long)sizeof(*tlv_ip_reach)); return (0); } if (!TTEST(*tlv_ip_reach)) return (0); - mask = EXTRACT_32BITS(tlv_ip_reach->mask); - prefix_len = 0; - - while (prefix_len <= 33) { - if (bitmasks[prefix_len++] == mask) { - prefix_len--; - break; - } - } + prefix_len = mask2plen(EXTRACT_32BITS(tlv_ip_reach->mask)); - /* - * 34 indicates no match -> must be a discontiguous netmask - * lets dump the mask, otherwise print the prefix_len - */ - if (prefix_len == 34) - printf("\n\t\t\tIPv4 prefix: %u.%u.%u.%u mask %u.%u.%u.%u", - (tlv_ip_reach->prefix)[0], - (tlv_ip_reach->prefix)[1], - (tlv_ip_reach->prefix)[2], - (tlv_ip_reach->prefix)[3], - (tlv_ip_reach->mask)[0], (tlv_ip_reach->mask)[1], - (tlv_ip_reach->mask)[2], (tlv_ip_reach->mask)[3]); - else - printf("\n\t\t\tIPv4 prefix: %u.%u.%u.%u/%u", - (tlv_ip_reach->prefix)[0], - (tlv_ip_reach->prefix)[1], - (tlv_ip_reach->prefix)[2], - (tlv_ip_reach->prefix)[3], prefix_len); - - printf("\n\t\t\t Default Metric: %02d, %s, Distribution: %s", - ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->metric_default), - ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->metric_default) ? "External" : "Internal", - ISIS_LSP_TLV_METRIC_UPDOWN(tlv_ip_reach->metric_default) ? "down" : "up"); - - if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->metric_delay)) - printf("\n\t\t\t Delay Metric: %02d, %s", - ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->metric_delay), - ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->metric_delay) ? "External" : "Internal"); - - if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->metric_expense)) - printf("\n\t\t\t Expense Metric: %02d, %s", - ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->metric_expense), - ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->metric_expense) ? "External" : "Internal"); - - if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->metric_error)) - printf("\n\t\t\t Error Metric: %02d, %s", - ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->metric_error), - ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->metric_error) ? "External" : "Internal"); + if (prefix_len == -1) + printf("%sIPv4 prefix: %s mask %s", + ident, + ipaddr_string((tlv_ip_reach->prefix)), + ipaddr_string((tlv_ip_reach->mask))); + else + printf("%sIPv4 prefix: %15s/%u", + ident, + ipaddr_string((tlv_ip_reach->prefix)), + prefix_len); + + printf(", Distribution: %s, Metric: %u, %s", + ISIS_LSP_TLV_METRIC_UPDOWN(tlv_ip_reach->isis_metric_block.metric_default) ? "down" : "up", + ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_default), + ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_default) ? "External" : "Internal"); + + if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->isis_metric_block.metric_delay)) + printf("%s Delay Metric: %u, %s", + ident, + ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_delay), + ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_delay) ? "External" : "Internal"); + + if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->isis_metric_block.metric_expense)) + printf("%s Expense Metric: %u, %s", + ident, + ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_expense), + ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_expense) ? "External" : "Internal"); + + if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->isis_metric_block.metric_error)) + printf("%s Error Metric: %u, %s", + ident, + ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_error), + ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_error) ? "External" : "Internal"); length -= sizeof(struct isis_tlv_ip_reach); tlv_ip_reach++; @@ -659,11 +790,348 @@ isis_print_tlv_ip_reach (const u_char *cp, int length) } /* + * this is the common IP-REACH subTLV decoder it is called + * from various EXTD-IP REACH TLVs (135,235,236,237) + */ + +static int +isis_print_ip_reach_subtlv (const u_int8_t *tptr,int subt,int subl,const char *ident) { + + /* first lets see if we know the subTLVs name*/ + printf("%s%s subTLV #%u, length: %u", + ident, + tok2str(isis_ext_ip_reach_subtlv_values, + "unknown", + subt), + subt, + subl); + + if (!TTEST2(*tptr,subl)) + goto trunctlv; + + switch(subt) { + case SUBTLV_EXTD_IP_REACH_ADMIN_TAG32: + while (subl >= 4) { + printf(", 0x%08x (=%u)", + EXTRACT_32BITS(tptr), + EXTRACT_32BITS(tptr)); + tptr+=4; + subl-=4; + } + break; + case SUBTLV_EXTD_IP_REACH_ADMIN_TAG64: + while (subl >= 8) { + printf(", 0x%08x%08x", + EXTRACT_32BITS(tptr), + EXTRACT_32BITS(tptr+4)); + tptr+=8; + subl-=8; + } + break; + default: + if(!print_unknown_data(tptr,"\n\t\t ", + subl)) + return(0); + break; + } + return(1); + +trunctlv: + printf("%spacket exceeded snapshot",ident); + return(0); +} + +/* + * this is the common IS-REACH subTLV decoder it is called + * from isis_print_ext_is_reach() + */ + +static int +isis_print_is_reach_subtlv (const u_int8_t *tptr,int subt,int subl,const char *ident) { + + int priority_level; + union { /* int to float conversion buffer for several subTLVs */ + float f; + u_int32_t i; + } bw; + + /* first lets see if we know the subTLVs name*/ + printf("%s%s subTLV #%u, length: %u", + ident, + tok2str(isis_ext_is_reach_subtlv_values, + "unknown", + subt), + subt, + subl); + + if (!TTEST2(*tptr,subl)) + goto trunctlv; + + switch(subt) { + case SUBTLV_EXT_IS_REACH_ADMIN_GROUP: + case SUBTLV_EXT_IS_REACH_LINK_LOCAL_REMOTE_ID: + case SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID: + if (subl >= 4) { + printf(", 0x%08x", EXTRACT_32BITS(tptr)); + if (subl == 8) /* draft-ietf-isis-gmpls-extensions */ + printf(", 0x%08x", EXTRACT_32BITS(tptr+4)); + } + break; + case SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR: + case SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR: + if (subl >= 4) + printf(", %s", ipaddr_string(tptr)); + break; + case SUBTLV_EXT_IS_REACH_MAX_LINK_BW : + case SUBTLV_EXT_IS_REACH_RESERVABLE_BW: + if (subl >= 4) { + bw.i = EXTRACT_32BITS(tptr); + printf(", %.3f Mbps", bw.f*8/1000000 ); + } + break; + case SUBTLV_EXT_IS_REACH_UNRESERVED_BW : + if (subl >= 32) { + for (priority_level = 0; priority_level < 8; priority_level++) { + bw.i = EXTRACT_32BITS(tptr); + printf("%s priority level %d: %.3f Mbps", + ident, + priority_level, + bw.f*8/1000000 ); + tptr+=4; + } + } + break; + case SUBTLV_EXT_IS_REACH_TE_METRIC: + if (subl >= 3) + printf(", %u", EXTRACT_24BITS(tptr)); + break; + case SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE: + if (subl >= 2) { + printf(", %s, Priority %u", + bittok2str(gmpls_link_prot_values, "none", *tptr), + *(tptr+1)); + } + break; + case SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR: + if (subl >= 36) { + printf("%s Interface Switching Capability:%s", + ident, + tok2str(gmpls_switch_cap_values, "Unknown", *(tptr))); + printf(", LSP Encoding: %s", + tok2str(gmpls_encoding_values, "Unknown", *(tptr+1))); + tptr+=4; + printf("%s Max LSP Bandwidth:",ident); + for (priority_level = 0; priority_level < 8; priority_level++) { + bw.i = EXTRACT_32BITS(tptr); + printf("%s priority level %d: %.3f Mbps", + ident, + priority_level, + bw.f*8/1000000 ); + tptr+=4; + } + subl-=36; + /* there is some optional stuff left to decode but this is as of yet + not specified so just lets hexdump what is left */ + if(subl>0){ + if(!print_unknown_data(tptr,"\n\t\t ", + subl-36)) + return(0); + } + } + break; + default: + if(!print_unknown_data(tptr,"\n\t\t ", + subl)) + return(0); + break; + } + return(1); + +trunctlv: + printf("%spacket exceeded snapshot",ident); + return(0); +} + + +/* + * this is the common IS-REACH decoder it is called + * from various EXTD-IS REACH style TLVs (22,24,222) + */ + +static int +isis_print_ext_is_reach (const u_int8_t *tptr,const char *ident, int tlv_type) { + + char ident_buffer[20]; + int subtlv_type,subtlv_len,subtlv_sum_len; + int proc_bytes = 0; /* how many bytes did we process ? */ + + if (!TTEST2(*tptr, NODE_ID_LEN)) + return(0); + + printf("%sIS Neighbor: %s", ident, isis_print_id(tptr, NODE_ID_LEN)); + tptr+=(NODE_ID_LEN); + + if (tlv_type != TLV_IS_ALIAS_ID) { /* the Alias TLV Metric field is implicit 0 */ + if (!TTEST2(*tptr, 3)) /* and is therefore skipped */ + return(0); + printf(", Metric: %d",EXTRACT_24BITS(tptr)); + tptr+=3; + } + + if (!TTEST2(*tptr, 1)) + return(0); + subtlv_sum_len=*(tptr++); /* read out subTLV length */ + proc_bytes=NODE_ID_LEN+3+1; + printf(", %ssub-TLVs present",subtlv_sum_len ? "" : "no "); + if (subtlv_sum_len) { + printf(" (%u)",subtlv_sum_len); + while (subtlv_sum_len>0) { + if (!TTEST2(*tptr,2)) + return(0); + subtlv_type=*(tptr++); + subtlv_len=*(tptr++); + /* prepend the ident string */ + snprintf(ident_buffer, sizeof(ident_buffer), "%s ",ident); + if(!isis_print_is_reach_subtlv(tptr,subtlv_type,subtlv_len,ident_buffer)) + return(0); + tptr+=subtlv_len; + subtlv_sum_len-=(subtlv_len+2); + proc_bytes+=(subtlv_len+2); + } + } + return(proc_bytes); +} + +/* + * this is the common Multi Topology ID decoder + * it is called from various MT-TLVs (222,229,235,237) + */ + +static int +isis_print_mtid (const u_int8_t *tptr,const char *ident) { + + if (!TTEST2(*tptr, 2)) + return(0); + + printf("%s%s", + ident, + tok2str(isis_mt_values, + "Reserved for IETF Consensus", + ISIS_MASK_MTID(EXTRACT_16BITS(tptr)))); + + printf(" Topology (0x%03x), Flags: [%s]", + ISIS_MASK_MTID(EXTRACT_16BITS(tptr)), + bittok2str(isis_mt_flag_values, "none",ISIS_MASK_MTFLAGS(EXTRACT_16BITS(tptr)))); + + return(2); +} + +/* + * this is the common extended IP reach decoder + * it is called from TLVs (135,235,236,237) + * we process the TLV and optional subTLVs and return + * the amount of processed bytes + */ + +static int +isis_print_extd_ip_reach (const u_int8_t *tptr, const char *ident, u_int16_t afi) { + + char ident_buffer[20]; + u_int8_t prefix[16]; /* shared copy buffer for IPv4 and IPv6 prefixes */ + u_int metric, status_byte, bit_length, byte_length, sublen, processed, subtlvtype, subtlvlen; + + if (!TTEST2(*tptr, 4)) + return (0); + metric = EXTRACT_32BITS(tptr); + processed=4; + tptr+=4; + + if (afi == IPV4) { + if (!TTEST2(*tptr, 1)) /* fetch status byte */ + return (0); + status_byte=*(tptr++); + bit_length = status_byte&0x3f; + processed++; +#ifdef INET6 + } else if (afi == IPV6) { + if (!TTEST2(*tptr, 1)) /* fetch status & prefix_len byte */ + return (0); + status_byte=*(tptr++); + bit_length=*(tptr++); + processed+=2; +#endif + } else + return (0); /* somebody is fooling us */ + + byte_length = (bit_length + 7) / 8; /* prefix has variable length encoding */ + + if (!TTEST2(*tptr, byte_length)) + return (0); + memset(prefix, 0, 16); /* clear the copy buffer */ + memcpy(prefix,tptr,byte_length); /* copy as much as is stored in the TLV */ + tptr+=byte_length; + processed+=byte_length; + + if (afi == IPV4) + printf("%sIPv4 prefix: %15s/%u", + ident, + ipaddr_string(prefix), + bit_length); +#ifdef INET6 + if (afi == IPV6) + printf("%sIPv6 prefix: %s/%u", + ident, + ip6addr_string(prefix), + bit_length); +#endif + + printf(", Distribution: %s, Metric: %u", + ISIS_MASK_TLV_EXTD_IP_UPDOWN(status_byte) ? "down" : "up", + metric); + + if (afi == IPV4 && ISIS_MASK_TLV_EXTD_IP_SUBTLV(status_byte)) + printf(", sub-TLVs present"); +#ifdef INET6 + if (afi == IPV6) + printf(", %s%s", + ISIS_MASK_TLV_EXTD_IP6_IE(status_byte) ? "External" : "Internal", + ISIS_MASK_TLV_EXTD_IP6_SUBTLV(status_byte) ? ", sub-TLVs present" : ""); +#endif + + if ((ISIS_MASK_TLV_EXTD_IP_SUBTLV(status_byte) && afi == IPV4) || + (ISIS_MASK_TLV_EXTD_IP6_SUBTLV(status_byte) && afi == IPV6)) { + /* assume that one prefix can hold more + than one subTLV - therefore the first byte must reflect + the aggregate bytecount of the subTLVs for this prefix + */ + if (!TTEST2(*tptr, 1)) + return (0); + sublen=*(tptr++); + processed+=sublen+1; + printf(" (%u)",sublen); /* print out subTLV length */ + + while (sublen>0) { + if (!TTEST2(*tptr,2)) + return (0); + subtlvtype=*(tptr++); + subtlvlen=*(tptr++); + /* prepend the ident string */ + snprintf(ident_buffer, sizeof(ident_buffer), "%s ",ident); + if(!isis_print_ip_reach_subtlv(tptr,subtlvtype,subtlvlen,ident_buffer)) + return(0); + tptr+=subtlvlen; + sublen-=(subtlvlen+2); + } + } + return (processed); +} + +/* * isis_print * Decode IS-IS packets. Return 0 on error. */ -static int isis_print (const u_char *p, u_int length) +static int isis_print (const u_int8_t *p, u_int length) { const struct isis_common_header *header; @@ -676,37 +1144,29 @@ static int isis_print (const u_char *p, u_int length) const struct isis_tlv_lsp *tlv_lsp; const struct isis_tlv_ptp_adj *tlv_ptp_adj; const struct isis_tlv_is_reach *tlv_is_reach; + const struct isis_tlv_es_reach *tlv_es_reach; - u_char pdu_type, max_area, type, len, tmp, alen, subl, subt, tslen, ttslen; - const u_char *optr, *pptr, *tptr; - u_char subtlv_len; + u_int8_t pdu_type, max_area, id_length, tlv_type, tlv_len, tmp, alen, lan_alen, prefix_len; + u_int8_t ext_is_len, ext_ip_len, mt_len; + const u_int8_t *optr, *pptr, *tptr; u_short packet_len,pdu_len; - u_int i,j,bit_length,byte_length,metric; - u_char prefix[4]; /* copy buffer for ipv4 prefixes */ -#ifdef INET6 - u_char prefix6[16]; /* copy buffer for ipv6 prefixes */ -#endif - u_char off[2]; - float bw; /* copy buffer for several subTLVs of the extended IS reachability TLV */ + u_int i; packet_len=length; - optr = p; /* initialize the _o_riginal pointer - need it for parsing the checksum TLV */ - header = (const struct isis_common_header *)p; + optr = p; /* initialize the _o_riginal pointer to the packet start - + need it for parsing the checksum TLV */ + header = (const struct isis_common_header *)p; TCHECK(*header); - pptr = p+(ISIS_COMMON_HEADER_SIZE); + pptr = p+(ISIS_COMMON_HEADER_SIZE); header_iih_lan = (const struct isis_iih_lan_header *)pptr; header_iih_ptp = (const struct isis_iih_ptp_header *)pptr; header_lsp = (const struct isis_lsp_header *)pptr; header_csnp = (const struct isis_csnp_header *)pptr; header_psnp = (const struct isis_psnp_header *)pptr; - + /* * Sanity checking of the header. */ - if (header->nlpid != NLPID_ISIS) { - printf(", coding error!"); - return (0); - } if (header->version != ISIS_VERSION) { printf(", version %d packet not supported", header->version); @@ -718,16 +1178,16 @@ static int isis_print (const u_char *p, u_int length) header->id_length); return (0); } - - if (header->pkt_version != ISIS_VERSION) { - printf(", version %d packet not supported", header->pkt_version); + + if (header->pdu_version != ISIS_VERSION) { + printf(", version %d packet not supported", header->pdu_version); return (0); } max_area = header->max_area; switch(max_area) { case 0: - max_area = 3; /* silly shit */ + max_area = 3; /* silly shit */ break; case 255: printf(", bad packet -- 255 areas"); @@ -736,17 +1196,98 @@ static int isis_print (const u_char *p, u_int length) break; } - printf(", hlen: %u, v: %u, sys-id-len: 6 (0), max-area: %u (%u)", + id_length = header->id_length; + switch(id_length) { + case 0: + id_length = 6; /* silly shit again */ + break; + case 1: /* 1-8 are valid sys-ID lenghts */ + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + break; + case 255: + id_length = 0; /* entirely useless */ + break; + default: + break; + } + + /* toss any non 6-byte sys-ID len PDUs */ + if (id_length != 6 ) { + printf(", bad packet -- illegal sys-ID length (%u)", id_length); + return (0); + } + + pdu_type=header->pdu_type; + + /* in non-verbose mode print the basic PDU Type plus PDU specific brief information*/ + if (vflag < 1) { + printf(", IS-IS, %s", + tok2str(isis_pdu_values,"unknown PDU-Type %u",pdu_type)); + + switch (pdu_type) { + + case L1_LAN_IIH: + case L2_LAN_IIH: + printf(", src-id %s", + isis_print_id(header_iih_lan->source_id,SYSTEM_ID_LEN)); + printf(", lan-id %s, prio %u", + isis_print_id(header_iih_lan->lan_id,NODE_ID_LEN), + header_iih_lan->priority); + break; + case PTP_IIH: + printf(", src-id %s", isis_print_id(header_iih_ptp->source_id,SYSTEM_ID_LEN)); + break; + case L1_LSP: + case L2_LSP: + printf(", lsp-id %s, seq 0x%08x, lifetime %5us", + isis_print_id(header_lsp->lsp_id, LSP_ID_LEN), + EXTRACT_32BITS(header_lsp->sequence_number), + EXTRACT_16BITS(header_lsp->remaining_lifetime)); + break; + case L1_CSNP: + case L2_CSNP: + printf(", src-id %s", isis_print_id(header_csnp->source_id,SYSTEM_ID_LEN)); + break; + case L1_PSNP: + case L2_PSNP: + printf(", src-id %s", isis_print_id(header_psnp->source_id,SYSTEM_ID_LEN)); + break; + + } + printf(", length %u", length); + + return(1); + } + + /* ok they seem to want to know everything - lets fully decode it */ + printf(", IS-IS, length: %u",length); + + printf("\n\t%s, hlen: %u, v: %u, pdu-v: %u, sys-id-len: %u (%u), max-area: %u (%u)", + tok2str(isis_pdu_values, + "unknown, type %u", + pdu_type), header->fixed_len, - header->pkt_version, + header->version, + header->pdu_version, + id_length, + header->id_length, max_area, header->max_area); - - pdu_type=header->pdu_type; - + + if (vflag > 1) { + if(!print_unknown_data(optr,"\n\t",8)) /* provide the _o_riginal pointer */ + return(0); /* for optionally debugging the common header */ + } + switch (pdu_type) { - case L1_LAN_IIH: + case L1_LAN_IIH: case L2_LAN_IIH: if (header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE)) { printf(", bogus fixed header length %u should be %lu", @@ -756,39 +1297,27 @@ static int isis_print (const u_char *p, u_int length) pdu_len=EXTRACT_16BITS(header_iih_lan->pdu_len); if (packet_len>pdu_len) { - packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ - length=pdu_len; + packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ + length=pdu_len; } - printf(", L%s Lan IIH (%u)", - ISIS_MASK_LEVEL_BITS(pdu_type) ? "1" : "2", - pdu_len); - TCHECK(*header_iih_lan); - printf("\n\t\t source-id: "); - isis_print_sysid(header_iih_lan->source_id); - printf(", holding time: %us",EXTRACT_16BITS(header_iih_lan->holding_time)); - switch(header_iih_lan->circuit_type) { - - case 1: - printf(", Level 1 only"); - break; - - case 2: - printf(", Level 2 only"); - break; - - case 3: - printf(", Level 1, Level 2"); - break; - - default: - printf(", unknown 0x%02x", header_iih_lan->circuit_type); - break; - } - printf("\n\t\t lan-id: "); - isis_print_nodeid(header_iih_lan->lan_id); - printf(", Priority: %u",(header_iih_lan->priority) & PRIORITY_MASK); + printf("\n\t source-id: %s, holding time: %us, Flags: [%s]", + isis_print_id(header_iih_lan->source_id,SYSTEM_ID_LEN), + EXTRACT_16BITS(header_iih_lan->holding_time), + tok2str(isis_iih_circuit_type_values, + "unknown circuit type 0x%02x", + header_iih_lan->circuit_type)); + + printf("\n\t lan-id: %s, Priority: %u, PDU length: %u", + isis_print_id(header_iih_lan->lan_id, NODE_ID_LEN), + (header_iih_lan->priority) & PRIORITY_MASK, + pdu_len); + + if (vflag > 1) { + if(!print_unknown_data(pptr,"\n\t ",ISIS_IIH_LAN_HEADER_SIZE)) + return(0); + } packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE); pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE); @@ -800,37 +1329,29 @@ static int isis_print (const u_char *p, u_int length) header->fixed_len, (unsigned long)ISIS_IIH_PTP_HEADER_SIZE); return (0); } - + pdu_len=EXTRACT_16BITS(header_iih_ptp->pdu_len); if (packet_len>pdu_len) { - packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ - length=pdu_len; + packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ + length=pdu_len; } - - printf(", PTP IIH (%u)",pdu_len); - TCHECK(*header_iih_ptp); - printf("\n\t\t source-id: "); - isis_print_sysid(header_iih_ptp->source_id); - printf(", holding time: %us",EXTRACT_16BITS(header_iih_ptp->holding_time)); - printf(", circuit-id: 0x%02x", header_iih_ptp->circuit_id); - switch(header_iih_ptp->circuit_type) { - - case 1: - printf(", Level 1 only"); - break; - case 2: - printf(", Level 2 only"); - break; - - case 3: - printf(", Level 1, Level 2"); - break; - - default: - printf(", unknown 0x%02x", header_iih_ptp->circuit_type); - break; - } + TCHECK(*header_iih_ptp); + printf("\n\t source-id: %s, holding time: %us, Flags: [%s]", + isis_print_id(header_iih_ptp->source_id,SYSTEM_ID_LEN), + EXTRACT_16BITS(header_iih_ptp->holding_time), + tok2str(isis_iih_circuit_type_values, + "unknown circuit type 0x%02x", + header_iih_ptp->circuit_type)); + + printf("\n\t circuit-id: 0x%02x, PDU length: %u", + header_iih_ptp->circuit_id, + pdu_len); + + if (vflag > 1) { + if(!print_unknown_data(pptr,"\n\t ",ISIS_IIH_PTP_HEADER_SIZE)) + return(0); + } packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE); pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE); @@ -843,26 +1364,33 @@ static int isis_print (const u_char *p, u_int length) header->fixed_len, (unsigned long)ISIS_LSP_HEADER_SIZE); return (0); } - + pdu_len=EXTRACT_16BITS(header_lsp->pdu_len); if (packet_len>pdu_len) { - packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ - length=pdu_len; + packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ + length=pdu_len; } - if (pdu_type == L1_LSP) - printf(", L1 LSP (%u)",pdu_len); - else if (pdu_type == L2_LSP) - printf(", L2 LSP (%u)",pdu_len); - TCHECK(*header_lsp); - printf("\n\t\t lsp-id: "); - isis_print_lspid(header_lsp->lsp_id); - printf(", sequence number: 0x%08x",EXTRACT_32BITS(header_lsp->sequence_number)); - printf(", lifetime: %5us",EXTRACT_16BITS(header_lsp->remaining_lifetime)); - printf("\n\t\t checksum: 0x%04x",EXTRACT_16BITS(header_lsp->checksum)); - - printf(", %s", ISIS_MASK_LSP_OL_BIT(header_lsp->typeblock) ? "Overload bit set, " : ""); + printf("\n\t lsp-id: %s, seq: 0x%08x, lifetime: %5us\n\t chksum: 0x%04x", + isis_print_id(header_lsp->lsp_id, LSP_ID_LEN), + EXTRACT_32BITS(header_lsp->sequence_number), + EXTRACT_16BITS(header_lsp->remaining_lifetime), + EXTRACT_16BITS(header_lsp->checksum)); + + /* if this is a purge do not attempt to verify the checksum */ + if ( EXTRACT_16BITS(header_lsp->remaining_lifetime) == 0 && + EXTRACT_16BITS(header_lsp->checksum) == 0) + printf(" (purged)"); + else + /* verify the checksum - + * checking starts at the lsp-id field at byte position [12] + * hence the length needs to be reduced by 12 bytes */ + printf(" (%s)", (osi_cksum((u_int8_t *)header_lsp->lsp_id, length-12)) ? "incorrect" : "correct"); + + printf(", PDU length: %u, Flags: [ %s", + pdu_len, + ISIS_MASK_LSP_OL_BIT(header_lsp->typeblock) ? "Overload bit set, " : ""); if (ISIS_MASK_LSP_ATT_BITS(header_lsp->typeblock)) { printf("%s", ISIS_MASK_LSP_ATT_DEFAULT_BIT(header_lsp->typeblock) ? "default " : ""); @@ -872,7 +1400,12 @@ static int isis_print (const u_char *p, u_int length) printf("ATT bit set, "); } printf("%s", ISIS_MASK_LSP_PARTITION_BIT(header_lsp->typeblock) ? "P bit set, " : ""); - printf("%s", tok2str(isis_lsp_istype_values,"Unknown(0x%x)",ISIS_MASK_LSP_ISTYPE_BITS(header_lsp->typeblock))); + printf("%s ]", tok2str(isis_lsp_istype_values,"Unknown(0x%x)",ISIS_MASK_LSP_ISTYPE_BITS(header_lsp->typeblock))); + + if (vflag > 1) { + if(!print_unknown_data(pptr,"\n\t ",ISIS_LSP_HEADER_SIZE)) + return(0); + } packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE); pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE); @@ -885,21 +1418,26 @@ static int isis_print (const u_char *p, u_int length) header->fixed_len, (unsigned long)ISIS_CSNP_HEADER_SIZE); return (0); } - + pdu_len=EXTRACT_16BITS(header_csnp->pdu_len); if (packet_len>pdu_len) { - packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ - length=pdu_len; + packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ + length=pdu_len; } - printf(", L%s CSNP (%u)", ISIS_MASK_LEVEL_BITS(pdu_type) ? "2" : "1", pdu_len); TCHECK(*header_csnp); - printf("\n\t\t source-id: "); - isis_print_nodeid(header_csnp->source_id); - printf("\n\t\t start lsp-id: "); - isis_print_lspid(header_csnp->start_lsp_id); - printf("\n\t\t end lsp-id: "); - isis_print_lspid(header_csnp->end_lsp_id); + printf("\n\t source-id: %s, PDU length: %u", + isis_print_id(header_csnp->source_id, NODE_ID_LEN), + pdu_len); + printf("\n\t start lsp-id: %s", + isis_print_id(header_csnp->start_lsp_id, LSP_ID_LEN)); + printf("\n\t end lsp-id: %s", + isis_print_id(header_csnp->end_lsp_id, LSP_ID_LEN)); + + if (vflag > 1) { + if(!print_unknown_data(pptr,"\n\t ",ISIS_CSNP_HEADER_SIZE)) + return(0); + } packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE); pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE); @@ -915,651 +1453,570 @@ static int isis_print (const u_char *p, u_int length) pdu_len=EXTRACT_16BITS(header_psnp->pdu_len); if (packet_len>pdu_len) { - packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ - length=pdu_len; + packet_len=pdu_len; /* do TLV decoding as long as it makes sense */ + length=pdu_len; } - printf(", L%s PSNP (%u)", ISIS_MASK_LEVEL_BITS(pdu_type) ? "2" : "1", pdu_len); TCHECK(*header_psnp); - printf("\n\t\t source-id: "); - isis_print_nodeid(header_psnp->source_id); - + printf("\n\t source-id: %s, PDU length: %u", + isis_print_id(header_psnp->source_id, NODE_ID_LEN), + pdu_len); + + if (vflag > 1) { + if(!print_unknown_data(pptr,"\n\t ",ISIS_PSNP_HEADER_SIZE)) + return(0); + } + packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE); pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE); break; default: - printf(", PDU type (0x%02x) not supported", pdu_type); - return (1); + if(!print_unknown_data(pptr,"\n\t ",length)) + return(0); + return (0); } /* * Now print the TLV's. */ - + while (packet_len >= 2) { if (pptr == snapend) { return (1); } if (!TTEST2(*pptr, 2)) { - printf("\n\t\t\t packet exceeded snapshot (%ld) bytes", - (long)(pptr-snapend)); + printf("\n\t\t packet exceeded snapshot (%ld) bytes", + (long)(pptr-snapend)); return (1); } - type = *pptr++; - len = *pptr++; + tlv_type = *pptr++; + tlv_len = *pptr++; + tmp =tlv_len; /* copy temporary len & pointer to packet data */ + tptr = pptr; packet_len -= 2; - if (len > packet_len) { + if (tlv_len > packet_len) { break; } - printf("\n\t\t "); - switch (type) { + /* first lets see if we know the TLVs name*/ + printf("\n\t %s TLV #%u, length: %u", + tok2str(isis_tlv_values, + "unknown", + tlv_type), + tlv_type, + tlv_len); + + /* now check if we have a decoder otherwise do a hexdump at the end*/ + switch (tlv_type) { case TLV_AREA_ADDR: - printf("Area address(es) (%u)",len); - tmp = len; - tptr = pptr; if (!TTEST2(*tptr, 1)) goto trunctlv; alen = *tptr++; while (tmp && alen < tmp) { - printf("\n\t\t\tArea address (%u): ",alen); - if (!print_nsap(tptr, alen)) - return (1); + printf("\n\t Area address (length: %u): %s", + alen, + print_nsap(tptr, alen)); tptr += alen; tmp -= alen + 1; if (tmp==0) /* if this is the last area address do not attemt a boundary check */ - break; + break; if (!TTEST2(*tptr, 1)) goto trunctlv; alen = *tptr++; } break; case TLV_ISNEIGH: - printf("IS Neighbor(s) (%u)",len); - tmp = len; - tptr = pptr; while (tmp >= ETHER_ADDR_LEN) { - printf("\n\t\t\tIS Neighbor: "); - if (!isis_print_sysid(tptr)) - return (1); - tmp -= ETHER_ADDR_LEN; - tptr += ETHER_ADDR_LEN; + if (!TTEST2(*tptr, ETHER_ADDR_LEN)) + goto trunctlv; + printf("\n\t SNPA: %s",isis_print_id(tptr,ETHER_ADDR_LEN)); + tmp -= ETHER_ADDR_LEN; + tptr += ETHER_ADDR_LEN; } break; + case TLV_ISNEIGH_VARLEN: + if (!TTEST2(*tptr, 1)) + goto trunctlv; + lan_alen = *tptr++; /* LAN adress length */ + tmp --; + printf("\n\t LAN address length %u bytes ",lan_alen); + while (tmp >= lan_alen) { + if (!TTEST2(*tptr, lan_alen)) + goto trunctlv; + printf("\n\t\tIS Neighbor: %s",isis_print_id(tptr,lan_alen)); + tmp -= lan_alen; + tptr +=lan_alen; + } + break; + case TLV_PADDING: - printf("Padding (%u)", len); break; case TLV_MT_IS_REACH: - printf("Multi Topology IS Reachability (%u)",len); - tptr=pptr; - tmp=len; - while (tmp>0) { - printf("\n\t\t\t"); - if (!TTEST2(*tptr, 2)) - goto trunctlv; - switch(EXTRACT_16BITS(tptr)&0x0fff) { - - case 0: - printf("IPv4 unicast"); - break; - - case 1: - printf("In-Band Management"); - break; - - case 2: - printf("IPv6 unicast"); - break; - - case 3: - printf("Multicast"); - break; - - case 4095: - printf("Development, Experimental or Proprietary"); - break; - - default: - printf("Reserved for IETF Consensus"); - break; - } - printf(" Topology (0x%03x)",EXTRACT_16BITS(tptr)&0x0fff); - tptr+=2; - printf("\n\t\t\t IS Neighbor: "); - if (!isis_print_nodeid(tptr)) - return (1); - tptr+=(SYSTEM_ID_LEN+1); - if (!TTEST2(*tptr, 3)) + while (tmp >= 2+NODE_ID_LEN+3+1) { + mt_len = isis_print_mtid(tptr, "\n\t "); + if (mt_len == 0) /* did something go wrong ? */ goto trunctlv; - printf(", Metric: %d",EXTRACT_24BITS(tptr)); - tptr+=3; - if (!TTEST2(*tptr, 1)) + tptr+=mt_len; + tmp-=mt_len; + + ext_is_len = isis_print_ext_is_reach(tptr,"\n\t ",tlv_type); + if (ext_is_len == 0) /* did something go wrong ? */ goto trunctlv; - tslen=*(tptr++); - printf(", %ssub-TLVs present",tslen ? "" : "no "); - - tptr+=tslen; - tmp-=(13+tslen); + + tmp-=ext_is_len; + tptr+=ext_is_len; } break; + case TLV_IS_ALIAS_ID: + while (tmp >= NODE_ID_LEN+1) { /* is it worth attempting a decode ? */ + ext_is_len = isis_print_ext_is_reach(tptr,"\n\t ",tlv_type); + if (ext_is_len == 0) /* did something go wrong ? */ + goto trunctlv; + tmp-=ext_is_len; + tptr+=ext_is_len; + } + break; + case TLV_EXT_IS_REACH: - printf("Extended IS Reachability (%u)",len); - tptr=pptr; - tmp=len; - while (tmp>0) { - printf("\n\t\t\tIS Neighbor: "); - if (!isis_print_nodeid(tptr)) - return (1); - tptr+=(SYSTEM_ID_LEN+1); - if (!TTEST2(*tptr, 3)) - goto trunctlv; - printf(", Metric: %d",EXTRACT_24BITS(tptr)); - tptr+=3; - if (!TTEST2(*tptr, 1)) - goto trunctlv; - tslen=*(tptr++); - printf(", %ssub-TLVs present",tslen ? "" : "no "); - if (tslen) { - printf(" (%u)",tslen); - ttslen=tslen; - while (ttslen>0) { - if (!TTEST2(*tptr,2)) - goto trunctlv; - printf("\n\t\t\t "); - subt=*(tptr++); - subl=*(tptr++); - switch(subt) { - case SUBTLV_EXT_IS_REACH_ADMIN_GROUP: - printf("Administrative groups: 0x%08x", EXTRACT_32BITS(tptr)); - break; - case SUBTLV_EXT_IS_REACH_MAX_LINK_BW : - if (!TTEST2(*tptr,4)) - goto trunctlv; - j = EXTRACT_32BITS(tptr); - memcpy (&bw, &j, 4); - printf("Maximum link bandwidth : %.3f Mbps", - bw*8/1000000 ); - break; - case SUBTLV_EXT_IS_REACH_RESERVABLE_BW : - if (!TTEST2(*tptr,4)) - goto trunctlv; - j = EXTRACT_32BITS(tptr); - memcpy (&bw, &j, 4); - printf("Reservable link bandwidth: %.3f Mbps", - bw*8/1000000 ); - break; - case SUBTLV_EXT_IS_REACH_UNRESERVED_BW : - printf("Unreserved bandwidth:"); - for (i = 0; i < 8; i++) { - if (!TTEST2(*tptr,4)) - goto trunctlv; - j = EXTRACT_32BITS(tptr); - memcpy (&bw, &j, 4); - printf("\n\t\t\t priority level %d: %.3f Mbps", - i, bw*8/1000000 ); - tptr+=4; - } - tptr-=32; - break; - case SUBTLV_EXT_IS_REACH_TE_METRIC: - if (!TTEST2(*tptr,3)) - goto trunctlv; - printf("Traffic Engineering Metric: %d", EXTRACT_24BITS(tptr)); - break; - case SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR: - if (!TTEST2(*tptr,4)) - goto trunctlv; - printf("IPv4 interface address: %s", ipaddr_string(tptr)); - break; - case SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR: - if (!TTEST2(*tptr,4)) - goto trunctlv; - printf("IPv4 neighbor address: %s", ipaddr_string(tptr)); - break; - case 250: - case 251: - case 252: - case 253: - case 254: - printf("Reserved for cisco specific extensions, type %d, length %d", subt, subl); - break; - case 255: - printf("Reserved for future expansion, type %d, length %d", subt, subl); - break; - default: - printf("unknown subTLV, type %d, length %d", subt, subl); - } - tptr+=subl; - ttslen-=(subl+2); - } - } - tptr+=tslen; - tmp-=(11+tslen); + while (tmp >= NODE_ID_LEN+3+1) { /* is it worth attempting a decode ? */ + ext_is_len = isis_print_ext_is_reach(tptr,"\n\t ",tlv_type); + if (ext_is_len == 0) /* did something go wrong ? */ + goto trunctlv; + tmp-=ext_is_len; + tptr+=ext_is_len; } break; case TLV_IS_REACH: - printf("IS Reachability (%u)",len); - - tptr=pptr; - if (!TTEST2(*tptr,1)) /* check if there is one byte left to read out the virtual flag */ - goto trunctlv; - - switch (*tptr) { - case 0: - printf("\n\t\t\tIsNotVirtual"); - break; - case 1: - printf("\n\t\t\tIsVirtual"); - break; - default: - printf("\n\t\t\tbogus virtual flag 0x%02x",(*tptr)); - break; - } - - tptr++; - + goto trunctlv; + printf("\n\t %s", + tok2str(isis_is_reach_virtual_values, + "bogus virtual flag 0x%02x", + *tptr++)); tlv_is_reach = (const struct isis_tlv_is_reach *)tptr; - - tmp = len; while (tmp >= sizeof(struct isis_tlv_is_reach)) { if (!TTEST(*tlv_is_reach)) goto trunctlv; - - printf("\n\t\t\tIS Neighbor: "); - isis_print_nodeid(tlv_is_reach->neighbor_nodeid); - - printf(", Default Metric: %d, %s", - ISIS_LSP_TLV_METRIC_VALUE(tlv_is_reach->metric_default), - ISIS_LSP_TLV_METRIC_IE(tlv_is_reach->metric_default) ? "External" : "Internal"); - - if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_is_reach->metric_delay)) - printf("\n\t\t\t Delay Metric: %d, %s", - ISIS_LSP_TLV_METRIC_VALUE(tlv_is_reach->metric_delay), - ISIS_LSP_TLV_METRIC_IE(tlv_is_reach->metric_delay) ? "External" : "Internal"); - - if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_is_reach->metric_expense)) - printf("\n\t\t\t Expense Metric: %d, %s", - ISIS_LSP_TLV_METRIC_VALUE(tlv_is_reach->metric_expense), - ISIS_LSP_TLV_METRIC_IE(tlv_is_reach->metric_expense) ? "External" : "Internal"); - - if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_is_reach->metric_error)) - printf("\n\t\t\t Error Metric: %d, %s", - ISIS_LSP_TLV_METRIC_VALUE(tlv_is_reach->metric_error), - ISIS_LSP_TLV_METRIC_IE(tlv_is_reach->metric_error) ? "External" : "Internal"); - + printf("\n\t IS Neighbor: %s", + isis_print_id(tlv_is_reach->neighbor_nodeid, NODE_ID_LEN)); + isis_print_metric_block(&tlv_is_reach->isis_metric_block); tmp -= sizeof(struct isis_tlv_is_reach); tlv_is_reach++; } break; - case TLV_IP_REACH: - printf("IP Internal reachability (%u)",len); - if (!isis_print_tlv_ip_reach(pptr, len)) - return (1); - break; + case TLV_ESNEIGH: + tlv_es_reach = (const struct isis_tlv_es_reach *)tptr; + while (tmp >= sizeof(struct isis_tlv_es_reach)) { + if (!TTEST(*tlv_es_reach)) + goto trunctlv; + printf("\n\t ES Neighbor: %s", + isis_print_id(tlv_es_reach->neighbor_sysid,SYSTEM_ID_LEN)); + isis_print_metric_block(&tlv_es_reach->isis_metric_block); + tmp -= sizeof(struct isis_tlv_es_reach); + tlv_es_reach++; + } + break; - case TLV_IP_REACH_EXT: - printf("IP External reachability (%u)",len); - if (!isis_print_tlv_ip_reach(pptr, len)) + /* those two TLVs share the same format */ + case TLV_INT_IP_REACH: + case TLV_EXT_IP_REACH: + if (!isis_print_tlv_ip_reach(pptr, "\n\t ", tlv_len)) return (1); break; - case TLV_EXT_IP_REACH: - printf("Extended IP reachability (%u)",len); - i=len; - tptr=pptr; - - while (i>0) { - memset (prefix, 0, 4); - if (!TTEST2(*tptr, 4)) - return (1); - metric = EXTRACT_32BITS(tptr); - tptr+=4; + case TLV_EXTD_IP_REACH: + while (tmp>0) { + ext_ip_len = isis_print_extd_ip_reach(tptr, "\n\t ", IPV4); + if (ext_ip_len == 0) /* did something go wrong ? */ + goto trunctlv; + tptr+=ext_ip_len; + tmp-=ext_ip_len; + } + break; - if (!TTEST2(*tptr, 1)) - return (1); - j=*(tptr); - bit_length = (*(tptr)++&0x3f); - byte_length = (bit_length + 7) / 8; - if (!TTEST2(*tptr, byte_length)) - return (1); - - memcpy(prefix,tptr,byte_length); - - printf("\n\t\t\tIPv4 prefix: %u.%u.%u.%u/%d", - prefix[0], - prefix[1], - prefix[2], - prefix[3], - bit_length); - - printf("\n\t\t\t Metric: %u, Distribution: %s", - metric, - ISIS_MASK_TLV_EXT_IP_UPDOWN(j) ? "down" : "up"); - - printf(", %ssub-TLVs present", - ISIS_MASK_TLV_EXT_IP_SUBTLV(j) ? "" : "no "); - - if (ISIS_MASK_TLV_EXT_IP_SUBTLV(j)) { - if (!TTEST2(*tptr, 1)) - return (1); - subtlv_len = *tptr; - printf(" (%u)",subtlv_len); /* no subTLV decoder supported - just print out subTLV length */ - i -= subtlv_len; - tptr += subtlv_len + 1; - } + case TLV_MT_IP_REACH: + while (tmp>0) { + mt_len = isis_print_mtid(tptr, "\n\t "); + if (mt_len == 0) /* did something go wrong ? */ + goto trunctlv; + tptr+=mt_len; + tmp-=mt_len; - i-=(5+byte_length); - tptr+=byte_length; + ext_ip_len = isis_print_extd_ip_reach(tptr, "\n\t ", IPV4); + if (ext_ip_len == 0) /* did something go wrong ? */ + goto trunctlv; + tptr+=ext_ip_len; + tmp-=ext_ip_len; } break; #ifdef INET6 - case TLV_IP6_REACH: - printf("IP6 reachability (%u)",len); - i=len; - tptr=pptr; - - while (i>0) { - if (!TTEST2(*tptr, 4)) - return (1); - metric = EXTRACT_32BITS(tptr); - tptr+=4; + while (tmp>0) { + ext_ip_len = isis_print_extd_ip_reach(tptr, "\n\t ", IPV6); + if (ext_ip_len == 0) /* did something go wrong ? */ + goto trunctlv; + tptr+=ext_ip_len; + tmp-=ext_ip_len; + } + break; - if (!TTEST2(*tptr, 2)) - return (1); - j=*(tptr++); - bit_length = (*(tptr)++); - byte_length = (bit_length + 7) / 8; - if (!TTEST2(*tptr, byte_length)) - return (1); - - memset(prefix6, 0, 16); - memcpy(prefix6,tptr,byte_length); - - printf("\n\t\t\tIPv6 prefix: %s/%u", - ip6addr_string(prefix6), - bit_length); - - printf("\n\t\t\t Metric: %u, %s, Distribution: %s, %ssub-TLVs present", - metric, - ISIS_MASK_TLV_IP6_IE(j) ? "External" : "Internal", - ISIS_MASK_TLV_IP6_UPDOWN(j) ? "down" : "up", - ISIS_MASK_TLV_IP6_SUBTLV(j) ? "" : "no "); - - if (ISIS_MASK_TLV_IP6_SUBTLV(j)) { - if (!TTEST2(*tptr, 1)) - return (1); - printf(" (%u)",*tptr); /* no subTLV decoder supported - just print out subTLV length */ - i-=*tptr; - tptr+=*tptr++; - } + case TLV_MT_IP6_REACH: + while (tmp>0) { + mt_len = isis_print_mtid(tptr, "\n\t "); + if (mt_len == 0) /* did something go wrong ? */ + goto trunctlv; + tptr+=mt_len; + tmp-=mt_len; - i-=(6+byte_length); - tptr+=byte_length; + ext_ip_len = isis_print_extd_ip_reach(tptr, "\n\t ", IPV6); + if (ext_ip_len == 0) /* did something go wrong ? */ + goto trunctlv; + tptr+=ext_ip_len; + tmp-=ext_ip_len; } - break; -#endif -#ifdef INET6 case TLV_IP6ADDR: - printf("IPv6 Interface address(es) (%u)",len); - i=len; - tptr=pptr; - while (i>0) { + while (tmp>0) { if (!TTEST2(*tptr, 16)) goto trunctlv; - printf("\n\t\t\tIPv6 interface address: %s", + printf("\n\t IPv6 interface address: %s", ip6addr_string(tptr)); tptr += 16; - i -= 16; + tmp -= 16; } break; #endif case TLV_AUTH: - if (!TTEST2(*pptr, 1)) + if (!TTEST2(*tptr, 1)) goto trunctlv; - printf("Authentication (%u)",len); - if (*pptr==SUBTLV_AUTH_SIMPLE) { - printf("\n\t\t\tsimple text password: "); - for(i=1;i<len;i++) { - if (!TTEST2(*(pptr+i), 1)) + + printf("\n\t %s: ", + tok2str(isis_subtlv_auth_values, + "unknown Authentication type 0x%02x", + *tptr)); + + switch (*tptr) { + case SUBTLV_AUTH_SIMPLE: + for(i=1;i<tlv_len;i++) { + if (!TTEST2(*(tptr+i), 1)) goto trunctlv; - printf("%c",*(pptr+i)); + printf("%c",*(tptr+i)); } - } - if (!TTEST2(*pptr, 1)) - goto trunctlv; - if (*pptr==SUBTLV_AUTH_MD5) { - printf("\n\t\t\tMD5 password: "); - for(i=1;i<len;i++) { - if (!TTEST2(*(pptr+i), 1)) + break; + case SUBTLV_AUTH_MD5: + for(i=1;i<tlv_len;i++) { + if (!TTEST2(*(tptr+i), 1)) goto trunctlv; - printf("%02x",*(pptr+i)); + printf("%02x",*(tptr+i)); } + if (tlv_len != SUBTLV_AUTH_MD5_LEN+1) + printf(", (malformed subTLV) "); + break; + case SUBTLV_AUTH_PRIVATE: + default: + if(!print_unknown_data(tptr+1,"\n\t\t ",tlv_len-1)) + return(0); + break; } break; case TLV_PTP_ADJ: - printf("Point-to-point Adjacency State (%u)",len); - tlv_ptp_adj = (const struct isis_tlv_ptp_adj *)pptr; - i=len; - if(i>=1) { - if (!TTEST2(*pptr, 1)) + tlv_ptp_adj = (const struct isis_tlv_ptp_adj *)tptr; + if(tmp>=1) { + if (!TTEST2(*tptr, 1)) goto trunctlv; - printf("\n\t\t\tAdjacency State: %s", - tok2str(isis_ptp_adjancey_values, "#0x%x", *pptr)); - i--; + printf("\n\t Adjacency State: %s (%u)", + tok2str(isis_ptp_adjancey_values, "unknown", *tptr), + *tptr); + tmp--; } - if(i>=4) { - if (!TTEST2(tlv_ptp_adj->ext_local_circuit_id, 4)) + if(tmp>sizeof(tlv_ptp_adj->extd_local_circuit_id)) { + if (!TTEST2(tlv_ptp_adj->extd_local_circuit_id, + sizeof(tlv_ptp_adj->extd_local_circuit_id))) goto trunctlv; - printf("\n\t\t\tExtended Local circuit ID: 0x%08x", - EXTRACT_32BITS(tlv_ptp_adj->ext_local_circuit_id)); - i-=4; + printf("\n\t Extended Local circuit-ID: 0x%08x", + EXTRACT_32BITS(tlv_ptp_adj->extd_local_circuit_id)); + tmp-=sizeof(tlv_ptp_adj->extd_local_circuit_id); } - if(i>=6) { - if (!TTEST2(tlv_ptp_adj->neighbor_sysid, 6)) + if(tmp>=SYSTEM_ID_LEN) { + if (!TTEST2(tlv_ptp_adj->neighbor_sysid, SYSTEM_ID_LEN)) goto trunctlv; - printf("\n\t\t\tNeighbor SystemID: "); - isis_print_sysid(tlv_ptp_adj->neighbor_sysid); - i-=6; + printf("\n\t Neighbor System-ID: %s", + isis_print_id(tlv_ptp_adj->neighbor_sysid,SYSTEM_ID_LEN)); + tmp-=SYSTEM_ID_LEN; } - if(i>=4) { - if (!TTEST2(tlv_ptp_adj->neighbor_ext_local_circuit_id, 4)) + if(tmp>=sizeof(tlv_ptp_adj->neighbor_extd_local_circuit_id)) { + if (!TTEST2(tlv_ptp_adj->neighbor_extd_local_circuit_id, + sizeof(tlv_ptp_adj->neighbor_extd_local_circuit_id))) goto trunctlv; - printf("\n\t\t\tNeighbor Extended Local circuit ID: 0x%08x", - EXTRACT_32BITS(tlv_ptp_adj->neighbor_ext_local_circuit_id)); + printf("\n\t Neighbor Extended Local circuit-ID: 0x%08x", + EXTRACT_32BITS(tlv_ptp_adj->neighbor_extd_local_circuit_id)); } break; case TLV_PROTOCOLS: - printf("Protocols supported (%u)", len); - printf("\n\t\t\tNLPID(s): "); - for (i = 0; i < len; i++) { - if (!TTEST2(*(pptr+i), 1)) + printf("\n\t NLPID(s): "); + while (tmp>0) { + if (!TTEST2(*(tptr), 1)) goto trunctlv; - printf("%s (0x%02x)",tok2str(isis_nlpid_values, "Unknown", *(pptr+i)),*(pptr+i)); - if (i<len-1) + printf("%s (0x%02x)", + tok2str(osi_nlpid_values, + "unknown", + *tptr), + *tptr); + if (tmp>1) /* further NPLIDs ? - put comma */ printf(", "); + tptr++; + tmp--; } break; case TLV_TE_ROUTER_ID: - printf("Traffic Engineering Router ID (%u)",len); if (!TTEST2(*pptr, 4)) goto trunctlv; - printf("\n\t\t\tTraffic Engineering Router ID: %s", ipaddr_string(pptr)); + printf("\n\t Traffic Engineering Router ID: %s", ipaddr_string(pptr)); break; case TLV_IPADDR: - printf("IPv4 Interface address(es) (%u)",len); - i=len; - tptr=pptr; - while (i>0) { + while (tmp>0) { if (!TTEST2(*tptr, 4)) goto trunctlv; - printf("\n\t\t\tIPv4 interface address: %s", ipaddr_string(tptr)); + printf("\n\t IPv4 interface address: %s", ipaddr_string(tptr)); tptr += 4; - i -= 4; + tmp -= 4; } break; case TLV_HOSTNAME: - printf("Hostname (%u)", len); - printf("\n\t\t\tHostname: "); - for(i = 0; i < len; i++) { - if (!TTEST2(*(pptr+i), 1)) + printf("\n\t Hostname: "); + while (tmp>0) { + if (!TTEST2(*tptr, 1)) goto trunctlv; - printf("%c",*(pptr+i)); + printf("%c",*tptr++); + tmp--; + } + break; + + case TLV_SHARED_RISK_GROUP: + if (!TTEST2(*tptr, NODE_ID_LEN)) + goto trunctlv; + printf("\n\t IS Neighbor: %s", isis_print_id(tptr, NODE_ID_LEN)); + tptr+=(NODE_ID_LEN); + tmp-=(NODE_ID_LEN); + + if (!TTEST2(*tptr, 1)) + goto trunctlv; + printf(", Flags: [%s]", ISIS_MASK_TLV_SHARED_RISK_GROUP(*tptr++) ? "numbered" : "unnumbered"); + tmp--; + + if (!TTEST2(*tptr,4)) + goto trunctlv; + printf("\n\t IPv4 interface address: %s", ipaddr_string(tptr)); + tptr+=4; + tmp-=4; + + if (!TTEST2(*tptr,4)) + goto trunctlv; + printf("\n\t IPv4 neighbor address: %s", ipaddr_string(tptr)); + tptr+=4; + tmp-=4; + + while (tmp>0) { + if (!TTEST2(*tptr, 4)) + goto trunctlv; + printf("\n\t Link-ID: 0x%08x", EXTRACT_32BITS(tptr)); + tptr+=4; + tmp-=4; } break; - case TLV_LSP: - tlv_lsp = (const struct isis_tlv_lsp *)pptr; - printf("LSP entries (%u)", len); - i=0; - while(i<len) { - printf("\n\t\t\tlsp-id: "); - if (!isis_print_nodeid(tlv_lsp->lsp_id)) - return (1); - if (!TTEST((tlv_lsp->lsp_id)[SYSTEM_ID_LEN+1])) + case TLV_LSP: + tlv_lsp = (const struct isis_tlv_lsp *)tptr; + while(tmp>0) { + if (!TTEST((tlv_lsp->lsp_id)[LSP_ID_LEN-1])) goto trunctlv; - printf("-%02x",(tlv_lsp->lsp_id)[SYSTEM_ID_LEN+1]); + printf("\n\t lsp-id: %s", + isis_print_id(tlv_lsp->lsp_id, LSP_ID_LEN)); if (!TTEST2(tlv_lsp->sequence_number, 4)) goto trunctlv; - printf("\n\t\t\t sequence number: 0x%08x",EXTRACT_32BITS(tlv_lsp->sequence_number)); + printf(", seq: 0x%08x",EXTRACT_32BITS(tlv_lsp->sequence_number)); if (!TTEST2(tlv_lsp->remaining_lifetime, 2)) goto trunctlv; - printf("\n\t\t\t Remaining lifetime: %5ds",EXTRACT_16BITS(tlv_lsp->remaining_lifetime)); + printf(", lifetime: %5ds",EXTRACT_16BITS(tlv_lsp->remaining_lifetime)); if (!TTEST2(tlv_lsp->checksum, 2)) goto trunctlv; - printf("\n\t\t\t checksum: 0x%04x",EXTRACT_16BITS(tlv_lsp->checksum)); - i+=sizeof(struct isis_tlv_lsp); + printf(", chksum: 0x%04x",EXTRACT_16BITS(tlv_lsp->checksum)); + tmp-=sizeof(struct isis_tlv_lsp); tlv_lsp++; } break; case TLV_CHECKSUM: - if (!TTEST2(*pptr, 2)) + if (!TTEST2(*tptr, 2)) goto trunctlv; - printf("Checksum (%u)", len); - printf("\n\t\t\tchecksum: 0x%04x", - EXTRACT_16BITS(pptr)); - - if (osi_cksum(optr, length, off)) - printf(" (incorrect)"); - else - printf(" (correct)"); + printf("\n\t checksum: 0x%04x ", EXTRACT_16BITS(tptr)); + /* do not attempt to verify the checksum if it is zero + * most likely a HMAC-MD5 TLV is also present and + * to avoid conflicts the checksum TLV is zeroed. + * see rfc3358 for details + */ + if (EXTRACT_16BITS(tptr) == 0) + printf("(unverified)"); + else printf("(%s)", osi_cksum(optr, length) ? "incorrect" : "correct"); break; case TLV_MT_SUPPORTED: - printf("Multi Topology (%u)",len); - i=len; - tptr=pptr; - while (i>1) { - /* length can only be a multiple of 2, otherwise there is + while (tmp>1) { + /* length can only be a multiple of 2, otherwise there is something broken -> so decode down until length is 1 */ - if (i!=1) { - if (!TTEST2(*tptr, 2)) - goto trunctlv; - printf("\n\t\t\t"); - switch(EXTRACT_16BITS(tptr)&0x0fff) { - - case 0: - printf("IPv4 unicast"); - break; - - case 1: - printf("In-Band Management"); - break; - - case 2: - printf("IPv6 unicast"); - break; - - case 3: - printf("Multicast"); - break; - - case 4095: - printf("Development, Experimental or Proprietary"); - break; - - default: - printf("Reserved for IETF Consensus"); - break; - } - printf(" Topology (0x%03x)%s%s", - EXTRACT_16BITS(tptr)&0xfff, - (EXTRACT_16BITS(tptr)&0x8000) ? "" : ", no sub-TLVs present", - (EXTRACT_16BITS(tptr)&0x4000) ? ", ATT bit set" : "" ); + if (tmp!=1) { + mt_len = isis_print_mtid(tptr, "\n\t "); + if (mt_len == 0) /* did something go wrong ? */ + goto trunctlv; + tptr+=mt_len; + tmp-=mt_len; } else { - printf("\n\t\t\tmalformed MT-ID"); + printf("\n\t malformed MT-ID"); break; } - i-=2; - tptr+=2; } break; case TLV_RESTART_SIGNALING: - tptr=pptr; - printf("Restart Signaling (%u)",len); - if (!TTEST2(*tptr, 3)) - goto trunctlv; - - printf("\n\t\t\tRestart Request bit %s, Restart Acknowledgement bit %s\n\t\t\tRemaining holding time: %us", - ISIS_MASK_RESTART_RR(*tptr) ? "set" : "clear", - ISIS_MASK_RESTART_RA(*tptr) ? "set" : "clear", - EXTRACT_16BITS(tptr+1)); - tptr += 3; - + if (!TTEST2(*tptr, 3)) + goto trunctlv; + printf("\n\t Flags [%s], Remaining holding time %us", + bittok2str(isis_restart_flag_values, "none", *tptr), + EXTRACT_16BITS(tptr+1)); + tptr+=3; break; - default: - printf("unknown TLV, type %d, length %d\n\t\t\t", type, len); - tptr=pptr; + case TLV_IDRP_INFO: + if (!TTEST2(*tptr, 1)) + goto trunctlv; + printf("\n\t Inter-Domain Information Type: %s", + tok2str(isis_subtlv_idrp_values, + "Unknown (0x%02x)", + *tptr)); + switch (*tptr++) { + case SUBTLV_IDRP_ASN: + if (!TTEST2(*tptr, 2)) /* fetch AS number */ + goto trunctlv; + printf("AS Number: %u",EXTRACT_16BITS(tptr)); + break; + case SUBTLV_IDRP_LOCAL: + case SUBTLV_IDRP_RES: + default: + if(!print_unknown_data(tptr,"\n\t ",tlv_len-1)) + return(0); + break; + } + break; - for(i=0;i<len;i++) { - if (!TTEST2(*(tptr+i), 1)) - goto trunctlv; - printf("%02x",*(tptr+i)); /* formatted hex output of unknown TLV data */ - if (i%2) - printf(" "); - if (i/16!=(i+1)/16) { - if (i<(len-1)) - printf("\n\t\t\t"); - } - } + case TLV_LSP_BUFFERSIZE: + if (!TTEST2(*tptr, 2)) + goto trunctlv; + printf("\n\t LSP Buffersize: %u",EXTRACT_16BITS(tptr)); + break; + + case TLV_PART_DIS: + while (tmp >= SYSTEM_ID_LEN) { + if (!TTEST2(*tptr, SYSTEM_ID_LEN)) + goto trunctlv; + printf("\n\t %s",isis_print_id(tptr,SYSTEM_ID_LEN)); + tptr+=SYSTEM_ID_LEN; + tmp-=SYSTEM_ID_LEN; + } + break; + + case TLV_PREFIX_NEIGH: + if (!TTEST2(*tptr, sizeof(struct isis_metric_block))) + goto trunctlv; + printf("\n\t Metric Block"); + isis_print_metric_block((const struct isis_metric_block *)tptr); + tptr+=sizeof(struct isis_metric_block); + tmp-=sizeof(struct isis_metric_block); + + while(tmp>0) { + if (!TTEST2(*tptr, 1)) + goto trunctlv; + prefix_len=*tptr++; /* read out prefix length in semioctets*/ + tmp--; + if (!TTEST2(*tptr, prefix_len/2)) + goto trunctlv; + printf("\n\t\tAddress: %s/%u", + print_nsap(tptr,prefix_len/2), + prefix_len*4); + tptr+=prefix_len/2; + tmp-=prefix_len/2; + } + break; + + case TLV_IIH_SEQNR: + if (!TTEST2(*tptr, 4)) /* check if four bytes are on the wire */ + goto trunctlv; + printf("\n\t Sequence number: %u", EXTRACT_32BITS(tptr) ); + break; + + case TLV_VENDOR_PRIVATE: + if (!TTEST2(*tptr, 3)) /* check if enough byte for a full oui */ + goto trunctlv; + printf("\n\t Vendor OUI Code: 0x%06x", EXTRACT_24BITS(tptr) ); + tptr+=3; + tmp-=3; + if (tmp > 0) /* hexdump the rest */ + if(!print_unknown_data(tptr,"\n\t\t",tmp)) + return(0); + break; + /* + * FIXME those are the defined TLVs that lack a decoder + * you are welcome to contribute code ;-) + */ + + case TLV_DECNET_PHASE4: + case TLV_LUCENT_PRIVATE: + case TLV_IPAUTH: + case TLV_NORTEL_PRIVATE1: + case TLV_NORTEL_PRIVATE2: + + default: + if (vflag <= 1) { + if(!print_unknown_data(pptr,"\n\t\t",tlv_len)) + return(0); + } break; } + /* do we want to see an additionally hexdump ? */ + if (vflag> 1) { + if(!print_unknown_data(pptr,"\n\t ",tlv_len)) + return(0); + } - pptr += len; - packet_len -= len; + pptr += tlv_len; + packet_len -= tlv_len; } if (packet_len != 0) { - printf("\n\t\t\t %d straggler bytes", packet_len); + printf("\n\t %u straggler bytes", packet_len); } return (1); -trunc: + trunc: fputs("[|isis]", stdout); return (1); -trunctlv: - printf("\n\t\t\t packet exceeded snapshot"); + trunctlv: + printf("\n\t\t packet exceeded snapshot"); return(1); } @@ -1568,20 +2025,15 @@ trunctlv: */ static int -osi_cksum(register const u_char *p, register u_int len, u_char *off) +osi_cksum(const u_int8_t *tptr, u_int len) { int32_t c0 = 0, c1 = 0; - if ((off[0] == 0) && (off[1] == 0)) - return 0; - - off[0] = off[1] = 0; while ((int)--len >= 0) { - c0 += *p++; + c0 += *tptr++; c0 %= 255; c1 += c0; c1 %= 255; } return (c0 | c1); } - diff --git a/contrib/tcpdump/print-lcp.c b/contrib/tcpdump/print-lcp.c deleted file mode 100644 index ddea9c6053c7..000000000000 --- a/contrib/tcpdump/print-lcp.c +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that: (1) source code distributions - * retain the above copyright notice and this paragraph in its entirety, (2) - * distributions including binary code include the above copyright notice and - * this paragraph in its entirety in the documentation or other materials - * provided with the distribution, and (3) all advertising materials mentioning - * features or use of this software display the following acknowledgement: - * ``This product includes software developed by the University of California, - * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of - * the University 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#ifndef lint -static const char rcsid[] = -"@(#) $Header: /tcpdump/master/tcpdump/print-lcp.c,v 1.9 2000/10/06 04:23:12 guy Exp $ (LBL)"; -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <sys/param.h> -#include <sys/time.h> -#include <sys/socket.h> - -#include <netinet/in.h> - -#include <stdio.h> -#include <string.h> - -#include "interface.h" -#include "addrtoname.h" -#include "extract.h" /* must come after interface.h */ -#include "ppp.h" - -/* Codes */ -enum { - LCP_CONFREQ = 1, - LCP_CONFACK = 2, - LCP_CONFNAK = 3, - LCP_CONFREJ = 4, - LCP_TERMREQ = 5, - LCP_TERMACK = 6, - LCP_CODEREJ = 7, - LCP_PROTREJ = 8, - LCP_ECHOREQ = 9, - LCP_ECHOREP = 10, - LCP_DISCARD = 11 -}; - -static struct tok lcpcode2str[] = { - { LCP_CONFREQ, "ConfReq" }, - { LCP_CONFACK, "ConfAck" }, - { LCP_CONFNAK, "ConfNak" }, - { LCP_CONFREJ, "ConfRej" }, - { LCP_TERMREQ, "TermReq" }, - { LCP_TERMACK, "TermAck" }, - { LCP_CODEREJ, "CodeRej" }, - { LCP_PROTREJ, "ProtRej" }, - { LCP_ECHOREQ, "EchoReq" }, - { LCP_ECHOREP, "EchoRep" }, - { LCP_DISCARD, "Discard" }, - { 0, NULL } -}; - - -enum { - LCP_RESERVED = 0, - LCP_MRU = 1, - LCP_ASYNCMAP = 2, - LCP_AUTHPROTO = 3, - LCP_QUALPROTO = 4, - LCP_MAGICNUM = 5, - LCP_PCOMP = 7, - LCP_ACFCOMP = 8, - LCP_CALLBACK = 13 -}; - -static struct tok lcpoption2str[] = { - { LCP_RESERVED, "reserved"}, - { LCP_MRU, "mru"}, - { LCP_ASYNCMAP, "asyncmap"}, - { LCP_AUTHPROTO, "auth"}, - { LCP_QUALPROTO, "qual"}, - { LCP_MAGICNUM, "magic"}, - { LCP_PCOMP, "pcomp"}, - { LCP_ACFCOMP, "acfcomp"}, - { LCP_CALLBACK, "callback"}, - { 0, NULL } -}; - -static struct tok lcpauth2str[] = { - {0xc023, "PAP"}, - {0xc223, "CHAP"}, - { 0, NULL } -}; - -static struct tok lcpqual2str[] = { - {0xc025, "LQR"}, - { 0, NULL } -}; - -static struct tok lcpchap2str[] = { - {0x05, "MD5"}, - {0x80, "MS"}, - { 0, NULL } -}; - -void -lcp_print(register const u_char *bp, u_int length) -{ - u_short lcp_code, lcp_id, lcp_length; - const u_char *lcp_data; - - lcp_data = bp+4; - - if (snapend < lcp_data) { - printf(" [LCP|]"); - return; - } - - lcp_code = bp[0]; - lcp_id = bp[1]; - lcp_length = EXTRACT_16BITS(bp+2); - - printf("LCP %s id=0x%x", tok2str(lcpcode2str, "LCP-#%d", lcp_code), lcp_id); - - switch (lcp_code) { - case LCP_CONFREQ: - case LCP_CONFACK: - case LCP_CONFNAK: - case LCP_CONFREJ: - /* Print Options */ - { - u_char lcpopt_type, lcpopt_length; - const u_char *p=lcp_data; - while (p+2 < lcp_data+lcp_length && p+2 < snapend) { - lcpopt_type = p[0]; - lcpopt_length = p[1]; - p+=2; - printf(" <%s ",tok2str(lcpoption2str, "option-#%d", lcpopt_type)); - if (lcpopt_length) - switch (lcpopt_type) { - case LCP_MRU: - if (snapend < p+2) return; - printf("%d",ntohs(*(u_short*)p)); - if (lcpopt_length != 4) printf(" len=%d!",lcpopt_length); - break; - case LCP_AUTHPROTO: - if (snapend < p+2) return; - printf("%s",tok2str(lcpauth2str, "AUTH-%#x", ntohs(*(u_short*)p))); - if (lcpopt_length < 4) printf(" len=%d!",lcpopt_length); - if (lcpopt_length >= 5 && p < snapend) - printf(" %s",tok2str(lcpchap2str, "%#x", p[0])); - break; - case LCP_QUALPROTO: - if (snapend < p+2) return; - printf("%s",tok2str(lcpqual2str, "QUAL-%#x", ntohs(*(u_short*)p))); - if (lcpopt_length < 4) printf(" len=%d!",lcpopt_length); - /* Print data field of auth? */ - break; - case LCP_ASYNCMAP: - case LCP_MAGICNUM: - if (snapend < p+4) return; - printf("%#x", (unsigned)ntohl(*(u_long*)p)); - if (lcpopt_length != 6) printf(" len=%d!",lcpopt_length); - break; - case LCP_PCOMP: - case LCP_ACFCOMP: - case LCP_RESERVED: - if (lcpopt_length != 2) printf(" len=%d!",lcpopt_length); - break; - default: - if (lcpopt_length != 2) printf(" len=%d",lcpopt_length); - break; - } - printf(">"); - p+=lcpopt_length-2; - } - } - break; - case LCP_ECHOREQ: - case LCP_ECHOREP: - case LCP_DISCARD: - if (snapend < lcp_data+4) return; - printf(" magic=%#x", (unsigned)ntohl(*(u_long *) lcp_data)); - lcp_data +=4; - break; - case LCP_PROTREJ: - if (snapend < lcp_data+2) return; - printf(" prot=%s", tok2str(ppptype2str, "PROT-%#x", ntohs(*(u_short *) lcp_data))); - /* TODO print rejected packet too ? */ - break; - case LCP_CODEREJ: - if (snapend < lcp_data+4) return; - printf(" "); - lcp_print(lcp_data, (lcp_length+lcp_data > snapend ? snapend-lcp_data : lcp_length)); - break; - case LCP_TERMREQ: - case LCP_TERMACK: - break; - default: - break; - } - - return; -} diff --git a/contrib/tcpdump/print-llc.c b/contrib/tcpdump/print-llc.c index 39994a89ee63..49655b88881c 100644 --- a/contrib/tcpdump/print-llc.c +++ b/contrib/tcpdump/print-llc.c @@ -25,21 +25,16 @@ */ #ifndef lint -static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/print-llc.c,v 1.43 2001/10/08 21:25:22 fenner Exp $"; +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-llc.c,v 1.53.2.3 2003/12/29 22:33:18 hannes Exp $"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include <sys/param.h> -#include <sys/time.h> +#include <tcpdump-stdinc.h> -#include <netinet/in.h> - -#include <ctype.h> -#include <netdb.h> #include <stdio.h> #include <string.h> @@ -50,6 +45,23 @@ static const char rcsid[] = #include "llc.h" #include "ethertype.h" +static struct tok llc_values[] = { + { LLCSAP_NULL, "Null" }, + { LLCSAP_GLOBAL, "Global" }, + { LLCSAP_8021B_I, "802.1B I" }, + { LLCSAP_8021B_G, "802.1B G" }, + { LLCSAP_IP, "IP" }, + { LLCSAP_PROWAYNM, "ProWay NM" }, + { LLCSAP_8021D, "STP" }, + { LLCSAP_RS511, "RS511" }, + { LLCSAP_ISO8208, "ISO8208" }, + { LLCSAP_PROWAY, "ProWay" }, + { LLCSAP_SNAP, "SNAP" }, + { LLCSAP_IPX, "IPX" }, + { LLCSAP_NETBEUI, "NetBeui" }, + { LLCSAP_ISONS, "OSI" }, +}; + static struct tok cmd2str[] = { { LLC_UI, "ui" }, { LLC_TEST, "test" }, @@ -83,6 +95,14 @@ llc_print(const u_char *p, u_int length, u_int caplen, /* Watch out for possible alignment problems */ memcpy((char *)&llc, (char *)p, min(caplen, sizeof(llc))); + if (eflag) + printf("LLC, dsap %s (0x%02x), ssap %s (0x%02x), cmd 0x%02x, ", + tok2str(llc_values,"Unknown",llc.dsap), + llc.dsap, + tok2str(llc_values,"Unknown",llc.ssap), + llc.ssap, + llc.llcu); + if (llc.ssap == LLCSAP_GLOBAL && llc.dsap == LLCSAP_GLOBAL) { /* * This is an Ethernet_802.3 IPX frame; it has an @@ -98,6 +118,7 @@ llc_print(const u_char *p, u_int length, u_int caplen, * such as an 802.11 network; this has appeared in at * least one capture file.) */ + printf("(NOV-802.3) "); ipx_print(p, length); return (1); } @@ -107,6 +128,11 @@ llc_print(const u_char *p, u_int length, u_int caplen, return (1); } + if (llc.ssap == LLCSAP_IP && llc.dsap == LLCSAP_IP) { + ip_print(p+4, length-4); + return (1); + } + if (llc.ssap == LLCSAP_IPX && llc.dsap == LLCSAP_IPX && llc.llcui == LLC_UI) { /* @@ -116,6 +142,7 @@ llc_print(const u_char *p, u_int length, u_int caplen, * * Skip DSAP, LSAP, and control field. */ + printf("(NOV-802.2) "); p += 3; length -= 3; caplen -= 3; @@ -171,7 +198,7 @@ llc_print(const u_char *p, u_int length, u_int caplen, #endif if (llc.ssap == LLCSAP_ISONS && llc.dsap == LLCSAP_ISONS && llc.llcui == LLC_UI) { - isoclns_print(p + 3, length - 3, caplen - 3, esrc, edst); + isoclns_print(p + 3, length - 3, caplen - 3); return (1); } @@ -184,8 +211,6 @@ llc_print(const u_char *p, u_int length, u_int caplen, default_print((u_char *)p, caplen); return (0); } - if (vflag) - (void)printf("snap %s ", protoid_string(llc.llcpi)); caplen -= sizeof(llc); length -= sizeof(llc); @@ -193,45 +218,15 @@ llc_print(const u_char *p, u_int length, u_int caplen, orgcode = EXTRACT_24BITS(&llc.llc_orgcode[0]); et = EXTRACT_16BITS(&llc.llc_ethertype[0]); - switch (orgcode) { - case OUI_ENCAP_ETHER: - case OUI_CISCO_90: - /* - * This is an encapsulated Ethernet packet, - * or a packet bridged by some piece of - * Cisco hardware; the protocol ID is - * an Ethernet protocol type. - */ - ret = ether_encap_print(et, p, length, caplen, - extracted_ethertype); - if (ret) - return (ret); - break; - - case OUI_APPLETALK: - if (et == ETHERTYPE_ATALK) { - /* - * No, I have no idea why Apple used one - * of their own OUIs, rather than - * 0x000000, and an Ethernet packet - * type, for Appletalk data packets, - * but used 0x000000 and an Ethernet - * packet type for AARP packets. - */ - ret = ether_encap_print(et, p, length, caplen, - extracted_ethertype); - if (ret) - return (ret); - } - break; - - case OUI_CISCO: - if (et == ETHERTYPE_CISCO_CDP) { - cdp_print(p, length, caplen, esrc, edst); - return 1; - } - break; - } + /* + * XXX - what *is* the right bridge pad value here? + * Does anybody ever bridge one form of LAN traffic + * over a networking type that uses 802.2 LLC? + */ + ret = snap_print(p, length, caplen, extracted_ethertype, + orgcode, et, 2); + if (ret) + return (ret); } if ((llc.ssap & ~LLC_GSAP) == llc.dsap) { @@ -300,7 +295,7 @@ llc_print(const u_char *p, u_int length, u_int caplen, } if ((control & LLC_S_FMT) == LLC_S_FMT) { - static char *llc_s[] = { "rr", "rej", "rnr", "03" }; + static const char *llc_s[] = { "rr", "rej", "rnr", "03" }; (void)printf("%s (r=%d,%c)", llc_s[LLC_S_CMD(control)], LLC_IS_NR(control), @@ -316,8 +311,121 @@ llc_print(const u_char *p, u_int length, u_int caplen, caplen -= 4; } (void)printf(" len=%d", length); - if (caplen > 0 && !qflag) { - default_print_unaligned(p, caplen); - } return(1); } + +int +snap_print(const u_char *p, u_int length, u_int caplen, + u_short *extracted_ethertype, u_int32_t orgcode, u_short et, + u_int bridge_pad) +{ + register int ret; + + switch (orgcode) { + case OUI_ENCAP_ETHER: + case OUI_CISCO_90: + /* + * This is an encapsulated Ethernet packet, + * or a packet bridged by some piece of + * Cisco hardware; the protocol ID is + * an Ethernet protocol type. + */ + ret = ether_encap_print(et, p, length, caplen, + extracted_ethertype); + if (ret) + return (ret); + break; + + case OUI_APPLETALK: + if (et == ETHERTYPE_ATALK) { + /* + * No, I have no idea why Apple used one + * of their own OUIs, rather than + * 0x000000, and an Ethernet packet + * type, for Appletalk data packets, + * but used 0x000000 and an Ethernet + * packet type for AARP packets. + */ + ret = ether_encap_print(et, p, length, caplen, + extracted_ethertype); + if (ret) + return (ret); + } + break; + + case OUI_CISCO: + if (et == PID_CISCO_CDP) { + cdp_print(p, length, caplen); + return (1); + } + break; + + case OUI_RFC2684: + switch (et) { + + case PID_RFC2684_ETH_FCS: + case PID_RFC2684_ETH_NOFCS: + /* + * XXX - remove the last two bytes for + * PID_RFC2684_ETH_FCS? + */ + /* + * Skip the padding. + */ + caplen -= bridge_pad; + length -= bridge_pad; + p += bridge_pad; + + /* + * What remains is an Ethernet packet. + */ + ether_print(p, length, caplen); + return (1); + + case PID_RFC2684_802_5_FCS: + case PID_RFC2684_802_5_NOFCS: + /* + * XXX - remove the last two bytes for + * PID_RFC2684_ETH_FCS? + */ + /* + * Skip the padding, but not the Access + * Control field. + */ + caplen -= bridge_pad; + length -= bridge_pad; + p += bridge_pad; + + /* + * What remains is an 802.5 Token Ring + * packet. + */ + token_print(p, length, caplen); + return (1); + + case PID_RFC2684_FDDI_FCS: + case PID_RFC2684_FDDI_NOFCS: + /* + * XXX - remove the last two bytes for + * PID_RFC2684_ETH_FCS? + */ + /* + * Skip the padding. + */ + caplen -= bridge_pad + 1; + length -= bridge_pad + 1; + p += bridge_pad + 1; + + /* + * What remains is an FDDI packet. + */ + fddi_print(p, length, caplen); + return (1); + + case PID_RFC2684_BPDU: + stp_print(p, length); + return (1); + } + } + return (0); +} diff --git a/contrib/tcpdump/print-nfs.c b/contrib/tcpdump/print-nfs.c index c66c97e98877..208faa184ada 100644 --- a/contrib/tcpdump/print-nfs.c +++ b/contrib/tcpdump/print-nfs.c @@ -22,29 +22,25 @@ */ #ifndef lint -static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/print-nfs.c,v 1.89.4.2 2002/06/01 23:51:14 guy Exp $ (LBL)"; +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-nfs.c,v 1.99.2.2 2003/11/16 08:51:35 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include <sys/param.h> -#include <sys/time.h> -#include <sys/socket.h> - -#include <netinet/in.h> +#include <tcpdump-stdinc.h> #include <rpc/rpc.h> -#include <ctype.h> #include <pcap.h> #include <stdio.h> #include <string.h> #include "interface.h" #include "addrtoname.h" +#include "extract.h" #include "nfs.h" #include "nfsfh.h" @@ -170,7 +166,7 @@ static struct tok type2str[] = { * * Assume that a system that has INT64_FORMAT defined, has a 64-bit * integer datatype and can print it. - */ + */ #define UNSIGNED 0 #define SIGNED 1 @@ -181,7 +177,7 @@ static int print_int64(const u_int32_t *dp, int how) #ifdef INT64_FORMAT u_int64_t res; - res = ((u_int64_t)ntohl(dp[0]) << 32) | (u_int64_t)ntohl(dp[1]); + res = ((u_int64_t)EXTRACT_32BITS(&dp[0]) << 32) | (u_int64_t)EXTRACT_32BITS(&dp[1]); switch (how) { case SIGNED: printf(INT64_FORMAT, res); @@ -196,12 +192,18 @@ static int print_int64(const u_int32_t *dp, int how) return (0); } #else + u_int32_t high; + + high = EXTRACT_32BITS(&dp[0]); + switch (how) { case SIGNED: case UNSIGNED: case HEX: - printf("0x%x%08x", (u_int32_t)ntohl(dp[0]), - (u_int32_t)ntohl(dp[1])); + if (high != 0) + printf("0x%x%08x", high, EXTRACT_32BITS(&dp[1])); + else + printf("0x%x", EXTRACT_32BITS(&dp[1])); break; default: return (0); @@ -253,41 +255,61 @@ static const u_int32_t * parse_sattr3(const u_int32_t *dp, struct nfsv3_sattr *sa3) { TCHECK(dp[0]); - if ((sa3->sa_modeset = ntohl(*dp++))) { + sa3->sa_modeset = EXTRACT_32BITS(dp); + dp++; + if (sa3->sa_modeset) { TCHECK(dp[0]); - sa3->sa_mode = ntohl(*dp++); + sa3->sa_mode = EXTRACT_32BITS(dp); + dp++; } TCHECK(dp[0]); - if ((sa3->sa_uidset = ntohl(*dp++))) { + sa3->sa_uidset = EXTRACT_32BITS(dp); + dp++; + if (sa3->sa_uidset) { TCHECK(dp[0]); - sa3->sa_uid = ntohl(*dp++); + sa3->sa_uid = EXTRACT_32BITS(dp); + dp++; } TCHECK(dp[0]); - if ((sa3->sa_gidset = ntohl(*dp++))) { + sa3->sa_gidset = EXTRACT_32BITS(dp); + dp++; + if (sa3->sa_gidset) { TCHECK(dp[0]); - sa3->sa_gid = ntohl(*dp++); + sa3->sa_gid = EXTRACT_32BITS(dp); + dp++; } TCHECK(dp[0]); - if ((sa3->sa_sizeset = ntohl(*dp++))) { + sa3->sa_sizeset = EXTRACT_32BITS(dp); + dp++; + if (sa3->sa_sizeset) { TCHECK(dp[0]); - sa3->sa_size = ntohl(*dp++); + sa3->sa_size = EXTRACT_32BITS(dp); + dp++; } TCHECK(dp[0]); - if ((sa3->sa_atimetype = ntohl(*dp++)) == NFSV3SATTRTIME_TOCLIENT) { + sa3->sa_atimetype = EXTRACT_32BITS(dp); + dp++; + if (sa3->sa_atimetype == NFSV3SATTRTIME_TOCLIENT) { TCHECK(dp[1]); - sa3->sa_atime.nfsv3_sec = ntohl(*dp++); - sa3->sa_atime.nfsv3_nsec = ntohl(*dp++); + sa3->sa_atime.nfsv3_sec = EXTRACT_32BITS(dp); + dp++; + sa3->sa_atime.nfsv3_nsec = EXTRACT_32BITS(dp); + dp++; } TCHECK(dp[0]); - if ((sa3->sa_mtimetype = ntohl(*dp++)) == NFSV3SATTRTIME_TOCLIENT) { + sa3->sa_mtimetype = EXTRACT_32BITS(dp); + dp++; + if (sa3->sa_mtimetype == NFSV3SATTRTIME_TOCLIENT) { TCHECK(dp[1]); - sa3->sa_mtime.nfsv3_sec = ntohl(*dp++); - sa3->sa_mtime.nfsv3_nsec = ntohl(*dp++); + sa3->sa_mtime.nfsv3_sec = EXTRACT_32BITS(dp); + dp++; + sa3->sa_mtime.nfsv3_nsec = EXTRACT_32BITS(dp); + dp++; } return dp; @@ -330,15 +352,15 @@ nfsreply_print(register const u_char *bp, u_int length, if (!nflag) { strlcpy(srcid, "nfs", sizeof(srcid)); snprintf(dstid, sizeof(dstid), "%u", - (u_int32_t)ntohl(rp->rm_xid)); + EXTRACT_32BITS(&rp->rm_xid)); } else { snprintf(srcid, sizeof(srcid), "%u", NFS_PORT); snprintf(dstid, sizeof(dstid), "%u", - (u_int32_t)ntohl(rp->rm_xid)); + EXTRACT_32BITS(&rp->rm_xid)); } print_nfsaddr(bp2, srcid, dstid); (void)printf("reply %s %d", - ntohl(rp->rm_reply.rp_stat) == MSG_ACCEPTED? + EXTRACT_32BITS(&rp->rm_reply.rp_stat) == MSG_ACCEPTED? "ok":"ERR", length); @@ -361,11 +383,11 @@ parsereq(register const struct rpc_msg *rp, register u_int length) */ dp = (u_int32_t *)&rp->rm_call.cb_cred; TCHECK(dp[1]); - len = ntohl(dp[1]); + len = EXTRACT_32BITS(&dp[1]); if (len < length) { dp += (len + (2 * sizeof(*dp) + 3)) / sizeof(*dp); TCHECK(dp[1]); - len = ntohl(dp[1]); + len = EXTRACT_32BITS(&dp[1]); if (len < length) { dp += (len + (2 * sizeof(*dp) + 3)) / sizeof(*dp); TCHECK2(dp[0], 0); @@ -383,11 +405,11 @@ trunc: static const u_int32_t * parsefh(register const u_int32_t *dp, int v3) { - int len; + u_int len; if (v3) { TCHECK(dp[0]); - len = (int)ntohl(*dp) / 4; + len = EXTRACT_32BITS(dp) / 4; dp++; } else len = NFSX_V2FH / 4; @@ -463,11 +485,11 @@ nfsreq_print(register const u_char *bp, u_int length, rp = (const struct rpc_msg *)bp; if (!nflag) { snprintf(srcid, sizeof(srcid), "%u", - (u_int32_t)ntohl(rp->rm_xid)); + EXTRACT_32BITS(&rp->rm_xid)); strlcpy(dstid, "nfs", sizeof(dstid)); } else { snprintf(srcid, sizeof(srcid), "%u", - (u_int32_t)ntohl(rp->rm_xid)); + EXTRACT_32BITS(&rp->rm_xid)); snprintf(dstid, sizeof(dstid), "%u", NFS_PORT); } print_nfsaddr(bp2, srcid, dstid); @@ -475,8 +497,8 @@ nfsreq_print(register const u_char *bp, u_int length, xid_map_enter(rp, bp2); /* record proc number for later on */ - v3 = (ntohl(rp->rm_call.cb_vers) == NFS_VER3); - proc = ntohl(rp->rm_call.cb_proc); + v3 = (EXTRACT_32BITS(&rp->rm_call.cb_vers) == NFS_VER3); + proc = EXTRACT_32BITS(&rp->rm_call.cb_proc); if (!v3 && proc < NFS_NPROCS) proc = nfsv3_procid[proc]; @@ -515,7 +537,7 @@ nfsreq_print(register const u_char *bp, u_int length, if ((dp = parsereq(rp, length)) != NULL && (dp = parsefh(dp, v3)) != NULL) { TCHECK(dp[0]); - printf(" %04x", (u_int32_t)ntohl(dp[0])); + printf(" %04x", EXTRACT_32BITS(&dp[0])); return; } break; @@ -534,13 +556,13 @@ nfsreq_print(register const u_char *bp, u_int length, if (v3) { TCHECK(dp[2]); printf(" %u bytes @ ", - (u_int32_t) ntohl(dp[2])); + EXTRACT_32BITS(&dp[2])); print_int64(dp, UNSIGNED); } else { TCHECK(dp[1]); printf(" %u bytes @ %u", - (u_int32_t)ntohl(dp[1]), - (u_int32_t)ntohl(dp[0])); + EXTRACT_32BITS(&dp[1]), + EXTRACT_32BITS(&dp[0])); } return; } @@ -553,22 +575,22 @@ nfsreq_print(register const u_char *bp, u_int length, if (v3) { TCHECK(dp[4]); printf(" %u bytes @ ", - (u_int32_t) ntohl(dp[4])); + EXTRACT_32BITS(&dp[4])); print_int64(dp, UNSIGNED); if (vflag) { dp += 3; TCHECK(dp[0]); printf(" <%s>", tok2str(nfsv3_writemodes, - NULL, ntohl(*dp))); + NULL, EXTRACT_32BITS(dp))); } } else { TCHECK(dp[3]); printf(" %u (%u) bytes @ %u (%u)", - (u_int32_t)ntohl(dp[3]), - (u_int32_t)ntohl(dp[2]), - (u_int32_t)ntohl(dp[1]), - (u_int32_t)ntohl(dp[0])); + EXTRACT_32BITS(&dp[3]), + EXTRACT_32BITS(&dp[2]), + EXTRACT_32BITS(&dp[1]), + EXTRACT_32BITS(&dp[0])); } return; } @@ -607,15 +629,16 @@ nfsreq_print(register const u_char *bp, u_int length, if ((dp = parsereq(rp, length)) != 0 && (dp = parsefhn(dp, v3)) != 0) { TCHECK(*dp); - type = (nfs_type)ntohl(*dp++); + type = (nfs_type)EXTRACT_32BITS(dp); + dp++; if ((dp = parse_sattr3(dp, &sa3)) == 0) break; printf(" %s", tok2str(type2str, "unk-ft %d", type)); if (vflag && (type == NFCHR || type == NFBLK)) { TCHECK(dp[1]); printf(" %u/%u", - (u_int32_t)ntohl(dp[0]), - (u_int32_t)ntohl(dp[1])); + EXTRACT_32BITS(&dp[0]), + EXTRACT_32BITS(&dp[1])); dp += 2; } if (vflag) @@ -669,7 +692,7 @@ nfsreq_print(register const u_char *bp, u_int length, * offset cookie here. */ printf(" %u bytes @ ", - (u_int32_t) ntohl(dp[4])); + EXTRACT_32BITS(&dp[4])); print_int64(dp, SIGNED); if (vflag) printf(" verf %08x%08x", dp[2], @@ -681,8 +704,8 @@ nfsreq_print(register const u_char *bp, u_int length, * common, but offsets > 2^31 aren't. */ printf(" %u bytes @ %d", - (u_int32_t)ntohl(dp[1]), - (u_int32_t)ntohl(dp[0])); + EXTRACT_32BITS(&dp[1]), + EXTRACT_32BITS(&dp[0])); } return; } @@ -697,11 +720,11 @@ nfsreq_print(register const u_char *bp, u_int length, * We don't try to interpret the offset * cookie here. */ - printf(" %u bytes @ ", (u_int32_t) ntohl(dp[4])); + printf(" %u bytes @ ", EXTRACT_32BITS(&dp[4])); print_int64(dp, SIGNED); if (vflag) printf(" max %u verf %08x%08x", - (u_int32_t) ntohl(dp[5]), dp[2], dp[3]); + EXTRACT_32BITS(&dp[5]), dp[2], dp[3]); return; } break; @@ -731,14 +754,14 @@ nfsreq_print(register const u_char *bp, u_int length, printf(" commit"); if ((dp = parsereq(rp, length)) != NULL && (dp = parsefh(dp, v3)) != NULL) { - printf(" %u bytes @ ", (u_int32_t) ntohl(dp[2])); + printf(" %u bytes @ ", EXTRACT_32BITS(&dp[2])); print_int64(dp, UNSIGNED); return; } break; default: - printf(" proc-%u", (u_int32_t)ntohl(rp->rm_call.cb_proc)); + printf(" proc-%u", EXTRACT_32BITS(&rp->rm_call.cb_proc)); return; } @@ -761,9 +784,23 @@ nfs_printfh(register const u_int32_t *dp, const u_int len) { my_fsid fsid; ino_t ino; - char *sfsname = NULL; + const char *sfsname = NULL; + char *spacep; + + if (uflag) { + u_int i; + char const *sep = ""; + + printf(" fh["); + for (i=0; i<len; i++) { + (void)printf("%s%x", sep, dp[i]); + sep = ":"; + } + printf("]"); + return; + } - Parse_fh((caddr_t*)dp, len, &fsid, &ino, NULL, &sfsname, 0); + Parse_fh((const u_char *)dp, len, &fsid, &ino, NULL, &sfsname, 0); if (sfsname) { /* file system ID is ASCII, not numeric, for this server OS */ @@ -773,9 +810,9 @@ nfs_printfh(register const u_int32_t *dp, const u_int len) strncpy(temp, sfsname, NFSX_V3FHMAX); temp[sizeof(temp) - 1] = '\0'; /* Remove trailing spaces */ - sfsname = strchr(temp, ' '); - if (sfsname) - *sfsname = 0; + spacep = strchr(temp, ' '); + if (spacep) + *spacep = '\0'; (void)printf(" fh %s/", temp); } else { @@ -783,8 +820,8 @@ nfs_printfh(register const u_int32_t *dp, const u_int len) fsid.Fsid_dev.Major, fsid.Fsid_dev.Minor); } - if(fsid.Fsid_dev.Minor == 257 && uflag) - /* Print the undecoded handle */ + if(fsid.Fsid_dev.Minor == 257) + /* Print the undecoded handle */ (void)printf("%s", fsid.Opaque_Handle); else (void)printf("%ld", (long) ino); @@ -863,8 +900,8 @@ xid_map_enter(const struct rpc_msg *rp, const u_char *bp) memcpy(&xmep->server, &ip6->ip6_dst, sizeof(ip6->ip6_dst)); } #endif - xmep->proc = ntohl(rp->rm_call.cb_proc); - xmep->vers = ntohl(rp->rm_call.cb_vers); + xmep->proc = EXTRACT_32BITS(&rp->rm_call.cb_proc); + xmep->vers = EXTRACT_32BITS(&rp->rm_call.cb_vers); } /* @@ -885,7 +922,7 @@ xid_map_find(const struct rpc_msg *rp, const u_char *bp, u_int32_t *proc, int cmp; /* Start searching from where we last left off */ - i = xid_map_hint; + i = xid_map_hint; do { xmep = &xid_map[i]; cmp = 1; @@ -962,7 +999,7 @@ parserep(register const struct rpc_msg *rp, register u_int length) */ dp = ((const u_int32_t *)&rp->rm_reply) + 1; TCHECK(dp[1]); - len = ntohl(dp[1]); + len = EXTRACT_32BITS(&dp[1]); if (len >= length) return (NULL); /* @@ -974,7 +1011,7 @@ parserep(register const struct rpc_msg *rp, register u_int length) /* * now we can check the ar_stat field */ - astat = ntohl(*(enum accept_stat *)dp); + astat = EXTRACT_32BITS(dp); switch (astat) { case SUCCESS: @@ -1024,7 +1061,7 @@ parsestatus(const u_int32_t *dp, int *er) TCHECK(dp[0]); - errnum = ntohl(dp[0]); + errnum = EXTRACT_32BITS(&dp[0]); if (er) *er = errnum; if (errnum != 0) { @@ -1048,57 +1085,56 @@ parsefattr(const u_int32_t *dp, int verbose, int v3) if (verbose) { printf(" %s %o ids %d/%d", tok2str(type2str, "unk-ft %d ", - (u_int32_t)ntohl(fap->fa_type)), - (u_int32_t)ntohl(fap->fa_mode), - (u_int32_t)ntohl(fap->fa_uid), - (u_int32_t) ntohl(fap->fa_gid)); + EXTRACT_32BITS(&fap->fa_type)), + EXTRACT_32BITS(&fap->fa_mode), + EXTRACT_32BITS(&fap->fa_uid), + EXTRACT_32BITS(&fap->fa_gid)); if (v3) { TCHECK(fap->fa3_size); printf(" sz "); print_int64((u_int32_t *)&fap->fa3_size, UNSIGNED); - putchar(' '); } else { TCHECK(fap->fa2_size); - printf(" sz %d ", (u_int32_t) ntohl(fap->fa2_size)); + printf(" sz %d", EXTRACT_32BITS(&fap->fa2_size)); } } /* print lots more stuff */ if (verbose > 1) { if (v3) { TCHECK(fap->fa3_ctime); - printf("nlink %d rdev %d/%d ", - (u_int32_t)ntohl(fap->fa_nlink), - (u_int32_t) ntohl(fap->fa3_rdev.specdata1), - (u_int32_t) ntohl(fap->fa3_rdev.specdata2)); - printf("fsid "); - print_int64((u_int32_t *)&fap->fa2_fsid, HEX); - printf(" nodeid "); - print_int64((u_int32_t *)&fap->fa2_fileid, HEX); - printf(" a/m/ctime %u.%06u ", - (u_int32_t) ntohl(fap->fa3_atime.nfsv3_sec), - (u_int32_t) ntohl(fap->fa3_atime.nfsv3_nsec)); - printf("%u.%06u ", - (u_int32_t) ntohl(fap->fa3_mtime.nfsv3_sec), - (u_int32_t) ntohl(fap->fa3_mtime.nfsv3_nsec)); - printf("%u.%06u ", - (u_int32_t) ntohl(fap->fa3_ctime.nfsv3_sec), - (u_int32_t) ntohl(fap->fa3_ctime.nfsv3_nsec)); + printf(" nlink %d rdev %d/%d", + EXTRACT_32BITS(&fap->fa_nlink), + EXTRACT_32BITS(&fap->fa3_rdev.specdata1), + EXTRACT_32BITS(&fap->fa3_rdev.specdata2)); + printf(" fsid "); + print_int64((u_int32_t *)&fap->fa3_fsid, HEX); + printf(" fileid "); + print_int64((u_int32_t *)&fap->fa3_fileid, HEX); + printf(" a/m/ctime %u.%06u", + EXTRACT_32BITS(&fap->fa3_atime.nfsv3_sec), + EXTRACT_32BITS(&fap->fa3_atime.nfsv3_nsec)); + printf(" %u.%06u", + EXTRACT_32BITS(&fap->fa3_mtime.nfsv3_sec), + EXTRACT_32BITS(&fap->fa3_mtime.nfsv3_nsec)); + printf(" %u.%06u", + EXTRACT_32BITS(&fap->fa3_ctime.nfsv3_sec), + EXTRACT_32BITS(&fap->fa3_ctime.nfsv3_nsec)); } else { TCHECK(fap->fa2_ctime); - printf("nlink %d rdev %x fsid %x nodeid %x a/m/ctime ", - (u_int32_t) ntohl(fap->fa_nlink), - (u_int32_t) ntohl(fap->fa2_rdev), - (u_int32_t) ntohl(fap->fa2_fsid), - (u_int32_t) ntohl(fap->fa2_fileid)); - printf("%u.%06u ", - (u_int32_t) ntohl(fap->fa2_atime.nfsv2_sec), - (u_int32_t) ntohl(fap->fa2_atime.nfsv2_usec)); - printf("%u.%06u ", - (u_int32_t) ntohl(fap->fa2_mtime.nfsv2_sec), - (u_int32_t) ntohl(fap->fa2_mtime.nfsv2_usec)); - printf("%u.%06u ", - (u_int32_t) ntohl(fap->fa2_ctime.nfsv2_sec), - (u_int32_t) ntohl(fap->fa2_ctime.nfsv2_usec)); + printf(" nlink %d rdev %x fsid %x nodeid %x a/m/ctime", + EXTRACT_32BITS(&fap->fa_nlink), + EXTRACT_32BITS(&fap->fa2_rdev), + EXTRACT_32BITS(&fap->fa2_fsid), + EXTRACT_32BITS(&fap->fa2_fileid)); + printf(" %u.%06u", + EXTRACT_32BITS(&fap->fa2_atime.nfsv2_sec), + EXTRACT_32BITS(&fap->fa2_atime.nfsv2_usec)); + printf(" %u.%06u", + EXTRACT_32BITS(&fap->fa2_mtime.nfsv2_sec), + EXTRACT_32BITS(&fap->fa2_mtime.nfsv2_usec)); + printf(" %u.%06u", + EXTRACT_32BITS(&fap->fa2_ctime.nfsv2_sec), + EXTRACT_32BITS(&fap->fa2_ctime.nfsv2_usec)); } } return ((const u_int32_t *)((unsigned char *)dp + @@ -1195,15 +1231,15 @@ parsestatfs(const u_int32_t *dp, int v3) printf(" afiles "); print_int64((u_int32_t *)&sfsp->sf_afiles, UNSIGNED); printf(" invar %u", - (u_int32_t) ntohl(sfsp->sf_invarsec)); + EXTRACT_32BITS(&sfsp->sf_invarsec)); } } else { printf(" tsize %d bsize %d blocks %d bfree %d bavail %d", - (u_int32_t)ntohl(sfsp->sf_tsize), - (u_int32_t)ntohl(sfsp->sf_bsize), - (u_int32_t)ntohl(sfsp->sf_blocks), - (u_int32_t)ntohl(sfsp->sf_bfree), - (u_int32_t)ntohl(sfsp->sf_bavail)); + EXTRACT_32BITS(&sfsp->sf_tsize), + EXTRACT_32BITS(&sfsp->sf_bsize), + EXTRACT_32BITS(&sfsp->sf_blocks), + EXTRACT_32BITS(&sfsp->sf_bfree), + EXTRACT_32BITS(&sfsp->sf_bavail)); } return (1); @@ -1226,7 +1262,7 @@ parserddires(const u_int32_t *dp) TCHECK(dp[2]); printf(" offset %x size %d ", - (u_int32_t)ntohl(dp[0]), (u_int32_t)ntohl(dp[1])); + EXTRACT_32BITS(&dp[0]), EXTRACT_32BITS(&dp[1])); if (dp[2] != 0) printf(" eof"); @@ -1241,8 +1277,8 @@ parse_wcc_attr(const u_int32_t *dp) printf(" sz "); print_int64(dp, UNSIGNED); printf(" mtime %u.%06u ctime %u.%06u", - (u_int32_t)ntohl(dp[2]), (u_int32_t)ntohl(dp[3]), - (u_int32_t)ntohl(dp[4]), (u_int32_t)ntohl(dp[5])); + EXTRACT_32BITS(&dp[2]), EXTRACT_32BITS(&dp[3]), + EXTRACT_32BITS(&dp[4]), EXTRACT_32BITS(&dp[5])); return (dp + 6); } @@ -1253,7 +1289,7 @@ static const u_int32_t * parse_pre_op_attr(const u_int32_t *dp, int verbose) { TCHECK(dp[0]); - if (!ntohl(dp[0])) + if (!EXTRACT_32BITS(&dp[0])) return (dp + 1); dp++; TCHECK2(*dp, 24); @@ -1274,7 +1310,7 @@ static const u_int32_t * parse_post_op_attr(const u_int32_t *dp, int verbose) { TCHECK(dp[0]); - if (!ntohl(dp[0])) + if (!EXTRACT_32BITS(&dp[0])) return (dp + 1); dp++; if (verbose) { @@ -1309,7 +1345,7 @@ parsecreateopres(const u_int32_t *dp, int verbose) dp = parse_wcc_data(dp, verbose); else { TCHECK(dp[0]); - if (!ntohl(dp[0])) + if (!EXTRACT_32BITS(&dp[0])) return (dp + 1); dp++; if (!(dp = parsefh(dp, 1))) @@ -1318,7 +1354,7 @@ parsecreateopres(const u_int32_t *dp, int verbose) if (!(dp = parse_post_op_attr(dp, verbose))) return (0); if (vflag > 1) { - printf("dir attr:"); + printf(" dir attr:"); dp = parse_wcc_data(dp, verbose); } } @@ -1379,19 +1415,19 @@ parsefsinfo(const u_int32_t *dp) sfp = (struct nfsv3_fsinfo *)dp; TCHECK(*sfp); printf(" rtmax %u rtpref %u wtmax %u wtpref %u dtpref %u", - (u_int32_t) ntohl(sfp->fs_rtmax), - (u_int32_t) ntohl(sfp->fs_rtpref), - (u_int32_t) ntohl(sfp->fs_wtmax), - (u_int32_t) ntohl(sfp->fs_wtpref), - (u_int32_t) ntohl(sfp->fs_dtpref)); + EXTRACT_32BITS(&sfp->fs_rtmax), + EXTRACT_32BITS(&sfp->fs_rtpref), + EXTRACT_32BITS(&sfp->fs_wtmax), + EXTRACT_32BITS(&sfp->fs_wtpref), + EXTRACT_32BITS(&sfp->fs_dtpref)); if (vflag) { printf(" rtmult %u wtmult %u maxfsz ", - (u_int32_t) ntohl(sfp->fs_rtmult), - (u_int32_t) ntohl(sfp->fs_wtmult)); + EXTRACT_32BITS(&sfp->fs_rtmult), + EXTRACT_32BITS(&sfp->fs_wtmult)); print_int64((u_int32_t *)&sfp->fs_maxfilesize, UNSIGNED); printf(" delta %u.%06u ", - (u_int32_t) ntohl(sfp->fs_timedelta.nfsv3_sec), - (u_int32_t) ntohl(sfp->fs_timedelta.nfsv3_nsec)); + EXTRACT_32BITS(&sfp->fs_timedelta.nfsv3_sec), + EXTRACT_32BITS(&sfp->fs_timedelta.nfsv3_nsec)); } return (1); trunc: @@ -1417,12 +1453,12 @@ parsepathconf(const u_int32_t *dp) TCHECK(*spp); printf(" linkmax %u namemax %u %s %s %s %s", - (u_int32_t) ntohl(spp->pc_linkmax), - (u_int32_t) ntohl(spp->pc_namemax), - ntohl(spp->pc_notrunc) ? "notrunc" : "", - ntohl(spp->pc_chownrestricted) ? "chownres" : "", - ntohl(spp->pc_caseinsensitive) ? "igncase" : "", - ntohl(spp->pc_casepreserving) ? "keepcase" : ""); + EXTRACT_32BITS(&spp->pc_linkmax), + EXTRACT_32BITS(&spp->pc_namemax), + EXTRACT_32BITS(&spp->pc_notrunc) ? "notrunc" : "", + EXTRACT_32BITS(&spp->pc_chownrestricted) ? "chownres" : "", + EXTRACT_32BITS(&spp->pc_caseinsensitive) ? "igncase" : "", + EXTRACT_32BITS(&spp->pc_casepreserving) ? "keepcase" : ""); return (1); trunc: return (0); @@ -1510,7 +1546,7 @@ interp_reply(const struct rpc_msg *rp, u_int32_t proc, u_int32_t vers, int lengt if (!(dp = parse_post_op_attr(dp, vflag))) break; if (!er) - printf(" c %04x", (u_int32_t)ntohl(dp[0])); + printf(" c %04x", EXTRACT_32BITS(&dp[0])); return; case NFSPROC_READLINK: @@ -1533,8 +1569,8 @@ interp_reply(const struct rpc_msg *rp, u_int32_t proc, u_int32_t vers, int lengt return; if (vflag) { TCHECK(dp[1]); - printf("%u bytes", (u_int32_t) ntohl(dp[0])); - if (ntohl(dp[1])) + printf(" %u bytes", EXTRACT_32BITS(&dp[0])); + if (EXTRACT_32BITS(&dp[1])) printf(" EOF"); } return; @@ -1557,12 +1593,12 @@ interp_reply(const struct rpc_msg *rp, u_int32_t proc, u_int32_t vers, int lengt return; if (vflag) { TCHECK(dp[0]); - printf("%u bytes", (u_int32_t) ntohl(dp[0])); + printf(" %u bytes", EXTRACT_32BITS(&dp[0])); if (vflag > 1) { TCHECK(dp[1]); printf(" <%s>", tok2str(nfsv3_writemodes, - NULL, ntohl(dp[1]))); + NULL, EXTRACT_32BITS(&dp[1]))); } return; } diff --git a/contrib/tcpdump/print-ntp.c b/contrib/tcpdump/print-ntp.c index 0c84050738b5..a97719f14ea5 100644 --- a/contrib/tcpdump/print-ntp.c +++ b/contrib/tcpdump/print-ntp.c @@ -26,26 +26,25 @@ */ #ifndef lint -static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/print-ntp.c,v 1.32.4.1 2002/07/10 07:13:37 guy Exp $ (LBL)"; +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-ntp.c,v 1.37.2.2 2003/11/16 08:51:36 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include <sys/param.h> -#include <sys/time.h> -#include <sys/socket.h> +#include <tcpdump-stdinc.h> -#include <netinet/in.h> - -#include <ctype.h> #include <stdio.h> #include <string.h> +#ifdef HAVE_STRFTIME +#include <time.h> +#endif #include "interface.h" #include "addrtoname.h" +#include "extract.h" #ifdef MODEMASK #undef MODEMASK /* Solaris sucks */ #endif @@ -72,7 +71,7 @@ ntp_print(register const u_char *cp, u_int length) TCHECK(bp->status); version = (int)(bp->status & VERSIONMASK) >> 3; - printf(" v%d", version); + printf("NTPv%d", version); leapind = bp->status & LEAPMASK; switch (leapind) { @@ -127,14 +126,14 @@ ntp_print(register const u_char *cp, u_int length) } TCHECK(bp->stratum); - printf(" strat %d", bp->stratum); + printf(", strat %d", bp->stratum); TCHECK(bp->ppoll); - printf(" poll %d", bp->ppoll); + printf(", poll %d", bp->ppoll); /* Can't TCHECK bp->precision bitfield so bp->distance + 0 instead */ TCHECK2(bp->distance, 0); - printf(" prec %d", bp->precision); + printf(", prec %d", bp->precision); if (!vflag) return; @@ -144,11 +143,11 @@ ntp_print(register const u_char *cp, u_int length) p_sfix(&bp->distance); TCHECK(bp->dispersion); - fputs(" disp ", stdout); + fputs(", disp ", stdout); p_sfix(&bp->dispersion); TCHECK(bp->refid); - fputs(" ref ", stdout); + fputs(", ref ", stdout); /* Interpretation depends on stratum */ switch (bp->stratum) { @@ -204,8 +203,8 @@ p_sfix(register const struct s_fixedpt *sfp) register int f; register float ff; - i = ntohs(sfp->int_part); - f = ntohs(sfp->fraction); + i = EXTRACT_16BITS(&sfp->int_part); + f = EXTRACT_16BITS(&sfp->fraction); ff = f / 65536.0; /* shift radix point by 16 bits */ f = ff * 1000000.0; /* Treat fraction as parts per million */ printf("%d.%06d", i, f); @@ -221,14 +220,29 @@ p_ntp_time(register const struct l_fixedpt *lfp) register u_int32_t f; register float ff; - i = ntohl(lfp->int_part); - uf = ntohl(lfp->fraction); + i = EXTRACT_32BITS(&lfp->int_part); + uf = EXTRACT_32BITS(&lfp->fraction); ff = uf; if (ff < 0.0) /* some compilers are buggy */ ff += FMAXINT; ff = ff / FMAXINT; /* shift radix point by 32 bits */ f = ff * 1000000000.0; /* treat fraction as parts per billion */ printf("%u.%09d", i, f); + +#ifdef HAVE_STRFTIME + /* + * For extra verbosity, print the time in human-readable format. + */ + if (vflag > 1 && i) { + time_t seconds = i - JAN_1970; + struct tm *tm; + char time_buf[128]; + + tm = localtime(&seconds); + strftime(time_buf, sizeof (time_buf), "%Y/%m/%d %H:%M:%S", tm); + printf (" (%s)", time_buf); + } +#endif } /* Prints time difference between *lfp and *olfp */ @@ -237,16 +251,22 @@ p_ntp_delta(register const struct l_fixedpt *olfp, register const struct l_fixedpt *lfp) { register int32_t i; - register u_int32_t uf; - register u_int32_t ouf; + register u_int32_t u, uf; + register u_int32_t ou, ouf; register u_int32_t f; register float ff; int signbit; - i = ntohl(lfp->int_part) - ntohl(olfp->int_part); + u = EXTRACT_32BITS(&lfp->int_part); + ou = EXTRACT_32BITS(&olfp->int_part); + uf = EXTRACT_32BITS(&lfp->fraction); + ouf = EXTRACT_32BITS(&olfp->fraction); + if (ou == 0 && ouf == 0) { + p_ntp_time(lfp); + return; + } - uf = ntohl(lfp->fraction); - ouf = ntohl(olfp->fraction); + i = u - ou; if (i > 0) { /* new is definitely greater than old */ signbit = 0; @@ -280,3 +300,4 @@ p_ntp_delta(register const struct l_fixedpt *olfp, putchar('+'); printf("%d.%09d", i, f); } + diff --git a/contrib/tcpdump/print-null.c b/contrib/tcpdump/print-null.c index f8aa37bd3a31..a9f08bac0cc5 100644 --- a/contrib/tcpdump/print-null.c +++ b/contrib/tcpdump/print-null.c @@ -22,19 +22,15 @@ */ #ifndef lint -static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/print-null.c,v 1.41.4.1 2002/06/01 23:51:15 guy Exp $ (LBL)"; +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-null.c,v 1.49.2.2 2003/11/16 08:51:36 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include <sys/param.h> -#include <sys/time.h> -#include <sys/socket.h> - -#include <netinet/in.h> +#include <tcpdump-stdinc.h> #include <pcap.h> #include <stdio.h> @@ -48,10 +44,6 @@ static const char rcsid[] = #include "ip6.h" #endif -#ifndef AF_NS -#define AF_NS 6 /* XEROX NS protocols */ -#endif - /* * The DLT_NULL packet header is 4 bytes long. It contains a host-byte-order * 32-bit integer that specifies the family, e.g. AF_INET. @@ -64,6 +56,22 @@ static const char rcsid[] = */ #define NULL_HDRLEN 4 +/* + * BSD AF_ values. + * + * Unfortunately, the BSDs don't all use the same value for AF_INET6, + * so, because we want to be able to read captures from all of the BSDs, + * we check for all of them. + */ +#define BSD_AF_INET 2 +#define BSD_AF_NS 6 /* XEROX NS protocols */ +#define BSD_AF_ISO 7 +#define BSD_AF_APPLETALK 16 +#define BSD_AF_IPX 23 +#define BSD_AF_INET6_BSD 24 /* OpenBSD (and probably NetBSD), BSD/OS */ +#define BSD_AF_INET6_FREEBSD 28 +#define BSD_AF_INET6_DARWIN 30 + static void null_print(u_int family, u_int length) { @@ -72,20 +80,34 @@ null_print(u_int family, u_int length) else { switch (family) { - case AF_INET: + case BSD_AF_INET: printf("ip "); break; #ifdef INET6 - case AF_INET6: + case BSD_AF_INET6_BSD: + case BSD_AF_INET6_FREEBSD: + case BSD_AF_INET6_DARWIN: printf("ip6 "); break; #endif - case AF_NS: + case BSD_AF_NS: printf("ns "); break; + case BSD_AF_ISO: + printf("osi "); + break; + + case BSD_AF_APPLETALK: + printf("atalk "); + break; + + case BSD_AF_IPX: + printf("ipx "); + break; + default: printf("AF %u ", family); break; @@ -102,16 +124,23 @@ null_print(u_int family, u_int length) #define SWAPLONG(y) \ ((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff)) -void -null_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) +/* + * This is the top level routine of the printer. 'p' points + * to the ether header of the packet, 'h->ts' is the timestamp, + * 'h->length' is the length of the packet off the wire, and 'h->caplen' + * is the number of bytes actually captured. + */ +u_int +null_if_print(const struct pcap_pkthdr *h, const u_char *p) { u_int length = h->len; u_int caplen = h->caplen; - const struct ip *ip; u_int family; - ++infodelay; - ts_print(&h->ts); + if (caplen < NULL_HDRLEN) { + printf("[|null]"); + return (NULL_HDRLEN); + } memcpy((char *)&family, (char *)p, sizeof(family)); @@ -126,40 +155,47 @@ null_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) if ((family & 0xFFFF0000) != 0) family = SWAPLONG(family); - /* - * Some printers want to get back at the link level addresses, - * and/or check that they're not walking off the end of the packet. - * Rather than pass them all the way down, we set these globals. - */ - packetp = p; - snapend = p + caplen; - length -= NULL_HDRLEN; - - ip = (struct ip *)(p + NULL_HDRLEN); + caplen -= NULL_HDRLEN; + p += NULL_HDRLEN; if (eflag) null_print(family, length); - switch (IP_V(ip)) { - case 4: - ip_print((const u_char *)ip, length); + switch (family) { + + case BSD_AF_INET: + ip_print(p, length); break; + #ifdef INET6 - case 6: - ip6_print((const u_char *)ip, length); + case BSD_AF_INET6_BSD: + case BSD_AF_INET6_FREEBSD: + case BSD_AF_INET6_DARWIN: + ip6_print(p, length); break; -#endif /* INET6 */ - default: - printf("ip v%d", IP_V(ip)); +#endif + + case BSD_AF_ISO: + isoclns_print(p, length, caplen); + break; + + case BSD_AF_APPLETALK: + atalk_print(p, length); break; + + case BSD_AF_IPX: + ipx_print(p, length); + break; + + default: + /* unknown AF_ value */ + if (!eflag) + null_print(family, length + NULL_HDRLEN); + if (!xflag && !qflag) + default_print(p, caplen); } - if (xflag) - default_print((const u_char *)ip, caplen - NULL_HDRLEN); - putchar('\n'); - --infodelay; - if (infoprint) - info(0); + return (NULL_HDRLEN); } diff --git a/contrib/tcpdump/print-pim.c b/contrib/tcpdump/print-pim.c index d624249de57f..4aa4983899b9 100644 --- a/contrib/tcpdump/print-pim.c +++ b/contrib/tcpdump/print-pim.c @@ -22,19 +22,15 @@ */ #ifndef lint -static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/print-pim.c,v 1.29.4.1 2002/05/07 18:30:19 fenner Exp $ (LBL)"; +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-pim.c,v 1.37.2.4 2004/03/24 02:52:37 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include <sys/param.h> -#include <sys/time.h> -#include <sys/socket.h> - -#include <netinet/in.h> +#include <tcpdump-stdinc.h> /* * XXX: We consider a case where IPv6 is not ready yet for portability, @@ -58,7 +54,6 @@ struct pim { #include <stdio.h> #include <stdlib.h> -#include <unistd.h> #include "interface.h" #include "addrtoname.h" @@ -120,6 +115,7 @@ pimv1_join_prune_print(register const u_char *bp, register u_int len) while (ngroups--) { TCHECK2(bp[0], 4); (void)printf("\n\tGroup: %s", ipaddr_string(bp)); + TCHECK2(bp[4], 4); if (EXTRACT_32BITS(&bp[4]) != 0xffffffff) (void)printf("/%s", ipaddr_string(&bp[4])); TCHECK2(bp[8], 4); @@ -129,7 +125,7 @@ pimv1_join_prune_print(register const u_char *bp, register u_int len) bp += 12; len -= 12; for (njp = 0; njp < (njoin + nprune); njp++) { - char *type; + const char *type; if (njp < njoin) type = "Join "; @@ -161,6 +157,7 @@ pimv1_print(register const u_char *bp, register u_int len) if (bp >= ep) return; + TCHECK(bp[1]); type = bp[1]; switch (type) { @@ -449,7 +446,7 @@ static int pimv2_addr_print(const u_char *bp, enum pimv2_addrtype at, int silent) { int af; - char *afstr; + const char *afstr; int len, hdrlen; TCHECK(bp[0]); @@ -586,9 +583,25 @@ pimv2_print(register const u_char *bp, register u_int len) (void)printf(")"); break; + case 2: /* LAN Prune Delay */ + (void)printf(" (LAN-Prune-Delay: "); + if (olen != 4) { + (void)printf("!olen=%d!)", olen); + } else { + char t_bit; + u_int16_t lan_delay, override_interval; + lan_delay = EXTRACT_16BITS(&bp[4]); + override_interval = EXTRACT_16BITS(&bp[6]); + t_bit = (lan_delay & 0x8000)? 1 : 0; + lan_delay &= ~0x8000; + (void)printf("T-bit=%d lan-delay=%dms override-interval=%dms)", + t_bit, lan_delay, override_interval); + } + break; + case 18: /* Old DR-Priority */ if (olen == 4) - (void)printf(" (OLD-DR-Priority: %d)", + (void)printf(" (OLD-DR-Priority: %d)", EXTRACT_32BITS(&bp[4])); else goto unknown; @@ -628,6 +641,26 @@ pimv2_print(register const u_char *bp, register u_int len) (void)printf(" (bidir-capable)"); break; + case 24: /* Address List */ + case 65001: /* Address List (old implementations) */ + (void)printf(" (%saddr-list", + otype == 65001 ? "old" : ""); + if (vflag > 1) { + const u_char *ptr = &bp[4]; + while (ptr < &bp[4 + olen]) { + int advance; + + printf(" "); + advance = pimv2_addr_print(ptr, pimv2_unicast, 0); + if (advance < 0) { + printf("..."); + break; + } + ptr += advance; + } + } + (void)printf(")"); + break; default: unknown: if (vflag) diff --git a/contrib/tcpdump/print-ppp.c b/contrib/tcpdump/print-ppp.c index 3416ed664da2..01febb85b6cb 100644 --- a/contrib/tcpdump/print-ppp.c +++ b/contrib/tcpdump/print-ppp.c @@ -32,26 +32,21 @@ */ #ifndef lint -static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/print-ppp.c,v 1.64 2001/09/09 02:04:19 guy Exp $ (LBL)"; +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-ppp.c,v 1.89.2.3 2004/03/24 03:32:43 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include <sys/param.h> -#include <sys/time.h> +#include <tcpdump-stdinc.h> #ifdef __bsdi__ #include <net/slcompress.h> #include <net/if_ppp.h> #endif -#include <netinet/in.h> - -#include <ctype.h> -#include <netdb.h> #include <pcap.h> #include <stdio.h> @@ -68,7 +63,47 @@ static const char rcsid[] = * for the up-to-date information. */ -/* Control Protocols (LCP/IPCP/CCP etc.) Codes */ +/* Protocol Codes defined in ppp.h */ + +struct tok ppptype2str[] = { + { PPP_IP, "IP" }, + { PPP_OSI, "OSI" }, + { PPP_NS, "NS" }, + { PPP_DECNET, "DECNET" }, + { PPP_APPLE, "APPLE" }, + { PPP_IPX, "IPX" }, + { PPP_VJC, "VJC" }, + { PPP_VJNC, "VJNC" }, + { PPP_BRPDU, "BRPDU" }, + { PPP_STII, "STII" }, + { PPP_VINES, "VINES" }, + { PPP_MPLS_UCAST, "MPLS" }, + { PPP_MPLS_MCAST, "MPLS" }, + + { PPP_HELLO, "HELLO" }, + { PPP_LUXCOM, "LUXCOM" }, + { PPP_SNS, "SNS" }, + { PPP_IPCP, "IPCP" }, + { PPP_OSICP, "OSICP" }, + { PPP_NSCP, "NSCP" }, + { PPP_DECNETCP, "DECNETCP" }, + { PPP_APPLECP, "APPLECP" }, + { PPP_IPXCP, "IPXCP" }, + { PPP_STIICP, "STIICP" }, + { PPP_VINESCP, "VINESCP" }, + { PPP_MPLSCP, "MPLSCP" }, + + { PPP_LCP, "LCP" }, + { PPP_PAP, "PAP" }, + { PPP_LQM, "LQM" }, + { PPP_CHAP, "CHAP" }, + { PPP_BACP, "BACP" }, + { PPP_BAP, "BAP" }, + { PPP_MP, "ML" }, + { 0, NULL } +}; + +/* Control Protocols (LCP/IPCP/CCP etc.) Codes defined in RFC 1661 */ #define CPCODES_VEXT 0 /* Vendor-Specific (RFC2153) */ #define CPCODES_CONF_REQ 1 /* Configure-Request */ @@ -82,34 +117,29 @@ static const char rcsid[] = #define CPCODES_ECHO_REQ 9 /* Echo-Request (LCP only) */ #define CPCODES_ECHO_RPL 10 /* Echo-Reply (LCP only) */ #define CPCODES_DISC_REQ 11 /* Discard-Request (LCP only) */ -#define CPCODES_ID 12 /* Identification (LCP only) */ -#define CPCODES_TIME_REM 13 /* Time-Remaining (LCP only) */ -#define CPCODES_RESET_REQ 14 /* Reset-Request (CCP only) */ +#define CPCODES_ID 12 /* Identification (LCP only) RFC1570 */ +#define CPCODES_TIME_REM 13 /* Time-Remaining (LCP only) RFC1570 */ +#define CPCODES_RESET_REQ 14 /* Reset-Request (CCP only) RFC1962 */ #define CPCODES_RESET_REP 15 /* Reset-Reply (CCP only) */ -#define CPCODES_MIN CPCODES_VEXT -#define CPCODES_MAX CPCODES_RESET_REP - -static const char *cpcodes[] = { - /* - * Control Protocol code values (RFC1661) - */ - "Vend-Ext", /* (0) RFC2153 */ - "Conf-Req", /* (1) */ - "Conf-Ack", /* (2) */ - "Conf-Nak", /* (3) */ - "Conf-Rej", /* (4) */ - "Term-Req", /* (5) */ - "Term-Ack", /* (6) */ - "Code-Rej", /* (7) */ - "Prot-Rej", /* (8) */ - "Echo-Req", /* (9) */ - "Echo-Rep", /* (10) */ - "Disc-Req", /* (11) */ - "Ident", /* (12) RFC1570 */ - "Time-Rem", /* (13) RFC1570 */ - "Reset-Req", /* (14) RFC1962 */ - "Reset-Ack", /* (15) RFC1962 */ +struct tok cpcodes[] = { + {CPCODES_VEXT, "Vendor-Extension"}, /* RFC2153 */ + {CPCODES_CONF_REQ, "Conf-Request"}, + {CPCODES_CONF_ACK, "Conf-Ack"}, + {CPCODES_CONF_NAK, "Conf-Nack"}, + {CPCODES_CONF_REJ, "Conf-Reject"}, + {CPCODES_TERM_REQ, "Term-Request"}, + {CPCODES_TERM_ACK, "Term-Ack"}, + {CPCODES_CODE_REJ, "Code-Reject"}, + {CPCODES_PROT_REJ, "Prot-Reject"}, + {CPCODES_ECHO_REQ, "Echo-Request"}, + {CPCODES_ECHO_RPL, "Echo-Reply"}, + {CPCODES_DISC_REQ, "Disc-Req"}, + {CPCODES_ID, "Ident"}, /* RFC1570 */ + {CPCODES_TIME_REM, "Time-Rem"}, /* RFC1570 */ + {CPCODES_RESET_REQ, "Reset-Req"}, /* RFC1962 */ + {CPCODES_RESET_REP, "Reset-Ack"}, /* RFC1962 */ + {0, NULL} }; /* LCP Config Options */ @@ -263,6 +293,7 @@ static const char *ccpconfopts[] = { /* BVCP - to be supported */ /* BCP - to be supported */ /* IPXCP - to be supported */ +/* MPLSCP - to be supported */ /* Auth Algorithms */ @@ -331,7 +362,6 @@ static const char *papcode[] = { #define BAP_CSIND 7 #define BAP_CSRES 8 -static const char *ppp_protoname (u_int proto); static void handle_ctrl_proto (u_int proto,const u_char *p, int length); static void handle_chap (const u_char *p, int length); static void handle_pap (const u_char *p, int length); @@ -342,71 +372,35 @@ static int print_ccp_config_options (const u_char *p, int); static int print_bacp_config_options (const u_char *p, int); static void handle_ppp (u_int proto, const u_char *p, int length); -static const char * -ppp_protoname(u_int proto) -{ - static char buf[20]; - - switch (proto) { - case PPP_IP: return "IP"; - case PPP_IPV6: return "IPv6"; -#ifdef PPP_XNS - case PPP_XNS: return "XNS"; -#endif - case PPP_IPX: return "IPX"; - case PPP_OSI: return "OSI"; - case PPP_VJC: return "VJC"; - case PPP_VJNC: return "VJNC"; - case PPP_COMP: return "COMP"; - case PPP_IPCP: return "IPCP"; - case PPP_IPV6CP: return "IPv6CP"; - case PPP_IPXCP: return "IPXCP"; - case PPP_OSICP: return "OSICP"; - case PPP_CCP: return "CCP"; - case PPP_LCP: return "LCP"; - case PPP_PAP: return "PAP"; -#ifdef PPP_LQR - case PPP_LQR: return "LQR"; -#endif - case PPP_CHAP: return "CHAP"; - case PPP_BACP: return "BACP"; - case PPP_BAP: return "BAP"; - default: - snprintf(buf, sizeof(buf), "unknown-0x%04x", proto); - return buf; - } -} - /* generic Control Protocol (e.g. LCP, IPCP, CCP, etc.) handler */ static void -handle_ctrl_proto(u_int proto, const u_char *p, int length) +handle_ctrl_proto(u_int proto, const u_char *pptr, int length) { + const char *typestr; u_int code, len; int (*pfunc)(const u_char *, int); int x, j; + const u_char *tptr; - if (length < 1) { - printf("[|%s]", ppp_protoname(proto)); - return; - } else if (length < 4) { - printf("[|%s 0x%02x]", ppp_protoname(proto), *p); - return; - } + tptr=pptr; - code = *p; - if ((code >= CPCODES_MIN) && (code <= CPCODES_MAX)) - printf("%s", cpcodes[code]); - else { - printf("0x%02x", code); - return; - } - p++; + typestr = tok2str(ppptype2str, "unknown", proto); + printf("%s, ",typestr); - printf("(%u)", *p); /* ID */ - p++; + if (length < 4) /* FIXME weak boundary checking */ + goto trunc; + TCHECK2(*tptr, 2); - len = EXTRACT_16BITS(p); - p += 2; + code = *tptr++; + + printf("%s (0x%02x), id %u", + tok2str(cpcodes, "Unknown Opcode",code), + code, + *tptr++); /* ID */ + + TCHECK2(*tptr, 2); + len = EXTRACT_16BITS(tptr); + tptr += 2; if (length <= 4) return; /* there may be a NULL confreq etc. */ @@ -415,9 +409,11 @@ handle_ctrl_proto(u_int proto, const u_char *p, int length) case CPCODES_VEXT: if (length < 11) break; - printf(", Magic-Num=%08x", EXTRACT_32BITS(p)); - p += 4; - printf(" OUI=%02x%02x%02x", p[0], p[1], p[2]); + TCHECK2(*tptr, 4); + printf(", Magic-Num 0x%08x", EXTRACT_32BITS(tptr)); + tptr += 4; + TCHECK2(*tptr, 3); + printf(" OUI 0x%06x", EXTRACT_24BITS(tptr)); /* XXX: need to decode Kind and Value(s)? */ break; case CPCODES_CONF_REQ: @@ -448,10 +444,10 @@ handle_ctrl_proto(u_int proto, const u_char *p, int length) pfunc = NULL; break; } - if ((j = (*pfunc)(p, len)) == 0) + if ((j = (*pfunc)(tptr, len)) == 0) break; x -= j; - p += j; + tptr += j; } while (x > 0); break; @@ -465,7 +461,10 @@ handle_ctrl_proto(u_int proto, const u_char *p, int length) case CPCODES_PROT_REJ: if (length < 6) break; - printf(", Rejected-Protocol=%04x", EXTRACT_16BITS(p)); + TCHECK2(*tptr, 2); + printf(", Rejected %s Protocol (0x%04x)", + tok2str(ppptype2str,"unknown", EXTRACT_16BITS(tptr)), + EXTRACT_16BITS(tptr)); /* XXX: need to decode Rejected-Information? */ break; case CPCODES_ECHO_REQ: @@ -474,20 +473,35 @@ handle_ctrl_proto(u_int proto, const u_char *p, int length) case CPCODES_ID: if (length < 8) break; - printf(", Magic-Num=%08x", EXTRACT_32BITS(p)); + TCHECK2(*tptr, 4); + printf(", Magic-Num 0x%08x", EXTRACT_32BITS(tptr)); /* XXX: need to decode Data? */ break; case CPCODES_TIME_REM: if (length < 12) break; - printf(", Magic-Num=%08x", EXTRACT_32BITS(p)); - printf(" Seconds-Remaining=%u", EXTRACT_32BITS(p + 4)); + TCHECK2(*tptr, 4); + printf(", Magic-Num 0x%08x", EXTRACT_32BITS(tptr)); + TCHECK2(*(tptr + 4), 4); + printf(", Seconds-Remaining %us", EXTRACT_32BITS(tptr + 4)); /* XXX: need to decode Message? */ break; default: - printf(", unknown-Codes-0x%02x", code); + /* XXX this is dirty but we do not get the + * original pointer passed to the begin + * the PPP packet */ + if (vflag <= 1) + print_unknown_data(pptr-2,"\n\t",length+2); break; } + printf(", length %u", length); + + if (vflag >1) + print_unknown_data(pptr-2,"\n\t",length+2); + return; + +trunc: + printf("[|%s]", typestr); } /* LCP config options */ @@ -498,92 +512,114 @@ print_lcp_config_options(const u_char *p, int length) if (length < 2) return 0; + TCHECK2(*p, 2); len = p[1]; opt = p[0]; if (length < len) return 0; if ((opt >= LCPOPT_MIN) && (opt <= LCPOPT_MAX)) - printf(", %s", lcpconfopts[opt]); + printf(", %s ", lcpconfopts[opt]); else { - printf(", unknwhown-%d", opt); + printf(", unknown LCP option 0x%02x", opt); return len; } switch (opt) { case LCPOPT_VEXT: if (len >= 6) { - printf(" OUI=%02x%02x%02x", p[2], p[3], p[4]); + TCHECK2(*(p + 2), 3); + printf(" OUI 0x%06x", EXTRACT_24BITS(p+2)); #if 0 - printf(" kind=%02x", p[5]); - printf(" val=") + TCHECK(p[5]); + printf(" kind 0x%02x", p[5]); + printf(" val 0x") for (i = 0; i < len - 6; i++) { + TCHECK(p[6 + i]); printf("%02x", p[6 + i]); } #endif } break; case LCPOPT_MRU: - if (len == 4) - printf("=%u", EXTRACT_16BITS(p + 2)); + if (len == 4) { + TCHECK2(*(p + 2), 2); + printf(" %u", EXTRACT_16BITS(p + 2)); + } break; case LCPOPT_ACCM: - if (len == 6) - printf("=%08x", EXTRACT_32BITS(p + 2)); + if (len == 6) { + TCHECK2(*(p + 2), 4); + printf(" %08x", EXTRACT_32BITS(p + 2)); + } break; case LCPOPT_AP: if (len >= 4) { - if (p[2] == 0xc0 && p[3] == 0x23) - printf(" PAP"); - else if (p[2] == 0xc2 && p[3] == 0x23) { - printf(" CHAP/"); - switch (p[4]) { - default: - printf("unknown-algorithm-%u", p[4]); - break; - case AUTHALG_CHAPMD5: - printf("MD5"); - break; - case AUTHALG_MSCHAP1: - printf("MSCHAPv1"); - break; - case AUTHALG_MSCHAP2: - printf("MSCHAPv2"); - break; - } + TCHECK2(*(p + 2), 2); + switch (EXTRACT_16BITS(p+2)) { + case PPP_PAP: + printf(" PAP"); + break; + case PPP_CHAP: + printf(" CHAP"); + TCHECK(p[4]); + switch (p[4]) { + default: + printf(", unknown-algorithm-%u", p[4]); + break; + case AUTHALG_CHAPMD5: + printf(", MD5"); + break; + case AUTHALG_MSCHAP1: + printf(", MSCHAPv1"); + break; + case AUTHALG_MSCHAP2: + printf(", MSCHAPv2"); + break; } - else if (p[2] == 0xc2 && p[3] == 0x27) - printf(" EAP"); - else if (p[2] == 0xc0 && p[3] == 0x27) - printf(" SPAP"); - else if (p[2] == 0xc1 && p[3] == 0x23) - printf(" Old-SPAP"); - else - printf("unknown"); + break; + case PPP_EAP: + printf(" EAP"); + break; + case PPP_SPAP: + printf(" SPAP"); + break; + case PPP_SPAP_OLD: + printf(" Old-SPAP"); + break; + default: + printf("unknown"); + } } break; case LCPOPT_QP: if (len >= 4) { - if (p[2] == 0xc0 && p[3] == 0x25) + TCHECK2(*(p + 2), 2); + if (EXTRACT_16BITS(p+2) == PPP_LQM) printf(" LQR"); else printf(" unknown"); } break; case LCPOPT_MN: - if (len == 6) - printf("=%08x", EXTRACT_32BITS(p + 2)); + if (len == 6) { + TCHECK2(*(p + 2), 4); + printf(" 0x%08x", EXTRACT_32BITS(p + 2)); + } break; case LCPOPT_PFC: break; case LCPOPT_ACFC: break; case LCPOPT_LD: - if (len == 4) - printf("=%04x", EXTRACT_16BITS(p + 2)); + if (len == 4) { + TCHECK2(*(p + 2), 2); + printf(" 0x%04x", EXTRACT_16BITS(p + 2)); + } break; case LCPOPT_CBACK: if (len < 3) break; + TCHECK(p[2]); switch (p[2]) { /* Operation */ case CALLBACK_AUTH: printf(" UserAuth"); @@ -609,12 +645,15 @@ print_lcp_config_options(const u_char *p, int length) } break; case LCPOPT_MLMRRU: - if (len == 4) - printf("=%u", EXTRACT_16BITS(p + 2)); + if (len == 4) { + TCHECK2(*(p + 2), 2); + printf(" %u", EXTRACT_16BITS(p + 2)); + } break; case LCPOPT_MLED: if (len < 3) break; + TCHECK(p[2]); switch (p[2]) { /* class */ case MEDCLASS_NULL: printf(" Null"); @@ -625,12 +664,14 @@ print_lcp_config_options(const u_char *p, int length) case MEDCLASS_IPV4: if (len != 7) break; - printf(" IPv4=%s", ipaddr_string(p + 3)); + TCHECK2(*(p + 3), 4); + printf(" IPv4 %s", ipaddr_string(p + 3)); break; case MEDCLASS_MAC: if (len != 9) break; - printf(" MAC=%02x:%02x:%02x:%02x:%02x:%02x", + TCHECK(p[8]); + printf(" MAC %02x:%02x:%02x:%02x:%02x:%02x", p[3], p[4], p[5], p[6], p[7], p[8]); break; case MEDCLASS_MNB: @@ -667,6 +708,10 @@ print_lcp_config_options(const u_char *p, int length) #endif } return len; + +trunc: + printf("[|lcp]"); + return 0; } /* CHAP */ @@ -683,10 +728,12 @@ handle_chap(const u_char *p, int length) printf("[|chap]"); return; } else if (length < 4) { + TCHECK(*p); printf("[|chap 0x%02x]", *p); return; } + TCHECK(*p); code = *p; if ((code >= CHAP_CODEMIN) && (code <= CHAP_CODEMAX)) printf("%s", chapcode[code - 1]); @@ -696,9 +743,11 @@ handle_chap(const u_char *p, int length) } p++; + TCHECK(*p); printf("(%u)", *p); /* ID */ p++; + TCHECK2(*p, 2); len = EXTRACT_16BITS(p); p += 2; @@ -714,26 +763,37 @@ handle_chap(const u_char *p, int length) case CHAP_RESP: if (length - (p - p0) < 1) return; + TCHECK(*p); val_size = *p; /* value size */ p++; if (length - (p - p0) < val_size) return; - printf(", Value="); - for (i = 0; i < val_size; i++) + printf(", Value "); + for (i = 0; i < val_size; i++) { + TCHECK(*p); printf("%02x", *p++); + } name_size = len - (p - p0); - printf(", Name="); - for (i = 0; i < name_size; i++) + printf(", Name "); + for (i = 0; i < name_size; i++) { + TCHECK(*p); safeputchar(*p++); + } break; case CHAP_SUCC: case CHAP_FAIL: msg_size = len - (p - p0); - printf(", Msg="); - for (i = 0; i< msg_size; i++) + printf(", Msg "); + for (i = 0; i< msg_size; i++) { + TCHECK(*p); safeputchar(*p++); + } break; } + return; + +trunc: + printf("[|chap]"); } /* PAP (see RFC 1334) */ @@ -750,10 +810,12 @@ handle_pap(const u_char *p, int length) printf("[|pap]"); return; } else if (length < 4) { + TCHECK(*p); printf("[|pap 0x%02x]", *p); return; } + TCHECK(*p); code = *p; if ((code >= PAP_CODEMIN) && (code <= PAP_CODEMAX)) printf("%s", papcode[code - 1]); @@ -763,9 +825,11 @@ handle_pap(const u_char *p, int length) } p++; + TCHECK(*p); printf("(%u)", *p); /* ID */ p++; + TCHECK2(*p, 2); len = EXTRACT_16BITS(p); p += 2; @@ -773,43 +837,55 @@ handle_pap(const u_char *p, int length) case PAP_AREQ: if (length - (p - p0) < 1) return; + TCHECK(*p); peerid_len = *p; /* Peer-ID Length */ p++; if (length - (p - p0) < peerid_len) return; - printf(", Peer="); - for (i = 0; i < peerid_len; i++) + printf(", Peer "); + for (i = 0; i < peerid_len; i++) { + TCHECK(*p); safeputchar(*p++); + } if (length - (p - p0) < 1) return; + TCHECK(*p); passwd_len = *p; /* Password Length */ p++; if (length - (p - p0) < passwd_len) return; - printf(", Name="); - for (i = 0; i < passwd_len; i++) + printf(", Name "); + for (i = 0; i < passwd_len; i++) { + TCHECK(*p); safeputchar(*p++); + } break; case PAP_AACK: case PAP_ANAK: if (length - (p - p0) < 1) return; + TCHECK(*p); msg_len = *p; /* Msg-Length */ p++; if (length - (p - p0) < msg_len) return; - printf(", Msg="); - for (i = 0; i< msg_len; i++) + printf(", Msg "); + for (i = 0; i< msg_len; i++) { + TCHECK(*p); safeputchar(*p++); + } break; } return; + +trunc: + printf("[|pap]"); } /* BAP */ static void -handle_bap(const u_char *p, int length) +handle_bap(const u_char *p _U_, int length _U_) { /* XXX: to be supported!! */ } @@ -823,6 +899,7 @@ print_ipcp_config_options(const u_char *p, int length) if (length < 2) return 0; + TCHECK2(*p, 2); len = p[1]; opt = p[0]; if (length < len) @@ -831,7 +908,8 @@ print_ipcp_config_options(const u_char *p, int length) case IPCPOPT_2ADDR: /* deprecated */ if (len != 10) goto invlen; - printf(", IP-Addrs src=%s dst=%s", + TCHECK2(*(p + 6), 4); + printf(", IP-Addrs src %s, dst %s", ipaddr_string(p + 2), ipaddr_string(p + 6)); break; @@ -839,6 +917,7 @@ print_ipcp_config_options(const u_char *p, int length) if (len < 4) goto invlen; printf(", IP-Comp"); + TCHECK2(*(p + 2), 2); if (EXTRACT_16BITS(p + 2) == PPP_VJC) { printf(" VJ-Comp"); /* XXX: VJ-Comp parameters should be decoded */ @@ -848,32 +927,38 @@ print_ipcp_config_options(const u_char *p, int length) case IPCPOPT_ADDR: if (len != 6) goto invlen; - printf(", IP-Addr=%s", ipaddr_string(p + 2)); + TCHECK2(*(p + 2), 4); + printf(", IP-Addr %s", ipaddr_string(p + 2)); break; case IPCPOPT_MOBILE4: if (len != 6) goto invlen; - printf(", Home-Addr=%s", ipaddr_string(p + 2)); + TCHECK2(*(p + 2), 4); + printf(", Home-Addr %s", ipaddr_string(p + 2)); break; case IPCPOPT_PRIDNS: if (len != 6) goto invlen; - printf(", Pri-DNS=%s", ipaddr_string(p + 2)); + TCHECK2(*(p + 2), 4); + printf(", Pri-DNS %s", ipaddr_string(p + 2)); break; case IPCPOPT_PRINBNS: if (len != 6) goto invlen; - printf(", Pri-NBNS=%s", ipaddr_string(p + 2)); + TCHECK2(*(p + 2), 4); + printf(", Pri-NBNS %s", ipaddr_string(p + 2)); break; case IPCPOPT_SECDNS: if (len != 6) goto invlen; - printf(", Sec-DNS=%s", ipaddr_string(p + 2)); + TCHECK2(*(p + 2), 4); + printf(", Sec-DNS %s", ipaddr_string(p + 2)); break; case IPCPOPT_SECNBNS: if (len != 6) goto invlen; - printf(", Sec-NBNS=%s", ipaddr_string(p + 2)); + TCHECK2(*(p + 2), 4); + printf(", Sec-NBNS %s", ipaddr_string(p + 2)); break; default: printf(", unknown-%d", opt); @@ -884,6 +969,10 @@ print_ipcp_config_options(const u_char *p, int length) invlen: printf(", invalid-length-%d", opt); return 0; + +trunc: + printf("[|ipcp]"); + return 0; } /* CCP config options */ @@ -894,6 +983,7 @@ print_ccp_config_options(const u_char *p, int length) if (length < 2) return 0; + TCHECK2(*p, 2); len = p[1]; opt = p[0]; if (length < len) @@ -925,6 +1015,10 @@ print_ccp_config_options(const u_char *p, int length) } #endif return len; + +trunc: + printf("[|ccp]"); + return 0; } /* BACP config options */ @@ -935,17 +1029,23 @@ print_bacp_config_options(const u_char *p, int length) if (length < 2) return 0; + TCHECK2(*p, 2); len = p[1]; opt = p[0]; if (length < len) return 0; if (opt == BACPOPT_FPEER) { + TCHECK2(*(p + 2), 4); printf(", Favored-Peer"); - printf(" Magic-Num=%08x", EXTRACT_32BITS(p + 2)); + printf(", Magic-Num 0x%08x", EXTRACT_32BITS(p + 2)); } else { printf(", unknown-option-%d", opt); } return len; + +trunc: + printf("[|bacp]"); + return 0; } @@ -956,6 +1056,9 @@ handle_ppp(u_int proto, const u_char *p, int length) switch (proto) { case PPP_LCP: case PPP_IPCP: + case PPP_OSICP: + case PPP_MPLSCP: + case PPP_IPV6CP: case PPP_CCP: case PPP_BACP: handle_ctrl_proto(proto, p, length); @@ -984,19 +1087,26 @@ handle_ppp(u_int proto, const u_char *p, int length) ipx_print(p, length); break; case PPP_OSI: - isoclns_print(p, length, length, NULL, NULL); + isoclns_print(p, length, length); break; - default: + case PPP_MPLS_UCAST: + case PPP_MPLS_MCAST: + mpls_print(p, length); break; + default: + printf("unknown PPP protocol (0x%04x)", proto); + print_unknown_data(p,"\n\t",length); + break; } } /* Standard PPP printer */ -void +u_int ppp_print(register const u_char *p, u_int length) { u_int proto; - u_int full_length = length; + u_int olen = length; /* _o_riginal length */ + u_int hdr_len = 0; /* * Here, we assume that p points to the Address and Control @@ -1004,57 +1114,55 @@ ppp_print(register const u_char *p, u_int length) */ if (length < 2) goto trunc; + TCHECK2(*p, 2); if (*p == PPP_ADDRESS && *(p + 1) == PPP_CONTROL) { p += 2; /* ACFC not used */ length -= 2; + hdr_len += 2; } if (length < 2) goto trunc; + TCHECK(*p); if (*p % 2) { proto = *p; /* PFC is used */ p++; length--; + hdr_len++; } else { + TCHECK2(*p, 2); proto = EXTRACT_16BITS(p); p += 2; length -= 2; + hdr_len += 2; } - if (eflag) - printf("%s %d: ", ppp_protoname(proto), full_length); + if (eflag) + printf("PPP-%s (0x%04x), length %u: ", + tok2str(ppptype2str, "unknown", proto), + proto, + olen); handle_ppp(proto, p, length); - return; + return (hdr_len); trunc: printf("[|ppp]"); + return (0); } /* PPP I/F printer */ -void -ppp_if_print(u_char *user, const struct pcap_pkthdr *h, - register const u_char *p) +u_int +ppp_if_print(const struct pcap_pkthdr *h, register const u_char *p) { register u_int length = h->len; register u_int caplen = h->caplen; - ++infodelay; - ts_print(&h->ts); - if (caplen < PPP_HDRLEN) { printf("[|ppp]"); - goto out; + return (caplen); } - /* - * Some printers want to get back at the link level addresses, - * and/or check that they're not walking off the end of the packet. - * Rather than pass them all the way down, we set these globals. */ - - packetp = p; - snapend = p + caplen; - #if 0 /* * XXX: seems to assume that there are 2 octets prepended to an @@ -1098,13 +1206,7 @@ ppp_if_print(u_char *user, const struct pcap_pkthdr *h, ppp_print(p, length); - if (xflag) - default_print(p, caplen); -out: - putchar('\n'); - --infodelay; - if (infoprint) - info(0); + return (0); } /* @@ -1116,62 +1218,52 @@ out: * * This handles, for example, DLT_PPP_SERIAL in NetBSD. */ -void -ppp_hdlc_if_print(u_char *user, const struct pcap_pkthdr *h, - register const u_char *p) +u_int +ppp_hdlc_if_print(const struct pcap_pkthdr *h, register const u_char *p) { register u_int length = h->len; register u_int caplen = h->caplen; u_int proto; - - ++infodelay; - ts_print(&h->ts); + u_int hdrlen = 0; if (caplen < 2) { printf("[|ppp]"); - goto out; + return (caplen); } - /* - * Some printers want to get back at the link level addresses, - * and/or check that they're not walking off the end of the packet. - * Rather than pass them all the way down, we set these globals. - */ - packetp = p; - snapend = p + caplen; - switch (p[0]) { case PPP_ADDRESS: if (caplen < 4) { printf("[|ppp]"); - goto out; + return (caplen); } if (eflag) printf("%02x %02x %d ", p[0], p[1], length); p += 2; length -= 2; + hdrlen += 2; proto = EXTRACT_16BITS(p); p += 2; length -= 2; - if (eflag) - printf("%s: ", ppp_protoname(proto)); + hdrlen += 2; + printf("%s: ", tok2str(ppptype2str, "unknown PPP protocol (0x%04x)", proto)); handle_ppp(proto, p, length); break; case CHDLC_UNICAST: case CHDLC_BCAST: - chdlc_print(p, length, caplen); - goto out; + return (chdlc_if_print(h, p)); default: if (eflag) printf("%02x %02x %d ", p[0], p[1], length); p += 2; length -= 2; + hdrlen += 2; /* * XXX - NetBSD's "ppp_netbsd_serial_if_print()" treats @@ -1182,82 +1274,28 @@ ppp_hdlc_if_print(u_char *user, const struct pcap_pkthdr *h, break; } - if (xflag) - default_print(p, caplen); -out: - putchar('\n'); - --infodelay; - if (infoprint) - info(0); + return (hdrlen); } - - -struct tok ppptype2str[] = { - { PPP_IP, "IP" }, - { PPP_OSI, "OSI" }, - { PPP_NS, "NS" }, - { PPP_DECNET, "DECNET" }, - { PPP_APPLE, "APPLE" }, - { PPP_IPX, "IPX" }, - { PPP_VJC, "VJC" }, - { PPP_VJNC, "VJNC" }, - { PPP_BRPDU, "BRPDU" }, - { PPP_STII, "STII" }, - { PPP_VINES, "VINES" }, - - { PPP_HELLO, "HELLO" }, - { PPP_LUXCOM, "LUXCOM" }, - { PPP_SNS, "SNS" }, - { PPP_IPCP, "IPCP" }, - { PPP_OSICP, "OSICP" }, - { PPP_NSCP, "NSCP" }, - { PPP_DECNETCP, "DECNETCP" }, - { PPP_APPLECP, "APPLECP" }, - { PPP_IPXCP, "IPXCP" }, - { PPP_STIICP, "STIICP" }, - { PPP_VINESCP, "VINESCP" }, - - { PPP_LCP, "LCP" }, - { PPP_PAP, "PAP" }, - { PPP_LQM, "LQM" }, - { PPP_CHAP, "CHAP" }, - { PPP_BACP, "BACP" }, - { PPP_BAP, "BAP" }, - { PPP_MP, "MP" }, - { 0, NULL } -}; - #define PPP_BSDI_HDRLEN 24 /* BSD/OS specific PPP printer */ -void -ppp_bsdos_if_print(u_char *user, const struct pcap_pkthdr *h, - register const u_char *p) +u_int +ppp_bsdos_if_print(const struct pcap_pkthdr *h _U_, register const u_char *p _U_) { + register int hdrlength; #ifdef __bsdi__ register u_int length = h->len; register u_int caplen = h->caplen; - register int hdrlength; u_int16_t ptype; const u_char *q; int i; - ++infodelay; - ts_print(&h->ts); - if (caplen < PPP_BSDI_HDRLEN) { printf("[|ppp]"); - goto out; + return (caplen) } - /* - * Some printers want to get back at the link level addresses, - * and/or check that they're not walking off the end of the packet. - * Rather than pass them all the way down, we set these globals. - */ - packetp = p; - snapend = p + caplen; hdrlength = 0; #if 0 @@ -1321,7 +1359,7 @@ ppp_bsdos_if_print(u_char *user, const struct pcap_pkthdr *h, switch (ptype) { case PPP_VJC: - ptype = vjc_print(q, length - (q - p), ptype); + ptype = vjc_print(q, ptype); hdrlength = PPP_BSDI_HDRLEN; p += hdrlength; switch (ptype) { @@ -1333,10 +1371,14 @@ ppp_bsdos_if_print(u_char *user, const struct pcap_pkthdr *h, ip6_print(p, length); break; #endif + case PPP_MPLS_UCAST: + case PPP_MPLS_MCAST: + mpls_print(p, length); + break; } goto printx; case PPP_VJNC: - ptype = vjc_print(q, length - (q - p), ptype); + ptype = vjc_print(q, ptype); hdrlength = PPP_BSDI_HDRLEN; p += hdrlength; switch (ptype) { @@ -1348,6 +1390,10 @@ ppp_bsdos_if_print(u_char *user, const struct pcap_pkthdr *h, ip6_print(p, length); break; #endif + case PPP_MPLS_UCAST: + case PPP_MPLS_MCAST: + mpls_print(p, length); + break; } goto printx; default: @@ -1376,17 +1422,17 @@ ppp_bsdos_if_print(u_char *user, const struct pcap_pkthdr *h, ip6_print(p, length); break; #endif + case PPP_MPLS_UCAST: + case PPP_MPLS_MCAST: + mpls_print(p, length); + break; default: - printf("%s ", tok2str(ppptype2str, "proto-#%d", ptype)); + printf("%s ", tok2str(ppptype2str, "unknown PPP protocol (0x%04x)", ptype)); } printx: - if (xflag) - default_print((const u_char *)p, caplen - hdrlength); -out: - putchar('\n'); - --infodelay; - if (infoprint) - info(0); +#else /* __bsdi */ + hdrlength = 0; #endif /* __bsdi__ */ + return (hdrlength); } diff --git a/contrib/tcpdump/print-sl.c b/contrib/tcpdump/print-sl.c index 6f2e872efe46..87f31bba19a5 100644 --- a/contrib/tcpdump/print-sl.c +++ b/contrib/tcpdump/print-sl.c @@ -22,21 +22,16 @@ */ #ifndef lint -static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/print-sl.c,v 1.57 2001/07/05 18:54:17 guy Exp $ (LBL)"; +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-sl.c,v 1.62.2.2 2003/11/16 08:51:44 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include <sys/param.h> -#include <sys/time.h> +#include <tcpdump-stdinc.h> -#include <netinet/in.h> - -#include <ctype.h> -#include <netdb.h> #include <pcap.h> #include <stdio.h> @@ -55,27 +50,17 @@ static u_int lastconn = 255; static void sliplink_print(const u_char *, const struct ip *, u_int); static void compressed_sl_print(const u_char *, const struct ip *, u_int, int); -void -sl_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) +u_int +sl_if_print(const struct pcap_pkthdr *h, const u_char *p) { register u_int caplen = h->caplen; register u_int length = h->len; register const struct ip *ip; - ++infodelay; - ts_print(&h->ts); - if (caplen < SLIP_HDRLEN) { printf("[|slip]"); - goto out; + return (caplen); } - /* - * Some printers want to get back at the link level addresses, - * and/or check that they're not walking off the end of the packet. - * Rather than pass them all the way down, we set these globals. - */ - packetp = p; - snapend = p + caplen; length -= SLIP_HDRLEN; @@ -97,37 +82,20 @@ sl_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) printf ("ip v%d", IP_V(ip)); } - if (xflag) - default_print((u_char *)ip, caplen - SLIP_HDRLEN); - out: - putchar('\n'); - --infodelay; - if (infoprint) - info(0); + return (SLIP_HDRLEN); } - -void -sl_bsdos_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) +u_int +sl_bsdos_if_print(const struct pcap_pkthdr *h, const u_char *p) { register u_int caplen = h->caplen; register u_int length = h->len; register const struct ip *ip; - ++infodelay; - ts_print(&h->ts); - if (caplen < SLIP_HDRLEN) { printf("[|slip]"); - goto out; + return (caplen); } - /* - * Some printers want to get back at the link level addresses, - * and/or check that they're not walking off the end of the packet. - * Rather than pass them all the way down, we set these globals. - */ - packetp = p; - snapend = p + caplen; length -= SLIP_HDRLEN; @@ -140,13 +108,7 @@ sl_bsdos_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) ip_print((u_char *)ip, length); - if (xflag) - default_print((u_char *)ip, caplen - SLIP_HDRLEN); - out: - putchar('\n'); - --infodelay; - if (infoprint) - info(0); + return (SLIP_HDRLEN); } static void diff --git a/contrib/tcpdump/print-sunrpc.c b/contrib/tcpdump/print-sunrpc.c index 41d3bfb30fcc..83e16f03395b 100644 --- a/contrib/tcpdump/print-sunrpc.c +++ b/contrib/tcpdump/print-sunrpc.c @@ -22,33 +22,30 @@ */ #ifndef lint -static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/print-sunrpc.c,v 1.39.6.1 2002/06/01 23:51:16 guy Exp $ (LBL)"; +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-sunrpc.c,v 1.43.2.2 2003/11/16 08:51:47 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include <sys/param.h> -#include <sys/time.h> -#include <sys/socket.h> - -#include <netinet/in.h> +#include <tcpdump-stdinc.h> #include <rpc/rpc.h> #ifdef HAVE_RPC_RPCENT_H #include <rpc/rpcent.h> #endif +#ifndef WIN32 #include <rpc/pmap_prot.h> +#endif /* WIN32 */ -#include <ctype.h> -#include <netdb.h> #include <stdio.h> #include <string.h> #include "interface.h" #include "addrtoname.h" +#include "extract.h" #include "ip.h" #ifdef INET6 @@ -84,11 +81,11 @@ sunrpcrequest_print(register const u_char *bp, register u_int length, if (!nflag) { snprintf(srcid, sizeof(srcid), "0x%x", - (u_int32_t)ntohl(rp->rm_xid)); + EXTRACT_32BITS(&rp->rm_xid)); strlcpy(dstid, "sunrpc", sizeof(dstid)); } else { snprintf(srcid, sizeof(srcid), "0x%x", - (u_int32_t)ntohl(rp->rm_xid)); + EXTRACT_32BITS(&rp->rm_xid)); snprintf(dstid, sizeof(dstid), "0x%x", PMAPPORT); } @@ -113,23 +110,23 @@ sunrpcrequest_print(register const u_char *bp, register u_int length, } printf(" %s", tok2str(proc2str, " proc #%u", - (u_int32_t)ntohl(rp->rm_call.cb_proc))); - x = ntohl(rp->rm_call.cb_rpcvers); + EXTRACT_32BITS(&rp->rm_call.cb_proc))); + x = EXTRACT_32BITS(&rp->rm_call.cb_rpcvers); if (x != 2) printf(" [rpcver %u]", x); - switch (ntohl(rp->rm_call.cb_proc)) { + switch (EXTRACT_32BITS(&rp->rm_call.cb_proc)) { case PMAPPROC_SET: case PMAPPROC_UNSET: case PMAPPROC_GETPORT: case PMAPPROC_CALLIT: - x = ntohl(rp->rm_call.cb_prog); + x = EXTRACT_32BITS(&rp->rm_call.cb_prog); if (!nflag) printf(" %s", progstr(x)); else printf(" %u", x); - printf(".%u", (u_int32_t)ntohl(rp->rm_call.cb_vers)); + printf(".%u", EXTRACT_32BITS(&rp->rm_call.cb_vers)); break; } } @@ -138,16 +135,22 @@ static char * progstr(prog) u_int32_t prog; { +#ifndef WIN32 register struct rpcent *rp; +#endif static char buf[32]; - static int lastprog = 0; + static u_int32_t lastprog = 0; if (lastprog != 0 && prog == lastprog) return (buf); +#ifndef WIN32 rp = getrpcbynumber(prog); if (rp == NULL) +#endif /* WIN32 */ (void) snprintf(buf, sizeof(buf), "#%u", prog); +#ifndef WIN32 else strlcpy(buf, rp->r_name, sizeof(buf)); +#endif return (buf); } diff --git a/contrib/tcpdump/print-token.c b/contrib/tcpdump/print-token.c index 748c4b66a88b..4d067061cbf8 100644 --- a/contrib/tcpdump/print-token.c +++ b/contrib/tcpdump/print-token.c @@ -26,19 +26,15 @@ * $FreeBSD$ */ #ifndef lint -static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/print-token.c,v 1.13 2001/09/18 15:46:37 fenner Exp $"; +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-token.c,v 1.22.2.2 2003/11/16 08:51:51 guy Exp $"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include <sys/param.h> -#include <sys/time.h> -#include <sys/socket.h> - -#include <netinet/in.h> +#include <tcpdump-stdinc.h> #include <pcap.h> #include <stdio.h> @@ -63,7 +59,7 @@ extract_token_addrs(const struct token_header *trp, char *fsrc, char *fdst) * Print the TR MAC header */ static inline void -token_print(register const struct token_header *trp, register u_int length, +token_hdr_print(register const struct token_header *trp, register u_int length, register const u_char *fsrc, register const u_char *fdst) { const char *srcname, *dstname; @@ -103,48 +99,26 @@ static const char *largest_frame[] = { "??" }; -/* - * This is the top level routine of the printer. 'p' is the points - * to the TR header of the packet, 'tvp' is the timestamp, - * 'length' is the length of the packet off the wire, and 'caplen' - * is the number of bytes actually captured. - */ -void -token_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) +u_int +token_print(const u_char *p, u_int length, u_int caplen) { - u_int caplen = h->caplen; - u_int length = h->len; const struct token_header *trp; u_short extracted_ethertype; struct ether_header ehdr; - u_int route_len = 0, seg; + u_int route_len = 0, hdr_len = TOKEN_HDRLEN; + int seg; trp = (const struct token_header *)p; - ++infodelay; - ts_print(&h->ts); - if (caplen < TOKEN_HDRLEN) { printf("[|token-ring]"); - goto out; + return hdr_len; } + /* * Get the TR addresses into a canonical form */ extract_token_addrs(trp, (char*)ESRC(&ehdr), (char*)EDST(&ehdr)); - /* - * Some printers want to get back at the ethernet addresses, - * and/or check that they're not walking off the end of the packet. - * Rather than pass them all the way down, we set these globals. - */ - snapend = p + caplen; - /* - * Actually, the only printers that use packetp are print-arp.c - * and print-bootp.c, and they assume that packetp points to an - * Ethernet header. The right thing to do is to fix them to know - * which link type is in use when they excavate. XXX - */ - packetp = (u_char *)&ehdr; /* Adjust for source routing information in the MAC header */ if (IS_SOURCE_ROUTED(trp)) { @@ -152,32 +126,33 @@ token_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) *ESRC(&ehdr) &= 0x7f; if (eflag) - token_print(trp, length, ESRC(&ehdr), EDST(&ehdr)); + token_hdr_print(trp, length, ESRC(&ehdr), EDST(&ehdr)); route_len = RIF_LENGTH(trp); if (vflag) { printf("%s ", broadcast_indicator[BROADCAST(trp)]); printf("%s", direction[DIRECTION(trp)]); - + for (seg = 0; seg < SEGMENT_COUNT(trp); seg++) printf(" [%d:%d]", RING_NUMBER(trp, seg), BRIDGE_NUMBER(trp, seg)); } else { printf("rt = %x", ntohs(trp->token_rcf)); - + for (seg = 0; seg < SEGMENT_COUNT(trp); seg++) printf(":%x", ntohs(trp->token_rseg[seg])); } printf(" (%s) ", largest_frame[LARGEST_FRAME(trp)]); } else { if (eflag) - token_print(trp, length, ESRC(&ehdr), EDST(&ehdr)); + token_hdr_print(trp, length, ESRC(&ehdr), EDST(&ehdr)); } /* Skip over token ring MAC header and routing information */ - length -= TOKEN_HDRLEN + route_len; - p += TOKEN_HDRLEN + route_len; - caplen -= TOKEN_HDRLEN + route_len; + hdr_len += route_len; + length -= hdr_len; + p += hdr_len; + caplen -= hdr_len; /* Frame Control field determines interpretation of packet */ extracted_ethertype = 0; @@ -187,7 +162,7 @@ token_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) &extracted_ethertype) == 0) { /* ether_type not known, print raw packet */ if (!eflag) - token_print(trp, + token_hdr_print(trp, length + TOKEN_HDRLEN + route_len, ESRC(&ehdr), EDST(&ehdr)); if (extracted_ethertype) { @@ -201,16 +176,22 @@ token_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) /* Some kinds of TR packet we cannot handle intelligently */ /* XXX - dissect MAC packets if frame type is 0 */ if (!eflag) - token_print(trp, length + TOKEN_HDRLEN + route_len, + token_hdr_print(trp, length + TOKEN_HDRLEN + route_len, ESRC(&ehdr), EDST(&ehdr)); if (!xflag && !qflag) default_print(p, caplen); } - if (xflag) - default_print(p, caplen); -out: - putchar('\n'); - --infodelay; - if (infoprint) - info(0); + return (hdr_len); +} + +/* + * This is the top level routine of the printer. 'p' points + * to the TR header of the packet, 'h->ts' is the timestamp, + * 'h->length' is the length of the packet off the wire, and 'h->caplen' + * is the number of bytes actually captured. + */ +u_int +token_if_print(const struct pcap_pkthdr *h, const u_char *p) +{ + return (token_print(p, h->len, h->caplen)); } diff --git a/contrib/tcpdump/print-udp.c b/contrib/tcpdump/print-udp.c index 536e9afae1ff..7d910cb7fc3c 100644 --- a/contrib/tcpdump/print-udp.c +++ b/contrib/tcpdump/print-udp.c @@ -22,18 +22,15 @@ */ #ifndef lint -static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/print-udp.c,v 1.101 2001/10/08 21:25:24 fenner Exp $ (LBL)"; +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-udp.c,v 1.124.2.5 2003/11/19 00:19:25 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include <sys/param.h> -#include <sys/time.h> - -#include <netinet/in.h> +#include <tcpdump-stdinc.h> #ifdef SEGSIZE #undef SEGSIZE @@ -47,6 +44,7 @@ static const char rcsid[] = #include "interface.h" #include "addrtoname.h" +#include "extract.h" #include "appletalk.h" #include "udp.h" @@ -55,6 +53,7 @@ static const char rcsid[] = #ifdef INET6 #include "ip6.h" #endif +#include "ipproto.h" #include "nameser.h" #include "nfs.h" @@ -110,21 +109,21 @@ struct rtcp_rr { #define RTCP_PT_APP 204 static void -vat_print(const void *hdr, u_int len, register const struct udphdr *up) +vat_print(const void *hdr, register const struct udphdr *up) { /* vat/vt audio */ u_int ts = *(u_int16_t *)hdr; if ((ts & 0xf060) != 0) { /* probably vt */ (void)printf("udp/vt %u %d / %d", - (u_int32_t)(ntohs(up->uh_ulen) - sizeof(*up)), + (u_int32_t)(EXTRACT_16BITS(&up->uh_ulen) - sizeof(*up)), ts & 0x3ff, ts >> 10); } else { /* probably vat */ - u_int32_t i0 = (u_int32_t)ntohl(((u_int *)hdr)[0]); - u_int32_t i1 = (u_int32_t)ntohl(((u_int *)hdr)[1]); + u_int32_t i0 = EXTRACT_32BITS(&((u_int *)hdr)[0]); + u_int32_t i1 = EXTRACT_32BITS(&((u_int *)hdr)[1]); printf("udp/vat %u c%d %u%s", - (u_int32_t)(ntohs(up->uh_ulen) - sizeof(*up) - 8), + (u_int32_t)(EXTRACT_16BITS(&up->uh_ulen) - sizeof(*up) - 8), i0 & 0xffff, i1, i0 & 0x800000? "*" : ""); /* audio format */ @@ -141,9 +140,9 @@ rtp_print(const void *hdr, u_int len, register const struct udphdr *up) /* rtp v1 or v2 */ u_int *ip = (u_int *)hdr; u_int hasopt, hasext, contype, hasmarker; - u_int32_t i0 = (u_int32_t)ntohl(((u_int *)hdr)[0]); - u_int32_t i1 = (u_int32_t)ntohl(((u_int *)hdr)[1]); - u_int dlen = ntohs(up->uh_ulen) - sizeof(*up) - 8; + u_int32_t i0 = EXTRACT_32BITS(&((u_int *)hdr)[0]); + u_int32_t i1 = EXTRACT_32BITS(&((u_int *)hdr)[1]); + u_int dlen = EXTRACT_16BITS(&up->uh_ulen) - sizeof(*up) - 8; const char * ptype; ip += 2; @@ -176,7 +175,7 @@ rtp_print(const void *hdr, u_int len, register const struct udphdr *up) i0 & 0xffff, i1); if (vflag) { - printf(" %u", (u_int32_t)ntohl(((u_int *)hdr)[2])); + printf(" %u", EXTRACT_32BITS(&((u_int *)hdr)[2])); if (hasopt) { u_int i2, optlen; do { @@ -220,8 +219,8 @@ rtcp_print(const u_char *hdr, const u_char *ep) printf(" [|rtcp]"); return (ep); } - len = (ntohs(rh->rh_len) + 1) * 4; - flags = ntohs(rh->rh_flags); + len = (EXTRACT_16BITS(&rh->rh_len) + 1) * 4; + flags = EXTRACT_16BITS(&rh->rh_flags); cnt = (flags >> 8) & 0x1f; switch (flags & 0xff) { case RTCP_PT_SR: @@ -230,16 +229,16 @@ rtcp_print(const u_char *hdr, const u_char *ep) if (len != cnt * sizeof(*rr) + sizeof(*sr) + sizeof(*rh)) printf(" [%d]", len); if (vflag) - printf(" %u", (u_int32_t)ntohl(rh->rh_ssrc)); + printf(" %u", EXTRACT_32BITS(&rh->rh_ssrc)); if ((u_char *)(sr + 1) > ep) { printf(" [|rtcp]"); return (ep); } - ts = (double)((u_int32_t)ntohl(sr->sr_ntp.upper)) + - ((double)((u_int32_t)ntohl(sr->sr_ntp.lower)) / + ts = (double)(EXTRACT_32BITS(&sr->sr_ntp.upper)) + + ((double)(EXTRACT_32BITS(&sr->sr_ntp.lower)) / 4294967296.0); - printf(" @%.2f %u %up %ub", ts, (u_int32_t)ntohl(sr->sr_ts), - (u_int32_t)ntohl(sr->sr_np), (u_int32_t)ntohl(sr->sr_nb)); + printf(" @%.2f %u %up %ub", ts, EXTRACT_32BITS(&sr->sr_ts), + EXTRACT_32BITS(&sr->sr_np), EXTRACT_32BITS(&sr->sr_nb)); rr = (struct rtcp_rr *)(sr + 1); break; case RTCP_PT_RR: @@ -248,18 +247,18 @@ rtcp_print(const u_char *hdr, const u_char *ep) printf(" [%d]", len); rr = (struct rtcp_rr *)(rh + 1); if (vflag) - printf(" %u", (u_int32_t)ntohl(rh->rh_ssrc)); + printf(" %u", EXTRACT_32BITS(&rh->rh_ssrc)); break; case RTCP_PT_SDES: printf(" sdes %d", len); if (vflag) - printf(" %u", (u_int32_t)ntohl(rh->rh_ssrc)); + printf(" %u", EXTRACT_32BITS(&rh->rh_ssrc)); cnt = 0; break; case RTCP_PT_BYE: printf(" bye %d", len); if (vflag) - printf(" %u", (u_int32_t)ntohl(rh->rh_ssrc)); + printf(" %u", EXTRACT_32BITS(&rh->rh_ssrc)); cnt = 0; break; default: @@ -275,20 +274,20 @@ rtcp_print(const u_char *hdr, const u_char *ep) return (ep); } if (vflag) - printf(" %u", (u_int32_t)ntohl(rr->rr_srcid)); - ts = (double)((u_int32_t)ntohl(rr->rr_lsr)) / 65536.; - dts = (double)((u_int32_t)ntohl(rr->rr_dlsr)) / 65536.; + printf(" %u", EXTRACT_32BITS(&rr->rr_srcid)); + ts = (double)(EXTRACT_32BITS(&rr->rr_lsr)) / 65536.; + dts = (double)(EXTRACT_32BITS(&rr->rr_dlsr)) / 65536.; printf(" %ul %us %uj @%.2f+%.2f", - (u_int32_t)ntohl(rr->rr_nl) & 0x00ffffff, - (u_int32_t)ntohl(rr->rr_ls), - (u_int32_t)ntohl(rr->rr_dv), ts, dts); + EXTRACT_32BITS(&rr->rr_nl) & 0x00ffffff, + EXTRACT_32BITS(&rr->rr_ls), + EXTRACT_32BITS(&rr->rr_dv), ts, dts); } return (hdr + len); } static int udp_cksum(register const struct ip *ip, register const struct udphdr *up, - register int len) + register u_int len) { union phu { struct phdr { @@ -303,11 +302,14 @@ static int udp_cksum(register const struct ip *ip, register const u_int16_t *sp; /* pseudo-header.. */ - phu.ph.len = htons(len); + phu.ph.len = htons((u_int16_t)len); phu.ph.mbz = 0; phu.ph.proto = IPPROTO_UDP; memcpy(&phu.ph.src, &ip->ip_src.s_addr, sizeof(u_int32_t)); - memcpy(&phu.ph.dst, &ip->ip_dst.s_addr, sizeof(u_int32_t)); + if (IP_HL(ip) == 5) + memcpy(&phu.ph.dst, &ip->ip_dst.s_addr, sizeof(u_int32_t)); + else + phu.ph.dst = ip_finddst(ip); sp = &phu.pa[0]; return in_cksum((u_short *)up, len, @@ -316,9 +318,9 @@ static int udp_cksum(register const struct ip *ip, #ifdef INET6 static int udp6_cksum(const struct ip6_hdr *ip6, const struct udphdr *up, - int len) + u_int len) { - int i, tlen; + size_t i; register const u_int16_t *sp; u_int32_t sum; union { @@ -332,14 +334,11 @@ static int udp6_cksum(const struct ip6_hdr *ip6, const struct udphdr *up, u_int16_t pa[20]; } phu; - tlen = ntohs(ip6->ip6_plen) + sizeof(struct ip6_hdr) - - ((const char *)up - (const char*)ip6); - /* pseudo-header */ memset(&phu, 0, sizeof(phu)); phu.ph.ph_src = ip6->ip6_src; phu.ph.ph_dst = ip6->ip6_dst; - phu.ph.ph_len = htonl(tlen); + phu.ph.ph_len = htonl(len); phu.ph.ph_nxt = IPPROTO_UDP; sum = 0; @@ -348,10 +347,10 @@ static int udp6_cksum(const struct ip6_hdr *ip6, const struct udphdr *up, sp = (const u_int16_t *)up; - for (i = 0; i < (tlen & ~1); i += 2) + for (i = 0; i < (len & ~1); i += 2) sum += *sp++; - if (tlen & 1) + if (len & 1) sum += htons((*(const u_int8_t *)sp) << 8); while (sum > 0xffff) @@ -362,40 +361,61 @@ static int udp6_cksum(const struct ip6_hdr *ip6, const struct udphdr *up, } #endif +static void +udpipaddr_print(const struct ip *ip, int sport, int dport) +{ +#ifdef INET6 + const struct ip6_hdr *ip6; -/* XXX probably should use getservbyname() and cache answers */ -#define TFTP_PORT 69 /*XXX*/ -#define KERBEROS_PORT 88 /*XXX*/ -#define SUNRPC_PORT 111 /*XXX*/ -#define SNMP_PORT 161 /*XXX*/ -#define NTP_PORT 123 /*XXX*/ -#define SNMPTRAP_PORT 162 /*XXX*/ -#define ISAKMP_PORT 500 /*XXX*/ -#define TIMED_PORT 525 /*XXX*/ -#define RIP_PORT 520 /*XXX*/ -#define KERBEROS_SEC_PORT 750 /*XXX*/ -#define L2TP_PORT 1701 /*XXX*/ -#define ISAKMP_PORT_USER1 7500 /*XXX - nonstandard*/ -#define ISAKMP_PORT_USER2 8500 /*XXX - nonstandard*/ -#define RX_PORT_LOW 7000 /*XXX*/ -#define RX_PORT_HIGH 7009 /*XXX*/ -#define NETBIOS_NS_PORT 137 -#define NETBIOS_DGRAM_PORT 138 -#define CISCO_AUTORP_PORT 496 /*XXX*/ -#define RADIUS_PORT 1645 -#define RADIUS_NEW_PORT 1812 -#define RADIUS_ACCOUNTING_PORT 1646 -#define RADIUS_NEW_ACCOUNTING_PORT 1813 -#define HSRP_PORT 1985 /*XXX*/ -#define LWRES_PORT 921 -#define ZEPHYR_SRV_PORT 2103 -#define ZEPHYR_CLT_PORT 2104 + if (IP_V(ip) == 6) + ip6 = (const struct ip6_hdr *)ip; + else + ip6 = NULL; -#ifdef INET6 -#define RIPNG_PORT 521 /*XXX*/ -#define DHCP6_SERV_PORT 546 /*XXX*/ -#define DHCP6_CLI_PORT 547 /*XXX*/ -#endif + if (ip6) { + if (ip6->ip6_nxt == IPPROTO_UDP) { + if (sport == -1) { + (void)printf("%s > %s: ", + ip6addr_string(&ip6->ip6_src), + ip6addr_string(&ip6->ip6_dst)); + } else { + (void)printf("%s.%s > %s.%s: ", + ip6addr_string(&ip6->ip6_src), + udpport_string(sport), + ip6addr_string(&ip6->ip6_dst), + udpport_string(dport)); + } + } else { + if (sport != -1) { + (void)printf("%s > %s: ", + udpport_string(sport), + udpport_string(dport)); + } + } + } else +#endif /*INET6*/ + { + if (ip->ip_p == IPPROTO_UDP) { + if (sport == -1) { + (void)printf("%s > %s: ", + ipaddr_string(&ip->ip_src), + ipaddr_string(&ip->ip_dst)); + } else { + (void)printf("%s.%s > %s.%s: ", + ipaddr_string(&ip->ip_src), + udpport_string(sport), + ipaddr_string(&ip->ip_dst), + udpport_string(dport)); + } + } else { + if (sport != -1) { + (void)printf("%s > %s: ", + udpport_string(sport), + udpport_string(dport)); + } + } + } +} void udp_print(register const u_char *bp, u_int length, @@ -421,27 +441,32 @@ udp_print(register const u_char *bp, u_int length, ip6 = NULL; #endif /*INET6*/ cp = (u_char *)(up + 1); - if (cp > snapend) { - (void)printf("%s > %s: [|udp]", - ipaddr_string(&ip->ip_src), ipaddr_string(&ip->ip_dst)); + if (!TTEST(up->uh_dport)) { + udpipaddr_print(ip, -1, -1); + (void)printf("[|udp]"); return; } + + sport = EXTRACT_16BITS(&up->uh_sport); + dport = EXTRACT_16BITS(&up->uh_dport); + if (length < sizeof(struct udphdr)) { - (void)printf("%s > %s: truncated-udp %d", - ipaddr_string(&ip->ip_src), ipaddr_string(&ip->ip_dst), - length); + udpipaddr_print(ip, sport, dport); + (void)printf("truncated-udp %d", length); return; } length -= sizeof(struct udphdr); - sport = ntohs(up->uh_sport); - dport = ntohs(up->uh_dport); - ulen = ntohs(up->uh_ulen); + if (cp > snapend) { + udpipaddr_print(ip, sport, dport); + (void)printf("[|udp]"); + return; + } + + ulen = EXTRACT_16BITS(&up->uh_ulen); if (ulen < 8) { - (void)printf("%s > %s: truncated-udplength %d", - ipaddr_string(&ip->ip_src), - ipaddr_string(&ip->ip_dst), - ulen); + udpipaddr_print(ip, sport, dport); + (void)printf("truncated-udplength %d", ulen); return; } if (packettype) { @@ -451,26 +476,18 @@ udp_print(register const u_char *bp, u_int length, switch (packettype) { case PT_VAT: - (void)printf("%s.%s > %s.%s: ", - ipaddr_string(&ip->ip_src), - udpport_string(sport), - ipaddr_string(&ip->ip_dst), - udpport_string(dport)); - vat_print((void *)(up + 1), length, up); + udpipaddr_print(ip, sport, dport); + vat_print((void *)(up + 1), up); break; case PT_WB: - (void)printf("%s.%s > %s.%s: ", - ipaddr_string(&ip->ip_src), - udpport_string(sport), - ipaddr_string(&ip->ip_dst), - udpport_string(dport)); + udpipaddr_print(ip, sport, dport); wb_print((void *)(up + 1), length); break; case PT_RPC: rp = (struct rpc_msg *)(up + 1); - direction = (enum msg_type)ntohl(rp->rm_direction); + direction = (enum msg_type)EXTRACT_32BITS(&rp->rm_direction); if (direction == CALL) sunrpcrequest_print((u_char *)rp, length, (u_char *)ip); @@ -480,40 +497,39 @@ udp_print(register const u_char *bp, u_int length, break; case PT_RTP: - (void)printf("%s.%s > %s.%s: ", - ipaddr_string(&ip->ip_src), - udpport_string(sport), - ipaddr_string(&ip->ip_dst), - udpport_string(dport)); + udpipaddr_print(ip, sport, dport); rtp_print((void *)(up + 1), length, up); break; case PT_RTCP: - (void)printf("%s.%s > %s.%s:", - ipaddr_string(&ip->ip_src), - udpport_string(sport), - ipaddr_string(&ip->ip_dst), - udpport_string(dport)); + udpipaddr_print(ip, sport, dport); while (cp < ep) cp = rtcp_print(cp, ep); break; case PT_SNMP: - (void)printf("%s.%s > %s.%s:", - ipaddr_string(&ip->ip_src), - udpport_string(sport), - ipaddr_string(&ip->ip_dst), - udpport_string(dport)); + udpipaddr_print(ip, sport, dport); snmp_print((const u_char *)(up + 1), length); break; case PT_CNFP: - (void)printf("%s.%s > %s.%s:", - ipaddr_string(&ip->ip_src), - udpport_string(sport), - ipaddr_string(&ip->ip_dst), - udpport_string(dport)); - cnfp_print(cp, length, (const u_char *)ip); + udpipaddr_print(ip, sport, dport); + cnfp_print(cp, (const u_char *)ip); + break; + + case PT_TFTP: + udpipaddr_print(ip, sport, dport); + tftp_print(cp, length); + break; + + case PT_AODV: + udpipaddr_print(ip, sport, dport); + aodv_print((const u_char *)(up + 1), length, +#ifdef INET6 + ip6 != NULL); +#else + FALSE); +#endif break; } return; @@ -525,7 +541,7 @@ udp_print(register const u_char *bp, u_int length, rp = (struct rpc_msg *)(up + 1); if (TTEST(rp->rm_direction)) { - direction = (enum msg_type)ntohl(rp->rm_direction); + direction = (enum msg_type)EXTRACT_32BITS(&rp->rm_direction); if (dport == NFS_PORT && direction == CALL) { nfsreq_print((u_char *)rp, length, (u_char *)ip); @@ -552,32 +568,7 @@ udp_print(register const u_char *bp, u_int length, return; } } -#ifdef INET6 - if (ip6) { - if (ip6->ip6_nxt == IPPROTO_UDP) { - (void)printf("%s.%s > %s.%s: ", - ip6addr_string(&ip6->ip6_src), - udpport_string(sport), - ip6addr_string(&ip6->ip6_dst), - udpport_string(dport)); - } else { - (void)printf("%s > %s: ", - udpport_string(sport), udpport_string(dport)); - } - } else -#endif /*INET6*/ - { - if (ip->ip_p == IPPROTO_UDP) { - (void)printf("%s.%s > %s.%s: ", - ipaddr_string(&ip->ip_src), - udpport_string(sport), - ipaddr_string(&ip->ip_dst), - udpport_string(dport)); - } else { - (void)printf("%s > %s: ", - udpport_string(sport), udpport_string(dport)); - } - } + udpipaddr_print(ip, sport, dport); if (IP_V(ip) == 4 && vflag && !fragmented) { int sum = up->uh_sum; @@ -596,7 +587,7 @@ udp_print(register const u_char *bp, u_int length, int sum = up->uh_sum; /* for IPv6, UDP checksum is mandatory */ if (TTEST2(cp[0], length)) { - sum = udp6_cksum(ip6, up, length); + sum = udp6_cksum(ip6, up, length + sizeof(struct udphdr)); if (sum != 0) (void)printf("[bad udp cksum %x!] ", sum); else @@ -608,16 +599,24 @@ udp_print(register const u_char *bp, u_int length, if (!qflag) { #define ISPORT(p) (dport == (p) || sport == (p)) if (ISPORT(NAMESERVER_PORT)) - ns_print((const u_char *)(up + 1), length); + ns_print((const u_char *)(up + 1), length, 0); + else if (ISPORT(MULTICASTDNS_PORT)) + ns_print((const u_char *)(up + 1), length, 1); else if (ISPORT(TIMED_PORT)) - timed_print((const u_char *)(up + 1), length); + timed_print((const u_char *)(up + 1)); else if (ISPORT(TFTP_PORT)) tftp_print((const u_char *)(up + 1), length); else if (ISPORT(IPPORT_BOOTPC) || ISPORT(IPPORT_BOOTPS)) - bootp_print((const u_char *)(up + 1), length, - sport, dport); + bootp_print((const u_char *)(up + 1), length); else if (ISPORT(RIP_PORT)) rip_print((const u_char *)(up + 1), length); + else if (ISPORT(AODV_PORT)) + aodv_print((const u_char *)(up + 1), length, +#ifdef INET6 + ip6 != NULL); +#else + FALSE); +#endif else if (ISPORT(ISAKMP_PORT)) isakmp_print((const u_char *)(up + 1), length, bp2); #if 1 /*???*/ @@ -629,33 +628,32 @@ udp_print(register const u_char *bp, u_int length, else if (ISPORT(NTP_PORT)) ntp_print((const u_char *)(up + 1), length); else if (ISPORT(KERBEROS_PORT) || ISPORT(KERBEROS_SEC_PORT)) - krb_print((const void *)(up + 1), length); + krb_print((const void *)(up + 1)); else if (ISPORT(L2TP_PORT)) l2tp_print((const u_char *)(up + 1), length); #ifdef TCPDUMP_DO_SMB - else if (ISPORT(NETBIOS_NS_PORT)) + else if (ISPORT(NETBIOS_NS_PORT)) nbt_udp137_print((const u_char *)(up + 1), length); - else if (ISPORT(NETBIOS_DGRAM_PORT)) - nbt_udp138_print((const u_char *)(up + 1), length); + else if (ISPORT(NETBIOS_DGRAM_PORT)) + nbt_udp138_print((const u_char *)(up + 1), length); #endif else if (dport == 3456) - vat_print((const void *)(up + 1), length, up); + vat_print((const void *)(up + 1), up); else if (ISPORT(ZEPHYR_SRV_PORT) || ISPORT(ZEPHYR_CLT_PORT)) zephyr_print((const void *)(up + 1), length); - /* - * Since there are 10 possible ports to check, I think - * a <> test would be more efficient - */ - else if ((sport >= RX_PORT_LOW && sport <= RX_PORT_HIGH) || - (dport >= RX_PORT_LOW && dport <= RX_PORT_HIGH)) - rx_print((const void *)(up + 1), length, sport, dport, - (u_char *) ip); + /* + * Since there are 10 possible ports to check, I think + * a <> test would be more efficient + */ + else if ((sport >= RX_PORT_LOW && sport <= RX_PORT_HIGH) || + (dport >= RX_PORT_LOW && dport <= RX_PORT_HIGH)) + rx_print((const void *)(up + 1), length, sport, dport, + (u_char *) ip); #ifdef INET6 else if (ISPORT(RIPNG_PORT)) ripng_print((const u_char *)(up + 1), length); else if (ISPORT(DHCP6_SERV_PORT) || ISPORT(DHCP6_CLI_PORT)) { - dhcp6_print((const u_char *)(up + 1), length, - sport, dport); + dhcp6_print((const u_char *)(up + 1), length); } #endif /*INET6*/ /* @@ -667,17 +665,24 @@ udp_print(register const u_char *bp, u_int length, cisco_autorp_print((const void *)(up + 1), length); else if (ISPORT(RADIUS_PORT) || ISPORT(RADIUS_NEW_PORT) || - ISPORT(RADIUS_ACCOUNTING_PORT) || + ISPORT(RADIUS_ACCOUNTING_PORT) || ISPORT(RADIUS_NEW_ACCOUNTING_PORT) ) radius_print((const u_char *)(up+1), length); else if (dport == HSRP_PORT) - hsrp_print((const u_char *)(up + 1), length); + hsrp_print((const u_char *)(up + 1), length); else if (ISPORT(LWRES_PORT)) lwres_print((const u_char *)(up + 1), length); + else if (ISPORT(LDP_PORT)) + ldp_print((const u_char *)(up + 1), length); + else if (ISPORT(MPLS_LSP_PING_PORT)) + mpls_lsp_ping_print((const u_char *)(up + 1), length); + else if (dport == BFD_CONTROL_PORT || + dport == BFD_ECHO_PORT ) + bfd_print((const u_char *)(up+1), length, dport); else - (void)printf("udp %u", + (void)printf("UDP, length: %u", (u_int32_t)(ulen - sizeof(*up))); #undef ISPORT } else - (void)printf("udp %u", (u_int32_t)(ulen - sizeof(*up))); + (void)printf("UDP, length: %u", (u_int32_t)(ulen - sizeof(*up))); } diff --git a/contrib/tcpdump/tcpdump.1 b/contrib/tcpdump/tcpdump.1 index fb3ec3ebe772..daa1dc0d9b56 100644 --- a/contrib/tcpdump/tcpdump.1 +++ b/contrib/tcpdump/tcpdump.1 @@ -1,4 +1,6 @@ -.\" @(#) $Header: /tcpdump/master/tcpdump/tcpdump.1,v 1.114 2002/01/04 07:37:49 guy Exp $ (LBL) +.\" @(#) $Header: /tcpdump/master/tcpdump/tcpdump.1,v 1.148.2.6 2004/03/28 21:25:03 fenner Exp $ (LBL) +.\" +.\" $NetBSD: tcpdump.8,v 1.9 2003/03/31 00:18:17 perry Exp $ .\" .\" Copyright (c) 1987, 1988, 1989, 1990, 1991, 1992, 1994, 1995, 1996, 1997 .\" The Regents of the University of California. All rights reserved. @@ -22,14 +24,14 @@ .\" .\" $FreeBSD$ .\" -.TH TCPDUMP 1 "3 January 2001" +.TH TCPDUMP 1 "7 January 2004" .SH NAME tcpdump \- dump traffic on a network .SH SYNOPSIS .na .B tcpdump [ -.B \-adeflLnNOpqRStuvxX +.B \-AdDeflLnNOpqRStuUvxX ] [ .B \-c .I count @@ -75,8 +77,15 @@ tcpdump \- dump traffic on a network .ti +8 [ .B \-E -.I algo:secret +.I spi@ipaddr algo:secret,... +] +.br +.ti +8 +[ +.B \-y +.I datalinktype ] +.ti +8 [ .B \-y .I datalinktype @@ -118,14 +127,23 @@ When .I tcpdump finishes capturing packets, it will report counts of: .IP +packets ``captured'' (this is the number of packets that +.I tcpdump +has received and processed); +.IP packets ``received by filter'' (the meaning of this depends on the OS on which you're running .IR tcpdump , and possibly on the way the OS was configured - if a filter was specified on the command line, on some OSes it counts packets regardless -of whether they were matched by the filter expression, and on other OSes -it counts only packets that were matched by the filter expression and -were processed by +of whether they were matched by the filter expression and, even if they +were matched by the filter expression, regardless of whether +.I tcpdump +has read and processed them yet, on other OSes it counts only packets that were +matched by the filter expression regardless of whether +.I tcpdump +has read and processed them yet, and on other OSes it counts only +packets that were matched by the filter expression and were processed by .IR tcpdump ); .IP packets ``dropped by kernel'' (this is the number of packets that were @@ -135,10 +153,14 @@ in the OS on which is running, if the OS reports that information to applications; if not, it will be reported as 0). .LP -On platforms that support the SIGINFO signal, such as most BSDs, it will -report those counts when it receives a SIGINFO signal (generated, for -example, by typing your ``status'' character, typically control-T) and -will continue capturing packets. +On platforms that support the SIGINFO signal, such as most BSDs +(including Mac OS X) and Digital/Tru64 UNIX, it will report those counts +when it receives a SIGINFO signal (generated, for example, by typing +your ``status'' character, typically control-T, although on some +platforms, such as Mac OS X, the ``status'' character is not set by +default, so you must set it with +.BR stty (1) +in order to use it) and will continue capturing packets. .LP Reading packets from a network interface may require that you have special privileges: @@ -159,7 +181,9 @@ to capture in promiscuous mode; on those versions of Solaris, you must be root, or .I tcpdump must be installed setuid to root, in order to capture in promiscuous -mode. +mode. Note that, on many (perhaps all) interfaces, if you don't capture +in promiscuous mode, you will not see any outgoing packets, so a capture +not done in promiscuous mode may not be very useful. .TP .B Under HP-UX with DLPI: You must be root or @@ -174,23 +198,48 @@ must be installed setuid to root. .B Under Linux: You must be root or .I tcpdump -must be installed setuid to root. +must be installed setuid to root (unless your distribution has a kernel +that supports capability bits such as CAP_NET_RAW and code to allow +those capability bits to be given to particular accounts and to cause +those bits to be set on a user's initial processes when they log in, in +which case you must have CAP_NET_RAW in order to capture and +CAP_NET_ADMIN to enumerate network devices with, for example, the +.B \-D +flag). .TP -.B Under Ultrix and Digital UNIX: -Once the super-user has enabled promiscuous-mode operation using -.IR pfconfig (8), -any user may capture network traffic with +.B Under ULTRIX and Digital UNIX/Tru64 UNIX: +Any user may capture network traffic with .IR tcpdump . +However, no user (not even the super-user) can capture in promiscuous +mode on an interface unless the super-user has enabled promiscuous-mode +operation on that interface using +.IR pfconfig (8), +and no user (not even the super-user) can capture unicast traffic +received by or sent by the machine on an interface unless the super-user +has enabled copy-all-mode operation on that interface using +.IR pfconfig , +so +.I useful +packet capture on an interface probably requires that either +promiscuous-mode or copy-all-mode operation, or both modes of +operation, be enabled on that interface. .TP -.B Under BSD: +.B Under BSD (this includes Mac OS X): You must have read access to .IR /dev/bpf* . +On BSDs with a devfs (this includes Mac OS X), this might involve more +than just having somebody with super-user access setting the ownership +or permissions on the BPF devices - it might involve configuring devfs +to set the ownership or permissions every time the system is booted, +if the system even supports that; if it doesn't support that, you might +have to find some other way to make that happen at boot time. .LP Reading a saved packet file doesn't require special privileges. .SH OPTIONS .TP -.B \-a -Attempt to convert network and broadcast addresses to names. +.B \-A +Print each packet (minus its link level header) in ASCII. Handy for +capturing web pages. .TP .B \-c Exit after receiving \fIcount\fP packets. @@ -217,11 +266,43 @@ program fragment. .B \-ddd Dump packet-matching code as decimal numbers (preceded with a count). .TP +.B \-D +Print the list of the network interfaces available on the system and on +which +.I tcpdump +can capture packets. For each network interface, a number and an +interface name, possibly followed by a text description of the +interface, is printed. The interface name or the number can be supplied +to the +.B \-i +flag to specify an interface on which to capture. +.IP +This can be useful on systems that don't have a command to list them +(e.g., Windows systems, or UNIX systems lacking +.BR "ifconfig \-a" ); +the number can be useful on Windows 2000 and later systems, where the +interface name is a somewhat complex string. +.IP +The +.B \-D +flag will not be supported if +.I tcpdump +was built with an older version of +.I libpcap +that lacks the +.B pcap_findalldevs() +function. +.TP .B \-e Print the link-level header on each dump line. .TP .B \-E -Use \fIalgo:secret\fP for decrypting IPsec ESP packets. +Use \fIspi@ipaddr algo:secret\fP for decrypting IPsec ESP packets that +are addressed to \fIaddr\fP and contain Security Parameter Index value +\fIspi\fP. This combination may be repeated with comma or newline seperation. +.IP +Note that setting the secret for IPv4 ESP packets is supported at this time. +.IP Algorithms may be \fBdes-cbc\fP, \fB3des-cbc\fP, @@ -232,21 +313,36 @@ Algorithms may be The default is \fBdes-cbc\fP. The ability to decrypt packets is only present if \fItcpdump\fP was compiled with cryptography enabled. -\fIsecret\fP the ascii text for ESP secret key. -We cannot take arbitrary binary value at this moment. +.IP +\fIsecret\fP is the ASCII text for ESP secret key. +If preceeded by 0x, then a hex value will be read. +.IP The option assumes RFC2406 ESP, not RFC1827 ESP. The option is only for debugging purposes, and -the use of this option with truly `secret' key is discouraged. +the use of this option with a true `secret' key is discouraged. By presenting IPsec secret key onto command line you make it visible to others, via .IR ps (1) and other occasions. +.IP +In addition to the above syntax, the syntax \fIfile name\fP may be used +to have tcpdump read the provided file in. The file is opened upon +receiving the first ESP packet, so any special permissions that tcpdump +may have been given should already have been given up. .TP .B \-f Print `foreign' IPv4 addresses numerically rather than symbolically (this option is intended to get around serious brain damage in Sun's NIS server \(em usually it hangs forever translating non-local internet numbers). +.IP +The test for `foreign' IPv4 addresses is done using the IPv4 address and +netmask of the interface on which capture is being done. If that +address or netmask are not available, available, either because the +interface on which capture is being done has no address or netmask or +because the capture is being done on the Linux "any" interface, which +can capture on more than one interface, this option will not work +correctly. .TP .B \-F Use \fIfile\fP as input for the filter expression. @@ -263,6 +359,13 @@ On Linux systems with 2.2 or later kernels, an argument of ``any'' can be used to capture packets from all interfaces. Note that captures on the ``any'' device will not be done in promiscuous mode. +.IP +If the +.B \-D +flag is supported, an interface number as printed by that flag can be +used as the +.I interface +argument. .TP .B \-l Make stdout line buffered. @@ -345,11 +448,13 @@ Setting Force packets selected by "\fIexpression\fP" to be interpreted the specified \fItype\fR. Currently known types are +\fBaodv\fR (Ad-hoc On-demand Distance Vector protocol), \fBcnfp\fR (Cisco NetFlow protocol), \fBrpc\fR (Remote Procedure Call), \fBrtp\fR (Real-Time Applications protocol), \fBrtcp\fR (Real-Time Applications control protocol), \fBsnmp\fR (Simple Network Management Protocol), +\fBtftp\fR (Trivial File Transfer Protocol), \fBvat\fR (Visual Audio Tool), and \fBwb\fR (distributed White Board). @@ -370,6 +475,23 @@ Print a timestamp in default format proceeded by date on each dump line. .B \-u Print undecoded NFS handles. .TP +.B \-U +Make output saved via the +.B \-w +option ``packet-buffered''; i.e., as each packet is saved, it will be +written to the output file, rather than being written only when the +output buffer fills. +.IP +The +.B \-U +flag will not be supported if +.I tcpdump +was built with an older version of +.I libpcap +that lacks the +.B pcap_dump_flush() +function. +.TP .B \-v (Slightly more) verbose output. For example, the time to live, @@ -401,18 +523,24 @@ Standard output is used if \fIfile\fR is ``-''. Print each packet (minus its link level header) in hex. The smaller of the entire packet or .I snaplen -bytes will be printed. +bytes will be printed. Note that this is the entire link-layer +packet, so for link layers that pad (e.g. Ethernet), the padding bytes +will also be printed when the higher layer packet is shorter than the +required padding. +.TP +.B \-xx +Print each packet, +.I including +its link level header, in hex. .TP .B \-X -When printing hex, print ascii too. -Thus if -.B \-x -is also set, the packet is printed in hex/ascii. +Print each packet (minus its link level header) in hex and ASCII. This is very handy for analysing new protocols. -Even if -.B \-x -is not also set, some parts of some packets may be printed -in hex/ascii. +.TP +.B \-XX +Print each packet, +.I including +its link level header, in hex and ASCII. .TP .B \-y Set the data link type to use while capturing packets to \fIdatalinktype\fP. @@ -458,7 +586,8 @@ If there is no dir qualifier, .B "src or dst" is assumed. -For `null' link layers (i.e. point to point protocols such as slip) the +For some link layers, such as SLIP and the ``cooked'' Linux capture mode +used for the ``any'' device and for some other device types, the .B inbound and .B outbound @@ -470,6 +599,7 @@ protos are: .BR ether , .BR fddi , .BR tr , +.BR wlan , .BR ip , .BR ip6 , .BR arp , @@ -504,8 +634,11 @@ analogous Ethernet fields. FDDI headers also contain other fields, but you cannot name them explicitly in a filter expression. .LP -Similarly, `tr' is an alias for `ether'; the previous paragraph's -statements about FDDI headers also apply to Token Ring headers.] +Similarly, `tr' and `wlan' are aliases for `ether'; the previous +paragraph's statements about FDDI headers also apply to Token Ring +and 802.11 wireless LAN headers. For 802.11 headers, the destination +address is the DA field and the source address is the SA field; the +BSSID, RA, and TA fields aren't tested.] .LP In addition to the above, there are some special `primitive' keywords that don't follow the pattern: @@ -675,10 +808,16 @@ True if the packet is an ethernet broadcast packet. The \fIether\fP keyword is optional. .IP "\fBip broadcast\fR" -True if the packet is an IP broadcast packet. -It checks for both -the all-zeroes and all-ones broadcast conventions, and looks up -the local subnet mask. +True if the packet is an IPv4 broadcast packet. +It checks for both the all-zeroes and all-ones broadcast conventions, +and looks up the subnet mask on the interface on which the capture is +being done. +.IP +If the subnet mask of the interface on which the capture is being done +is not available, either because the interface on which capture is being +done has no netmask or because the capture is being done on the Linux +"any" interface, which can capture on more than one interface, this +check will not work correctly. .IP "\fBether multicast\fR" True if the packet is an ethernet multicast packet. The \fIether\fP @@ -697,41 +836,60 @@ True if the packet is of ether type \fIprotocol\fR. Note these identifiers are also keywords and must be escaped via backslash (\\). .IP -[In the case of FDDI (e.g., `\fBfddi protocol arp\fR') and Token Ring -(e.g., `\fBtr protocol arp\fR'), for most of those protocols, the +[In the case of FDDI (e.g., `\fBfddi protocol arp\fR'), Token Ring +(e.g., `\fBtr protocol arp\fR'), and IEEE 802.11 wireless LANS (e.g., +`\fBwlan protocol arp\fR'), for most of those protocols, the protocol identification comes from the 802.2 Logical Link Control (LLC) -header, which is usually layered on top of the FDDI or Token Ring -header. +header, which is usually layered on top of the FDDI, Token Ring, or +802.11 header. .IP -When filtering for most protocol identifiers on FDDI or Token Ring, -\fItcpdump\fR checks only the protocol ID field of an LLC header in -so-called SNAP format with an Organizational Unit Identifier (OUI) of +When filtering for most protocol identifiers on FDDI, Token Ring, or +802.11, \fItcpdump\fR checks only the protocol ID field of an LLC header +in so-called SNAP format with an Organizational Unit Identifier (OUI) of 0x000000, for encapsulated Ethernet; it doesn't check whether the packet is in SNAP format with an OUI of 0x000000. -.IP -The exceptions are \fIiso\fP, for which it checks the DSAP (Destination -Service Access Point) and SSAP (Source Service Access Point) fields of -the LLC header, \fIstp\fP and \fInetbeui\fP, where it checks the DSAP of -the LLC header, and \fIatalk\fP, where it checks for a SNAP-format -packet with an OUI of 0x080007 and the Appletalk etype. +The exceptions are: +.RS +.TP +\fBiso\fP +\fItcpdump\fR checks the DSAP (Destination Service Access Point) and +SSAP (Source Service Access Point) fields of the LLC header; +.TP +\fBstp\fP and \fInetbeui\fP +\fItcpdump\fR checks the DSAP of the LLC header; +.TP +\fIatalk\fP +\fItcpdump\fR checks for a SNAP-format packet with an OUI of 0x080007 +and the AppleTalk etype. +.RE .IP In the case of Ethernet, \fItcpdump\fR checks the Ethernet type field -for most of those protocols; the exceptions are \fIiso\fP, \fIsap\fP, -and \fInetbeui\fP, for which it checks for an 802.3 frame and then -checks the LLC header as it does for FDDI and Token Ring, \fIatalk\fP, -where it checks both for the Appletalk etype in an Ethernet frame and -for a SNAP-format packet as it does for FDDI and Token Ring, \fIaarp\fP, -where it checks for the Appletalk ARP etype in either an Ethernet frame -or an 802.2 SNAP frame with an OUI of 0x000000, and \fIipx\fP, where it -checks for the IPX etype in an Ethernet frame, the IPX DSAP in the LLC -header, the 802.3 with no LLC header encapsulation of IPX, and the IPX -etype in a SNAP frame.] +for most of those protocols. The exceptions are: +.RS +.TP +\fBiso\fP, \fBsap\fP, and \fBnetbeui\fP +\fItcpdump\fR checks for an 802.3 frame and then checks the LLC header as +it does for FDDI, Token Ring, and 802.11; +.TP +\fBatalk\fP +\fItcpdump\fR checks both for the AppleTalk etype in an Ethernet frame and +for a SNAP-format packet as it does for FDDI, Token Ring, and 802.11; +.TP +\fBaarp\fP +\fItcpdump\fR checks for the AppleTalk ARP etype in either an Ethernet +frame or an 802.2 SNAP frame with an OUI of 0x000000; +.TP +\fBipx\fP +\fItcpdump\fR checks for the IPX etype in an Ethernet frame, the IPX +DSAP in the LLC header, the 802.3-with-no-LLC-header encapsulation of +IPX, and the IPX etype in a SNAP frame. +.RE .IP "\fBdecnet src \fIhost\fR" True if the DECNET source address is .IR host , which may be an address of the form ``10.123'', or a DECNET host name. -[DECNET host name support is only available on Ultrix systems +[DECNET host name support is only available on ULTRIX systems that are configured to run DECNET.] .IP "\fBdecnet dst \fIhost\fR" True if the DECNET destination address is @@ -739,6 +897,58 @@ True if the DECNET destination address is .IP "\fBdecnet host \fIhost\fR" True if either the DECNET source or destination address is .IR host . +.IP "\fBifname \fIinterface\fR" +True if the packet was logged as coming from the specified interface (applies +only to packets logged by OpenBSD's +.BR pf (4)). +.IP "\fBon \fIinterface\fR" +Synonymous with the +.B ifname +modifier. +.IP "\fBrnr \fInum\fR" +True if the packet was logged as matching the specified PF rule number +(applies only to packets logged by OpenBSD's +.BR pf (4)). +.IP "\fBrulenum \fInum\fR" +Synonomous with the +.B rnr +modifier. +.IP "\fBreason \fIcode\fR" +True if the packet was logged with the specified PF reason code. The known +codes are: +.BR match , +.BR bad-offset , +.BR fragment , +.BR short , +.BR normalize , +and +.B memory +(applies only to packets logged by OpenBSD's +.BR pf (4)). +.IP "\fBrset \fIname\fR" +True if the packet was logged as matching the specified PF ruleset +name of an anchored ruleset (applies only to packets logged by +.BR pf (4)). +.IP "\fBruleset \fIname\fR" +Synonomous with the +.B rset +modifier. +.IP "\fBsrnr \fInum\fR" +True if the packet was logged as matching the specified PF rule number +of an anchored ruleset (applies only to packets logged by +.BR pf (4)). +.IP "\fBsubrulenum \fInum\fR" +Synonomous with the +.B srnr +modifier. +.IP "\fBaction \fIact\fR" +True if PF took the specified action when the packet was logged. Known actions +are: +.B pass +and +.B block +(applies only to packets logged by OpenBSD's +.BR pf (4)). .IP "\fBip\fR, \fBip6\fR, \fBarp\fR, \fBrarp\fR, \fBatalk\fR, \fBaarp\fR, \fBdecnet\fR, \fBiso\fR, \fBstp\fR, \fBipx\fR, \fInetbeui\fP" Abbreviations for: .in +.5i @@ -784,12 +994,66 @@ Abbreviations for: .fi .in -.5i where \fIp\fR is one of the above protocols. -Note that \fItcpdump\fR does an incomplete job of parsing these protocols. +.IP "\fBl1\fR, \fBl2\fR, \fBiih\fR, \fBlsp\fR, \fBsnp\fR, \fBcsnp\fR, \fBpsnp\fR" +Abbreviations for IS-IS PDU types. +.IP "\fBvpi\fP \fIn\fR +True if the packet is an ATM packet, for SunATM on Solaris, with a +virtual path identifier of +.IR n . +.IP "\fBvci\fP \fIn\fR +True if the packet is an ATM packet, for SunATM on Solaris, with a +virtual channel identifier of +.IR n . +.IP \fBlane\fP +True if the packet is an ATM packet, for SunATM on Solaris, and is +an ATM LANE packet. +Note that the first \fBlane\fR keyword encountered in \fIexpression\fR +changes the tests done in the remainder of \fIexpression\fR +on the assumption that the packet is either a LANE emulated Ethernet +packet or a LANE LE Control packet. If \fBlane\fR isn't specified, the +tests are done under the assumption that the packet is an +LLC-encapsulated packet. +.IP \fBllc\fP +True if the packet is an ATM packet, for SunATM on Solaris, and is +an LLC-encapsulated packet. +.IP \fBoamf4s\fP +True if the packet is an ATM packet, for SunATM on Solaris, and is +a segment OAM F4 flow cell (VPI=0 & VCI=3). +.IP \fBoamf4e\fP +True if the packet is an ATM packet, for SunATM on Solaris, and is +an end-to-end OAM F4 flow cell (VPI=0 & VCI=4). +.IP \fBoamf4\fP +True if the packet is an ATM packet, for SunATM on Solaris, and is +a segment or end-to-end OAM F4 flow cell (VPI=0 & (VCI=3 | VCI=4)). +.IP \fBoam\fP +True if the packet is an ATM packet, for SunATM on Solaris, and is +a segment or end-to-end OAM F4 flow cell (VPI=0 & (VCI=3 | VCI=4)). +.IP \fBmetac\fP +True if the packet is an ATM packet, for SunATM on Solaris, and is +on a meta signaling circuit (VPI=0 & VCI=1). +.IP \fBbcc\fP +True if the packet is an ATM packet, for SunATM on Solaris, and is +on a broadcast signaling circuit (VPI=0 & VCI=2). +.IP \fBsc\fP +True if the packet is an ATM packet, for SunATM on Solaris, and is +on a signaling circuit (VPI=0 & VCI=5). +.IP \fBilmic\fP +True if the packet is an ATM packet, for SunATM on Solaris, and is +on an ILMI circuit (VPI=0 & VCI=16). +.IP \fBconnectmsg\fP +True if the packet is an ATM packet, for SunATM on Solaris, and is +on a signaling circuit and is a Q.2931 Setup, Call Proceeding, Connect, +Connect Ack, Release, or Release Done message. +.IP \fBmetaconnect\fP +True if the packet is an ATM packet, for SunATM on Solaris, and is +on a meta signaling circuit and is a Q.2931 Setup, Call Proceeding, Connect, +Release, or Release Done message. .IP "\fIexpr relop expr\fR" -True if the relation holds, where \fIrelop\fR is one of >, <, >=, <=, =, !=, -and \fIexpr\fR is an arithmetic expression composed of integer constants -(expressed in standard C syntax), the normal binary operators -[+, -, *, /, &, |], a length operator, and special packet data accessors. +True if the relation holds, where \fIrelop\fR is one of >, <, >=, <=, =, +!=, and \fIexpr\fR is an arithmetic expression composed of integer +constants (expressed in standard C syntax), the normal binary operators +[+, -, *, /, &, |, <<, >>], a length operator, and special packet data +accessors. To access data inside the packet, use the following syntax: .in +.5i @@ -797,9 +1061,11 @@ data inside the packet, use the following syntax: \fIproto\fB [ \fIexpr\fB : \fIsize\fB ]\fR .fi .in -.5i -\fIProto\fR is one of \fBether, fddi, tr, +\fIProto\fR is one of \fBether, fddi, tr, wlan, ppp, slip, link, ip, arp, rarp, tcp, udp, icmp\fR or \fBip6\fR, and indicates the protocol layer for the index operation. +(\fBether, fddi, wlan, tr, ppp, slip\fR and \fBlink\fR all refer to the +link layer.) Note that \fItcp, udp\fR and other upper-layer protocol types only apply to IPv4, not IPv6 (this will be fixed in the future). The byte offset, relative to the indicated protocol layer, is @@ -835,7 +1101,7 @@ The following ICMP type field values are available: \fBicmp-echoreply\fP, \fBicmp-maskreq\fP, \fBicmp-maskreply\fP. The following TCP flags field values are available: \fBtcp-fin\fP, -\fBtcp-syn\fP, \fBtcp-rst\fP, \fBtcp-push\fP, \fBtcp-push\fP, +\fBtcp-syn\fP, \fBtcp-rst\fP, \fBtcp-push\fP, \fBtcp-ack\fP, \fBtcp-urg\fP. .LP Primitives may be combined using: @@ -1005,6 +1271,12 @@ Regardless of whether the '-e' option is specified or not, the source routing information is printed for source-routed packets. .LP +On 802.11 networks, the '-e' option causes \fItcpdump\fP to print +the `frame control' fields, all of the addresses in the 802.11 header, +and the packet length. +As on FDDI networks, +packets are assumed to contain an LLC packet. +.LP \fI(N.B.: The following description assumes familiarity with the SLIP compression algorithm described in RFC-1144.)\fP .LP @@ -1099,7 +1371,8 @@ The general format of a tcp protocol line is: \fISrc\fP and \fIdst\fP are the source and destination IP addresses and ports. \fIFlags\fP are some combination of S (SYN), -F (FIN), P (PUSH) or R (RST) or a single `.' (no flags). +F (FIN), P (PUSH), R (RST), W (ECN CWR) or E (ECN-Echo), or a single +`.' (no flags). \fIData-seqno\fP describes the portion of sequence space covered by the data in this packet (see example below). \fIAck\fP is sequence number of the next data expected the other @@ -1507,10 +1780,10 @@ gory details. If you are decoding SMB sessions containing unicode strings then you may wish to set the environment variable USE_UNICODE to 1. A patch to -auto-detect unicode srings would be welcome. +auto-detect unicode strings would be welcome. For information on SMB packet formats and what all te fields mean see -www.cifs.org or the pub/samba/specs/ directory on your favourite +www.cifs.org or the pub/samba/specs/ directory on your favorite samba.org mirror site. The SMB patches were written by Andrew Tridgell (tridge@samba.org). @@ -1668,14 +1941,14 @@ follow the corresponding request, it might not be parsable. .HD -KIP Appletalk (DDP in UDP) +KIP AppleTalk (DDP in UDP) .LP -Appletalk DDP packets encapsulated in UDP datagrams are de-encapsulated +AppleTalk DDP packets encapsulated in UDP datagrams are de-encapsulated and dumped as DDP packets (i.e., all the UDP header information is discarded). The file .I /etc/atalk.names -is used to translate appletalk net and node numbers to names. +is used to translate AppleTalk net and node numbers to names. Lines in this file have the form .RS .nf @@ -1688,7 +1961,7 @@ Lines in this file have the form .sp .5 .fi .RE -The first two lines give the names of appletalk networks. +The first two lines give the names of AppleTalk networks. The third line gives the name of a particular host (a host is distinguished from a net by the 3rd octet in the number \- @@ -1700,7 +1973,7 @@ The file may contain blank lines or comment lines (lines starting with a `#'). .LP -Appletalk addresses are printed in the form +AppleTalk addresses are printed in the form .RS .nf .sp .5 @@ -1714,7 +1987,7 @@ jssmag.149.235 > icsd-net.2\fR .RE (If the .I /etc/atalk.names -doesn't exist or doesn't contain an entry for some appletalk +doesn't exist or doesn't contain an entry for some AppleTalk host/net number, addresses are printed in numeric form.) In the first example, NBP (DDP port 2) on net 144.1 node 209 is sending to whatever is listening on port 220 of net icsd node 112. @@ -1726,7 +1999,7 @@ the broadcast address (255) is indicated by a net name with no host number \- for this reason it's a good idea to keep node names and net names distinct in /etc/atalk.names). .LP -NBP (name binding protocol) and ATP (Appletalk transaction protocol) +NBP (name binding protocol) and ATP (AppleTalk transaction protocol) packets have their contents interpreted. Other protocols just dump the protocol name (or number if no name is registered for the @@ -1919,7 +2192,9 @@ will be copied from the kernel (the 2.0[.x] packet capture mechanism, if asked to copy only part of a packet to userland, will not report the true length of the packet; this would cause most IP packets to get an error from -.BR tcpdump ). +.BR tcpdump ); +.IP +capturing on some PPP devices won't work correctly. .LP We recommend that you upgrade to a 2.2 or later kernel. .LP @@ -1935,16 +2210,11 @@ prefer to fix the program generating them rather than \fItcpdump\fP. A packet trace that crosses a daylight savings time change will give skewed time stamps (the time change is ignored). .LP -Filter expressions that manipulate FDDI or Token Ring headers assume -that all FDDI and Token Ring packets are SNAP-encapsulated Ethernet -packets. -This is true for IP, ARP, and DECNET Phase IV, but is not true -for protocols such as ISO CLNS. -Therefore, the filter may inadvertently -accept certain packets that do not properly match the filter expression. +Filter expressions on fields other than those in Token Ring headers will +not correctly handle source-routed Token Ring packets. .LP -Filter expressions on fields other than those that manipulate Token Ring -headers will not correctly handle source-routed Token Ring packets. +Filter expressions on fields other than those in 802.11 headers will not +correctly handle 802.11 data packets with both To DS and From DS set. .LP .BR "ip6 proto" should chase header chain, but at this moment it does not. diff --git a/contrib/tcpdump/tcpdump.c b/contrib/tcpdump/tcpdump.c index dd39e4bf36e5..4314a1a8b390 100644 --- a/contrib/tcpdump/tcpdump.c +++ b/contrib/tcpdump/tcpdump.c @@ -26,11 +26,11 @@ */ #ifndef lint -static const char copyright[] = +static const char copyright[] _U_ = "@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\ The Regents of the University of California. All rights reserved.\n"; -static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/tcpdump.c,v 1.173 2001/12/22 22:12:23 guy Exp $ (LBL)"; +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/tcpdump.c,v 1.216.2.10 2004/03/17 19:47:48 guy Exp $ (LBL)"; #endif /* $FreeBSD$ */ @@ -47,27 +47,30 @@ static const char rcsid[] = #include "config.h" #endif -#include <sys/types.h> -#include <sys/time.h> +#include <tcpdump-stdinc.h> -#include <netinet/in.h> +#ifdef WIN32 +#include "getopt.h" +#include "w32_fzs.h" +extern int strcasecmp (const char *__s1, const char *__s2); +extern int SIZE_BUF; +#define off_t long +#define uint UINT +#endif /* WIN32 */ #include <pcap.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <unistd.h> -#include <ctype.h> - #include "interface.h" #include "addrtoname.h" #include "machdep.h" #include "setsignal.h" #include "gmt2local.h" +#include "pcap-missing.h" -int aflag; /* translate network and broadcast addresses */ int dflag; /* print filter code */ int eflag; /* print ethernet header */ int fflag; /* don't translate "foreign" IP address */ @@ -81,12 +84,14 @@ int Rflag = 1; /* print sequence # field in AH/ESP*/ int sflag = 0; /* use the libsmi to translate OIDs */ int Sflag; /* print raw TCP sequence numbers */ int tflag = 1; /* print packet arrival time */ +int Uflag = 0; /* "unbuffered" output of dump files */ int uflag = 0; /* Print undecoded NFS handles */ int vflag; /* verbose */ int xflag; /* print packet in hex */ int Xflag; /* print packet in ascii as well as hex */ off_t Cflag = 0; /* rotate dump files after this many bytes */ -int dlt = -1; /* if != -1, ask libpcap for the DLT it names */ +int Aflag = 0; /* print packet only in ascii observing LF, CR, TAB, SPACE */ +int dlt = -1; /* if != -1, ask libpcap for the DLT it names */ const char *dlt_name = NULL; @@ -94,8 +99,8 @@ char *espsecret = NULL; /* ESP secret key */ int packettype; -int infodelay; -int infoprint; +static int infodelay; +static int infoprint; char *program_name; @@ -106,22 +111,32 @@ static RETSIGTYPE cleanup(int); static void usage(void) __attribute__((noreturn)); static void show_dlts_and_exit(pcap_t *pd) __attribute__((noreturn)); -static void dump_and_trunc(u_char *, const struct pcap_pkthdr *, const u_char *); +static void print_packet(u_char *, const struct pcap_pkthdr *, const u_char *); +static void dump_packet_and_trunc(u_char *, const struct pcap_pkthdr *, const u_char *); +static void dump_packet(u_char *, const struct pcap_pkthdr *, const u_char *); #ifdef SIGINFO RETSIGTYPE requestinfo(int); #endif +static void info(int); +static u_int packets_captured; + /* Length of saved portion of packet. */ int snaplen = DEFAULT_SNAPLEN; +typedef u_int (*if_printer)(const struct pcap_pkthdr *, const u_char *); + struct printer { - pcap_handler f; + if_printer f; int type; }; static struct printer printers[] = { { arcnet_if_print, DLT_ARCNET }, +#ifdef DLT_ARCNET_LINUX + { arcnet_linux_if_print, DLT_ARCNET_LINUX }, +#endif { ether_if_print, DLT_EN10MB }, { token_if_print, DLT_IEEE802 }, #ifdef DLT_LANE8023 @@ -134,9 +149,13 @@ static struct printer printers[] = { { cip_if_print, DLT_ATM_CLIP }, #endif { sl_if_print, DLT_SLIP }, +#ifdef DLT_SLIP_BSDOS { sl_bsdos_if_print, DLT_SLIP_BSDOS }, +#endif { ppp_if_print, DLT_PPP }, +#ifdef DLT_PPP_BSDOS { ppp_bsdos_if_print, DLT_PPP_BSDOS }, +#endif { fddi_if_print, DLT_FDDI }, { null_if_print, DLT_NULL }, #ifdef DLT_LOOP @@ -165,10 +184,37 @@ static struct printer printers[] = { #ifdef DLT_LTALK { ltalk_if_print, DLT_LTALK }, #endif +#ifdef DLT_PFLOG + { pflog_if_print, DLT_PFLOG }, +#endif +#ifdef DLT_FR + { fr_if_print, DLT_FR }, +#endif +#ifdef DLT_FRELAY + { fr_if_print, DLT_FRELAY }, +#endif +#ifdef DLT_SUNATM + { sunatm_if_print, DLT_SUNATM }, +#endif +#ifdef DLT_IP_OVER_FC + { ipfc_if_print, DLT_IP_OVER_FC }, +#endif +#ifdef DLT_PRISM_HEADER + { prism_if_print, DLT_PRISM_HEADER }, +#endif +#ifdef DLT_IEEE802_11_RADIO + { ieee802_11_radio_if_print, DLT_IEEE802_11_RADIO }, +#endif +#ifdef DLT_ENC + { enc_if_print, DLT_ENC }, +#endif +#ifdef DLT_APPLE_IP_OVER_IEEE1394 + { ap1394_if_print, DLT_APPLE_IP_OVER_IEEE1394 }, +#endif { NULL, 0 }, }; -static pcap_handler +static if_printer lookup_printer(int type) { struct printer *p; @@ -177,7 +223,7 @@ lookup_printer(int type) if (type == p->type) return p->f; - error("unknown data link type %d", type); + return NULL; /* NOTREACHED */ } @@ -187,112 +233,101 @@ extern int optind; extern int opterr; extern char *optarg; +struct print_info { + if_printer printer; +}; + struct dump_info { char *WFileName; pcap_t *pd; pcap_dumper_t *p; }; -struct dlt_choice { - const char* name; - int dlt; -}; - -#define DLT_CHOICE(code) { #code, code } -#define DLT_CHOICE_SENTINEL { NULL, 0 } - -struct dlt_choice dlt_choices[] = { - DLT_CHOICE(DLT_ARCNET), - DLT_CHOICE(DLT_EN10MB), - DLT_CHOICE(DLT_IEEE802), -#ifdef DLT_LANE8023 - DLT_CHOICE(DLT_LANE8023), -#endif -#ifdef DLT_CIP - DLT_CHOICE(DLT_CIP), -#endif -#ifdef DLT_ATM_CLIP - DLT_CHOICE(DLT_ATM_CLIP), -#endif - DLT_CHOICE(DLT_SLIP), - DLT_CHOICE(DLT_SLIP_BSDOS), - DLT_CHOICE(DLT_PPP), - DLT_CHOICE(DLT_PPP_BSDOS), - DLT_CHOICE(DLT_FDDI), - DLT_CHOICE(DLT_NULL), -#ifdef DLT_LOOP - DLT_CHOICE(DLT_LOOP), -#endif - DLT_CHOICE(DLT_RAW), - DLT_CHOICE(DLT_ATM_RFC1483), -#ifdef DLT_C_HDLC - DLT_CHOICE(DLT_C_HDLC), -#endif -#ifdef DLT_HDLC - DLT_CHOICE(DLT_HDLC), -#endif -#ifdef DLT_PPP_SERIAL - DLT_CHOICE(DLT_PPP_SERIAL), -#endif -#ifdef DLT_PPP_ETHER - DLT_CHOICE(DLT_PPP_ETHER), -#endif -#ifdef DLT_LINUX_SLL - DLT_CHOICE(DLT_LINUX_SLL), -#endif -#ifdef DLT_IEEE802_11 - DLT_CHOICE(DLT_IEEE802_11), -#endif -#ifdef DLT_LTALK - DLT_CHOICE(DLT_LTALK), -#endif -#ifdef DLT_PFLOG - DLT_CHOICE(DLT_PFLOG), -#endif - DLT_CHOICE_SENTINEL -}; - static void show_dlts_and_exit(pcap_t *pd) { - int i, n_dlts; + int n_dlts; int *dlts = 0; + const char *dlt_name; + n_dlts = pcap_list_datalinks(pd, &dlts); if (n_dlts < 0) error("%s", pcap_geterr(pd)); else if (n_dlts == 0 || !dlts) error("No data link types."); - (void) fprintf(stderr, "Data link types (use option -y):\n"); + (void) fprintf(stderr, "Data link types (use option -y to set):\n"); while (--n_dlts >= 0) { - for (i = 0; dlt_choices[i].name; i++) { - if (dlt_choices[i].dlt != dlts[n_dlts]) { - continue; - } - (void) fprintf(stderr, " %s\n", - dlt_choices[i].name + sizeof("DLT_") - 1); - break; + dlt_name = pcap_datalink_val_to_name(dlts[n_dlts]); + if (dlt_name != NULL) { + (void) fprintf(stderr, " %s (%s)", dlt_name, + pcap_datalink_val_to_description(dlts[n_dlts])); + + /* + * OK, does tcpdump handle that type? + */ + if (lookup_printer(dlts[n_dlts]) == NULL) + (void) fprintf(stderr, " (not supported)"); + putchar('\n'); + } else { + (void) fprintf(stderr, " DLT %d (not supported)\n", + dlts[n_dlts]); } - if (!dlt_choices[i].name) - fprintf(stderr, " %d (not supported)\n", dlts[n_dlts]); } free(dlts); exit(0); } +/* + * Set up flags that might or might not be supported depending on the + * version of libpcap we're using. + */ +#ifdef WIN32 +#define B_FLAG "B:" +#define B_FLAG_USAGE " [ -B size ]" +#else /* WIN32 */ +#define B_FLAG +#define B_FLAG_USAGE +#endif /* WIN32 */ + +#ifdef HAVE_PCAP_FINDALLDEVS +#define D_FLAG "D" +#else +#define D_FLAG +#endif + +#ifdef HAVE_PCAP_DUMP_FLUSH +#define U_FLAG "U" +#else +#define U_FLAG +#endif + int main(int argc, char **argv) { register int cnt, op, i; bpf_u_int32 localnet, netmask; register char *cp, *infile, *cmdbuf, *device, *RFileName, *WFileName; - pcap_handler printer; + pcap_handler callback; + int type; struct bpf_program fcode; +#ifndef WIN32 RETSIGTYPE (*oldhandler)(int); +#endif + struct print_info printinfo; struct dump_info dumpinfo; u_char *pcap_userdata; char ebuf[PCAP_ERRBUF_SIZE]; +#ifdef HAVE_PCAP_FINDALLDEVS + pcap_if_t *devpointer; + int devnum; +#endif + int status; +#ifdef WIN32 + u_int UserBufferSize = 1000000; + if(wsockinit() != 0) return 1; +#endif /* WIN32 */ cnt = -1; device = NULL; @@ -310,15 +345,29 @@ main(int argc, char **argv) #ifdef LIBSMI smiInit("tcpdump"); #endif - + opterr = 0; while ( - (op = getopt(argc, argv, "ac:C:deE:fF:i:lLm:nNOpqr:Rs:StT:uvw:xXy:Y")) != -1) + (op = getopt(argc, argv, "aA" B_FLAG "c:C:d" D_FLAG "eE:fF:i:lLm:nNOpqr:Rs:StT:u" U_FLAG "vw:xXy:Y")) != -1) switch (op) { case 'a': - ++aflag; + /* compatibility for old -a */ + break; + + case 'A': + ++xflag; + ++Xflag; + ++Aflag; + break; + +#ifdef WIN32 + case 'B': + UserBufferSize = atoi(optarg)*1024; + if (UserBufferSize < 0) + error("invalid packet buffer size %s", optarg); break; +#endif /* WIN32 */ case 'c': cnt = atoi(optarg); @@ -328,7 +377,7 @@ main(int argc, char **argv) case 'C': Cflag = atoi(optarg) * 1000000; - if (Cflag < 0) + if (Cflag < 0) error("invalid file size %s", optarg); break; @@ -336,6 +385,22 @@ main(int argc, char **argv) ++dflag; break; +#ifdef HAVE_PCAP_FINDALLDEVS + case 'D': + if (pcap_findalldevs(&devpointer, ebuf) < 0) + error("%s", ebuf); + else { + for (i = 0; devpointer != 0; i++) { + printf("%d.%s", i+1, devpointer->name); + if (devpointer->description != NULL) + printf(" (%s)", devpointer->description); + printf("\n"); + devpointer = devpointer->next; + } + } + return 0; +#endif /* HAVE_PCAP_FINDALLDEVS */ + case 'L': Lflag++; break; @@ -360,15 +425,59 @@ main(int argc, char **argv) break; case 'i': + if (optarg[0] == '0' && optarg[1] == 0) + error("Invalid adapter index"); + +#ifdef HAVE_PCAP_FINDALLDEVS + /* + * If the argument is a number, treat it as + * an index into the list of adapters, as + * printed by "tcpdump -D". + * + * This should be OK on UNIX systems, as interfaces + * shouldn't have names that begin with digits. + * It can be useful on Windows, where more than + * one interface can have the same name. + */ + if ((devnum = atoi(optarg)) != 0) { + if (devnum < 0) + error("Invalid adapter index"); + + if (pcap_findalldevs(&devpointer, ebuf) < 0) + error("%s", ebuf); + else { + for (i = 0; i < devnum-1; i++){ + devpointer = devpointer->next; + if (devpointer == NULL) + error("Invalid adapter index"); + } + } + device = devpointer->name; + break; + } +#endif /* HAVE_PCAP_FINDALLDEVS */ device = optarg; break; case 'l': +#ifdef WIN32 + /* + * _IOLBF is the same as _IOFBF in Microsoft's C + * libraries; the only alternative they offer + * is _IONBF. + * + * XXX - this should really be checking for MSVC++, + * not WIN32, if, for example, MinGW has its own + * C library that is more UNIX-compatible. + */ + setvbuf(stdout, NULL, _IONBF, 0); +#else /* WIN32 */ #ifdef HAVE_SETLINEBUF setlinebuf(stdout); #else setvbuf(stdout, NULL, _IOLBF, 0); #endif +#endif /* WIN32 */ break; case 'n': @@ -390,7 +499,8 @@ main(int argc, char **argv) program_name, optarg); (void)fprintf(stderr, "(no libsmi support)\n"); #endif - + break; + case 'O': Oflag = 0; break; @@ -446,6 +556,10 @@ main(int argc, char **argv) packettype = PT_SNMP; else if (strcasecmp(optarg, "cnfp") == 0) packettype = PT_CNFP; + else if (strcasecmp(optarg, "tftp") == 0) + packettype = PT_TFTP; + else if (strcasecmp(optarg, "aodv") == 0) + packettype = PT_AODV; else error("unknown packet type `%s'", optarg); break; @@ -453,7 +567,13 @@ main(int argc, char **argv) case 'u': ++uflag; break; - + +#ifdef HAVE_PCAP_DUMP_FLUSH + case 'U': + ++Uflag; + break; +#endif + case 'v': ++vflag; break; @@ -467,31 +587,28 @@ main(int argc, char **argv) break; case 'X': - ++xflag; + ++xflag; ++Xflag; break; case 'y': - for (i = 0; dlt_choices[i].name; i++) { - if (!strcasecmp(dlt_choices[i].name + - sizeof("DLT_") - 1, - optarg)) { - dlt = dlt_choices[i].dlt; - dlt_name = dlt_choices[i].name; - break; - } - } - if (dlt < 0) { - error("invalid data link type %s", optarg); - } + dlt_name = optarg; + dlt = pcap_datalink_name_to_val(dlt_name); + if (dlt < 0) + error("invalid data link type %s", dlt_name); break; -#ifdef YYDEBUG +#if defined(HAVE_PCAP_DEBUG) || defined(HAVE_YYDEBUG) case 'Y': { /* Undocumented flag */ +#ifdef HAVE_PCAP_DEBUG + extern int pcap_debug; + pcap_debug = 1; +#else extern int yydebug; yydebug = 1; +#endif } break; #endif @@ -500,23 +617,39 @@ main(int argc, char **argv) /* NOTREACHED */ } - if (aflag && nflag) - error("-a and -n options are incompatible"); - if (tflag > 0) thiszone = gmt2local(0); if (RFileName != NULL) { + int dlt; + const char *dlt_name; + +#ifndef WIN32 /* - * We don't need network access, so set it back to the user id. - * Also, this prevents the user from reading anyone's - * trace file. + * We don't need network access, so relinquish any set-UID + * or set-GID privileges we have (if any). + * + * We do *not* want set-UID privileges when opening a + * trace file, as that might let the user read other + * people's trace files (especially if we're set-UID + * root). */ setuid(getuid()); - +#endif /* WIN32 */ pd = pcap_open_offline(RFileName, ebuf); if (pd == NULL) error("%s", ebuf); + dlt = pcap_datalink(pd); + dlt_name = pcap_datalink_val_to_name(dlt); + if (dlt_name == NULL) { + fprintf(stderr, "reading from file %s, link-type %u\n", + RFileName, dlt); + } else { + fprintf(stderr, + "reading from file %s, link-type %s (%s)\n", + RFileName, dlt_name, + pcap_datalink_val_to_description(dlt)); + } localnet = 0; netmask = 0; if (fflag != 0) @@ -527,18 +660,44 @@ main(int argc, char **argv) if (device == NULL) error("%s", ebuf); } +#ifdef WIN32 + if(IsTextUnicode(device, + wcslen((short*)device), // Device always ends with a double \0, so this way to determine its + // length should be always valid + NULL)) + { + fprintf(stderr, "%s: listening on %ws\n", program_name, device); + } + else + { + fprintf(stderr, "%s: listening on %s\n", program_name, device); + } + + fflush(stderr); +#endif /* WIN32 */ *ebuf = '\0'; pd = pcap_open_live(device, snaplen, !pflag, 1000, ebuf); if (pd == NULL) error("%s", ebuf); else if (*ebuf) warning("%s", ebuf); - if (Lflag) { + if (Lflag) show_dlts_and_exit(pd); - } if (dlt >= 0) { +#ifdef HAVE_PCAP_SET_DATALINK if (pcap_set_datalink(pd, dlt) < 0) error("%s", pcap_geterr(pd)); +#else + /* + * We don't actually support changing the + * data link type, so we only let them + * set it to what it already is. + */ + if (dlt != pcap_datalink(pd)) { + error("%s is not one of the DLTs supported by this device\n", + dlt_name); + } +#endif (void)fprintf(stderr, "%s: data link type %s\n", program_name, dlt_name); (void)fflush(stderr); @@ -556,7 +715,9 @@ main(int argc, char **argv) /* * Let user own process after socket has been opened. */ +#ifndef WIN32 setuid(getuid()); +#endif /* WIN32 */ } if (infile) cmdbuf = read_infile(infile); @@ -567,15 +728,21 @@ main(int argc, char **argv) error("%s", pcap_geterr(pd)); if (dflag) { bpf_dump(&fcode, dflag); + pcap_close(pd); exit(0); } init_addrtoname(localnet, netmask); +#ifndef WIN32 + (void)setsignal(SIGPIPE, cleanup); +#endif /* WIN32 */ (void)setsignal(SIGTERM, cleanup); (void)setsignal(SIGINT, cleanup); /* Cooperate with nohup(1) */ +#ifndef WIN32 if ((oldhandler = setsignal(SIGHUP, cleanup)) != SIG_DFL) (void)setsignal(SIGHUP, oldhandler); +#endif /* WIN32 */ if (pcap_setfilter(pd, &fcode) < 0) error("%s", pcap_geterr(pd)); @@ -584,53 +751,123 @@ main(int argc, char **argv) if (p == NULL) error("%s", pcap_geterr(pd)); if (Cflag != 0) { - printer = dump_and_trunc; + callback = dump_packet_and_trunc; dumpinfo.WFileName = WFileName; dumpinfo.pd = pd; dumpinfo.p = p; pcap_userdata = (u_char *)&dumpinfo; } else { - printer = pcap_dump; + callback = dump_packet; pcap_userdata = (u_char *)p; } } else { - printer = lookup_printer(pcap_datalink(pd)); - pcap_userdata = 0; + type = pcap_datalink(pd); + printinfo.printer = lookup_printer(type); + if (printinfo.printer == NULL) { + dlt_name = pcap_datalink_val_to_name(type); + if (dlt_name != NULL) + error("unsupported data link type %s", dlt_name); + else + error("unsupported data link type %d", type); + } + callback = print_packet; + pcap_userdata = (u_char *)&printinfo; + } #ifdef SIGINFO - (void)setsignal(SIGINFO, requestinfo); + (void)setsignal(SIGINFO, requestinfo); #endif - } +#ifndef WIN32 if (RFileName == NULL) { - (void)fprintf(stderr, "%s: listening on %s\n", - program_name, device); + int dlt; + const char *dlt_name; + + if (!vflag && !WFileName) { + (void)fprintf(stderr, + "%s: verbose output suppressed, use -v or -vv for full protocol decode\n", + program_name); + } else + (void)fprintf(stderr, "%s: ", program_name); + dlt = pcap_datalink(pd); + dlt_name = pcap_datalink_val_to_name(dlt); + if (dlt_name == NULL) { + (void)fprintf(stderr, "listening on %s, link-type %u, capture size %u bytes\n", + device, dlt, snaplen); + } else { + (void)fprintf(stderr, "listening on %s, link-type %s (%s), capture size %u bytes\n", + device, dlt_name, + pcap_datalink_val_to_description(dlt), snaplen); + } (void)fflush(stderr); } - if (pcap_loop(pd, cnt, printer, pcap_userdata) < 0) { +#endif /* WIN32 */ + status = pcap_loop(pd, cnt, callback, pcap_userdata); + if (WFileName == NULL) { + /* + * We're printing packets. Flush the printed output, + * so it doesn't get intermingled with error output. + */ + if (status == -2) { + /* + * We got interrupted, so perhaps we didn't + * manage to finish a line we were printing. + * Print an extra newline, just in case. + */ + putchar('\n'); + } + (void)fflush(stdout); + } + if (status == -1) { + /* + * Error. Report it. + */ (void)fprintf(stderr, "%s: pcap_loop: %s\n", program_name, pcap_geterr(pd)); - exit(1); } - if (RFileName == NULL) + if (RFileName == NULL) { + /* + * We're doing a live capture. Report the capture + * statistics. + */ info(1); + } pcap_close(pd); - exit(0); + exit(status == -1 ? 1 : 0); } /* make a clean exit on interrupts */ static RETSIGTYPE -cleanup(int signo) +cleanup(int signo _U_) { - - /* Can't print the summary if reading from a savefile */ +#ifdef HAVE_PCAP_BREAKLOOP + /* + * We have "pcap_breakloop()"; use it, so that we do as little + * as possible in the signal handler (it's probably not safe + * to do anything with standard I/O streams in a signal handler - + * the ANSI C standard doesn't say it is). + */ + pcap_breakloop(pd); +#else + /* + * We don't have "pcap_breakloop()"; this isn't safe, but + * it's the best we can do. Print the summary if we're + * not reading from a savefile - i.e., if we're doing a + * live capture - and exit. + */ if (pd != NULL && pcap_file(pd) == NULL) { + /* + * We got interrupted, so perhaps we didn't + * manage to finish a line we were printing. + * Print an extra newline, just in case. + */ + putchar('\n'); (void)fflush(stdout); - putc('\n', stderr); info(1); } exit(0); +#endif } -void +static void info(register int verbose) { struct pcap_stat stat; @@ -639,8 +876,15 @@ info(register int verbose) (void)fprintf(stderr, "pcap_stats: %s\n", pcap_geterr(pd)); return; } + if (!verbose) fprintf(stderr, "%s: ", program_name); + + (void)fprintf(stderr, "%u packets captured", packets_captured); + if (!verbose) + fputs(", ", stderr); + else + putc('\n', stderr); (void)fprintf(stderr, "%d packets received by filter", stat.ps_recv); if (!verbose) fputs(", ", stderr); @@ -678,73 +922,156 @@ swebitoa(unsigned int n, char *s) } static void -dump_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) +dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) { - struct dump_info *info; + struct dump_info *dump_info; static uint cnt = 2; char *name; - info = (struct dump_info *)user; - + ++packets_captured; + + ++infodelay; + + dump_info = (struct dump_info *)user; + /* * XXX - this won't prevent capture files from getting * larger than Cflag - the last packet written to the * file could put it over Cflag. */ - if (ftell((FILE *)info->p) > Cflag) { - name = (char *) malloc(strlen(info->WFileName) + 4); + if (ftell((FILE *)dump_info->p) > Cflag) { + /* + * Close the current file and open a new one. + */ + pcap_dump_close(dump_info->p); + if (cnt >= 1000) + error("too many output files"); + name = (char *) malloc(strlen(dump_info->WFileName) + 4); if (name == NULL) - error("dump_and_trunc: malloc"); - strcpy(name, info->WFileName); - swebitoa(cnt, name + strlen(info->WFileName)); + error("dump_packet_and_trunc: malloc"); + strcpy(name, dump_info->WFileName); + swebitoa(cnt, name + strlen(dump_info->WFileName)); cnt++; - pcap_dump_close(info->p); - info->p = pcap_dump_open(info->pd, name); + dump_info->p = pcap_dump_open(dump_info->pd, name); free(name); - if (info->p == NULL) + if (dump_info->p == NULL) error("%s", pcap_geterr(pd)); } - pcap_dump((u_char *)info->p, h, sp); + pcap_dump((u_char *)dump_info->p, h, sp); +#ifdef HAVE_PCAP_DUMP_FLUSH + if (Uflag) + pcap_dump_flush(dump_info->p); +#endif + + --infodelay; + if (infoprint) + info(0); } -/* Like default_print() but data need not be aligned */ -void -default_print_unaligned(register const u_char *cp, register u_int length) +static void +dump_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) { - register u_int i, s; - register int nshorts; + ++packets_captured; - if (Xflag) { - ascii_print(cp, length); - return; - } - nshorts = (u_int) length / sizeof(u_short); - i = 0; - while (--nshorts >= 0) { - if ((i++ % 8) == 0) - (void)printf("\n\t\t\t"); - s = *cp++; - (void)printf(" %02x%02x", s, *cp++); - } - if (length & 1) { - if ((i % 8) == 0) - (void)printf("\n\t\t\t"); - (void)printf(" %02x", *cp); + ++infodelay; + + pcap_dump(user, h, sp); +#ifdef HAVE_PCAP_DUMP_FLUSH + if (Uflag) + pcap_dump_flush((pcap_dumper_t *)user); +#endif + + --infodelay; + if (infoprint) + info(0); +} + +static void +print_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) +{ + struct print_info *print_info; + u_int hdrlen; + + ++packets_captured; + + ++infodelay; + ts_print(&h->ts); + + print_info = (struct print_info *)user; + + /* + * Some printers want to check that they're not walking off the + * end of the packet. + * Rather than pass it all the way down, we set this global. + */ + snapend = sp + h->caplen; + + hdrlen = (*print_info->printer)(h, sp); + if (xflag) { + /* + * Print the raw packet data. + */ + if (xflag > 1) { + /* + * Include the link-layer header. + */ + default_print(sp, h->caplen); + } else { + /* + * Don't include the link-layer header - and if + * we have nothing past the link-layer header, + * print nothing. + */ + if (h->caplen > hdrlen) + default_print(sp + hdrlen, + h->caplen - hdrlen); + } } + + putchar('\n'); + + --infodelay; + if (infoprint) + info(0); } +#ifdef WIN32 + /* + * XXX - there should really be libpcap calls to get the version + * number as a string (the string would be generated from #defines + * at run time, so that it's not generated from string constants + * in the library, as, on many UNIX systems, those constants would + * be statically linked into the application executable image, and + * would thus reflect the version of libpcap on the system on + * which the application was *linked*, not the system on which it's + * *running*. + * + * That routine should be documented, unlike the "version[]" + * string, so that UNIX vendors providing their own libpcaps + * don't omit it (as a couple of vendors have...). + * + * Packet.dll should perhaps also export a routine to return the + * version number of the Packet.dll code, to supply the + * "Wpcap_version" information on Windows. + */ + char WDversion[]="current-cvs.tcpdump.org"; + char version[]="current-cvs.tcpdump.org"; + char pcap_version[]="current-cvs.tcpdump.org"; + char Wpcap_version[]="3.0 alpha"; +#endif + /* - * By default, print the packet out in hex. + * By default, print the specified data out in hex. */ void default_print(register const u_char *bp, register u_int length) { - default_print_unaligned(bp, length); + ascii_print("\n\t", bp, length); /* pass on lf and identation string */ } #ifdef SIGINFO -RETSIGTYPE requestinfo(int signo) +RETSIGTYPE requestinfo(int signo _U_) { if (infodelay) ++infoprint; @@ -757,16 +1084,32 @@ static void usage(void) { extern char version[]; +#ifndef HAVE_PCAP_LIB_VERSION +#if defined(WIN32) || defined(HAVE_PCAP_VERSION) extern char pcap_version[]; +#else /* defined(WIN32) || defined(HAVE_PCAP_VERSION) */ + static char pcap_version[] = "unknown"; +#endif /* defined(WIN32) || defined(HAVE_PCAP_VERSION) */ +#endif /* HAVE_PCAP_LIB_VERSION */ +#ifdef HAVE_PCAP_LIB_VERSION + (void)fprintf(stderr, "%s version %s\n", program_name, version); + (void)fprintf(stderr, "%s\n", pcap_lib_version()); +#else /* HAVE_PCAP_LIB_VERSION */ +#ifdef WIN32 + (void)fprintf(stderr, "%s version %s, based on tcpdump version %s\n", program_name, WDversion, version); + (void)fprintf(stderr, "WinPcap version %s, based on libpcap version %s\n",Wpcap_version, pcap_version); +#else /* WIN32 */ (void)fprintf(stderr, "%s version %s\n", program_name, version); (void)fprintf(stderr, "libpcap version %s\n", pcap_version); +#endif /* WIN32 */ +#endif /* HAVE_PCAP_LIB_VERSION */ (void)fprintf(stderr, -"Usage: %s [-adeflLnNOpqRStuvxX] [ -c count ] [ -C file_size ]\n", program_name); +"Usage: %s [-aAd" D_FLAG "eflLnNOpqRStu" U_FLAG "vxX]" B_FLAG_USAGE " [-c count] [ -C file_size ]\n", program_name); (void)fprintf(stderr, -"\t\t[ -F file ] [ -i interface ] [ -r file ] [ -s snaplen ]\n"); +"\t\t[ -E algo:secret ] [ -F file ] [ -i interface ] [ -r file ]\n"); (void)fprintf(stderr, -"\t\t[ -T type ] [ -w file ] [ -E algo:secret ] [ -y datalinktype ]\n"); +"\t\t[ -s snaplen ] [ -T type ] [ -w file ] [ -y datalinktype ]\n"); (void)fprintf(stderr, "\t\t[ expression ]\n"); exit(1); diff --git a/contrib/tcpdump/token.h b/contrib/tcpdump/token.h index 1e9bd4faa525..e466c843630f 100644 --- a/contrib/tcpdump/token.h +++ b/contrib/tcpdump/token.h @@ -1,4 +1,4 @@ -/* @(#) $Header: /tcpdump/master/tcpdump/token.h,v 1.3 2000/10/03 02:55:03 itojun Exp $ (LBL) */ +/* @(#) $Header: /tcpdump/master/tcpdump/token.h,v 1.6 2002/12/11 07:14:12 guy Exp $ (LBL) */ /* * Copyright (c) 1998, Larry Lile * All rights reserved. @@ -41,7 +41,7 @@ #define LARGEST_FRAME(trp) ((ntohs((trp)->token_rcf) & 0x0070) >> 4) #define RING_NUMBER(trp, x) ((ntohs((trp)->token_rseg[x]) & 0xfff0) >> 4) #define BRIDGE_NUMBER(trp, x) ((ntohs((trp)->token_rseg[x]) & 0x000f)) -#define SEGMENT_COUNT(trp) ((RIF_LENGTH(trp) - 2) / 2) +#define SEGMENT_COUNT(trp) ((int)((RIF_LENGTH(trp) - 2) / 2)) struct token_header { u_int8_t token_ac; |