117680Spst/* 217680Spst * Copyright (c) 1994, 1995, 1996 317680Spst * The Regents of the University of California. All rights reserved. 417680Spst * 517680Spst * Redistribution and use in source and binary forms, with or without 617680Spst * modification, are permitted provided that: (1) source code distributions 717680Spst * retain the above copyright notice and this paragraph in its entirety, (2) 817680Spst * distributions including binary code include the above copyright notice and 917680Spst * this paragraph in its entirety in the documentation or other materials 1017680Spst * provided with the distribution, and (3) all advertising materials mentioning 1117680Spst * features or use of this software display the following acknowledgement: 1217680Spst * ``This product includes software developed by the University of California, 1317680Spst * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 1417680Spst * the University nor the names of its contributors may be used to endorse 1517680Spst * or promote products derived from this software without specific prior 1617680Spst * written permission. 1717680Spst * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 1817680Spst * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 1917680Spst * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 2026183Sfenner * 2117680Spst * Format and print Novell IPX packets. 2217680Spst * Contributed by Brad Parker (brad@fcr.com). 2356896Sfenner * 2456896Sfenner * $FreeBSD$ 2517680Spst */ 2626183Sfenner 2717680Spst#ifndef lint 28127675Sbmsstatic const char rcsid[] _U_ = 29190207Srpaulo "@(#) $Header: /tcpdump/master/tcpdump/print-ipx.c,v 1.42 2005-05-06 08:26:44 guy Exp $"; 3017680Spst#endif 3117680Spst 3256896Sfenner#ifdef HAVE_CONFIG_H 3356896Sfenner#include "config.h" 3456896Sfenner#endif 3556896Sfenner 36127675Sbms#include <tcpdump-stdinc.h> 3717680Spst 3817680Spst#include <stdlib.h> 3917680Spst#include <stdio.h> 4017680Spst#include <string.h> 4117680Spst 4217680Spst#include "interface.h" 4317680Spst#include "addrtoname.h" 4417680Spst#include "ipx.h" 4517680Spst#include "extract.h" 4617680Spst 4717680Spst 4817680Spststatic const char *ipxaddr_string(u_int32_t, const u_char *); 4917680Spstvoid ipx_decode(const struct ipxHdr *, const u_char *, u_int); 5017680Spstvoid ipx_sap_print(const u_short *, u_int); 5117680Spstvoid ipx_rip_print(const u_short *, u_int); 5217680Spst 5317680Spst/* 5417680Spst * Print IPX datagram packets. 5517680Spst */ 5617680Spstvoid 5717680Spstipx_print(const u_char *p, u_int length) 5817680Spst{ 5917680Spst const struct ipxHdr *ipx = (const struct ipxHdr *)p; 6017680Spst 61146778Ssam if (!eflag) 62146778Ssam printf("IPX "); 63146778Ssam 6417680Spst TCHECK(ipx->srcSkt); 65127675Sbms (void)printf("%s.%04x > ", 6617680Spst ipxaddr_string(EXTRACT_32BITS(ipx->srcNet), ipx->srcNode), 6717680Spst EXTRACT_16BITS(&ipx->srcSkt)); 6817680Spst 69146778Ssam (void)printf("%s.%04x: ", 7017680Spst ipxaddr_string(EXTRACT_32BITS(ipx->dstNet), ipx->dstNode), 7117680Spst EXTRACT_16BITS(&ipx->dstSkt)); 7217680Spst 7317680Spst /* take length from ipx header */ 7417680Spst TCHECK(ipx->length); 7517680Spst length = EXTRACT_16BITS(&ipx->length); 7617680Spst 7717680Spst ipx_decode(ipx, (u_char *)ipx + ipxSize, length - ipxSize); 7817680Spst return; 7917680Spsttrunc: 8017680Spst printf("[|ipx %d]", length); 8117680Spst} 8217680Spst 8317680Spststatic const char * 8417680Spstipxaddr_string(u_int32_t net, const u_char *node) 8517680Spst{ 8617680Spst static char line[256]; 8717680Spst 88127675Sbms snprintf(line, sizeof(line), "%08x.%02x:%02x:%02x:%02x:%02x:%02x", 8917680Spst net, node[0], node[1], node[2], node[3], node[4], node[5]); 9017680Spst 9117680Spst return line; 9217680Spst} 9317680Spst 9417680Spstvoid 9517680Spstipx_decode(const struct ipxHdr *ipx, const u_char *datap, u_int length) 9617680Spst{ 9717680Spst register u_short dstSkt; 9817680Spst 9917680Spst dstSkt = EXTRACT_16BITS(&ipx->dstSkt); 10017680Spst switch (dstSkt) { 10117680Spst case IPX_SKT_NCP: 102146778Ssam (void)printf("ipx-ncp %d", length); 10317680Spst break; 10417680Spst case IPX_SKT_SAP: 10517680Spst ipx_sap_print((u_short *)datap, length); 10617680Spst break; 10717680Spst case IPX_SKT_RIP: 10817680Spst ipx_rip_print((u_short *)datap, length); 10917680Spst break; 11017680Spst case IPX_SKT_NETBIOS: 111146778Ssam (void)printf("ipx-netbios %d", length); 11298527Sfenner#ifdef TCPDUMP_DO_SMB 11398527Sfenner ipx_netbios_print(datap, length); 11498527Sfenner#endif 11517680Spst break; 11617680Spst case IPX_SKT_DIAGNOSTICS: 117146778Ssam (void)printf("ipx-diags %d", length); 11817680Spst break; 11998527Sfenner case IPX_SKT_NWLINK_DGM: 120146778Ssam (void)printf("ipx-nwlink-dgm %d", length); 12198527Sfenner#ifdef TCPDUMP_DO_SMB 12298527Sfenner ipx_netbios_print(datap, length); 12398527Sfenner#endif 12498527Sfenner break; 12598527Sfenner case IPX_SKT_EIGRP: 126146778Ssam eigrp_print(datap, length); 12798527Sfenner break; 12817680Spst default: 129146778Ssam (void)printf("ipx-#%x %d", dstSkt, length); 13017680Spst break; 13117680Spst } 13217680Spst} 13317680Spst 13417680Spstvoid 13517680Spstipx_sap_print(const u_short *ipx, u_int length) 13617680Spst{ 13717680Spst int command, i; 13817680Spst 13917680Spst TCHECK(ipx[0]); 14017680Spst command = EXTRACT_16BITS(ipx); 14117680Spst ipx++; 14217680Spst length -= 2; 14317680Spst 14417680Spst switch (command) { 14517680Spst case 1: 14617680Spst case 3: 14717680Spst if (command == 1) 14817680Spst (void)printf("ipx-sap-req"); 14917680Spst else 15017680Spst (void)printf("ipx-sap-nearest-req"); 15117680Spst 15298527Sfenner TCHECK(ipx[0]); 153127675Sbms (void)printf(" %s", ipxsap_string(htons(EXTRACT_16BITS(&ipx[0])))); 15417680Spst break; 15517680Spst 15617680Spst case 2: 15717680Spst case 4: 15817680Spst if (command == 2) 15917680Spst (void)printf("ipx-sap-resp"); 16017680Spst else 16117680Spst (void)printf("ipx-sap-nearest-resp"); 16217680Spst 16317680Spst for (i = 0; i < 8 && length > 0; i++) { 164147904Ssam TCHECK(ipx[0]); 165147904Ssam (void)printf(" %s '", ipxsap_string(htons(EXTRACT_16BITS(&ipx[0])))); 166147904Ssam if (fn_printzp((u_char *)&ipx[1], 48, snapend)) { 167147904Ssam printf("'"); 168147904Ssam goto trunc; 169147904Ssam } 17098527Sfenner TCHECK2(ipx[25], 10); 17117680Spst printf("' addr %s", 17217680Spst ipxaddr_string(EXTRACT_32BITS(&ipx[25]), (u_char *)&ipx[27])); 17317680Spst ipx += 32; 17417680Spst length -= 64; 17517680Spst } 17617680Spst break; 17717680Spst default: 17898527Sfenner (void)printf("ipx-sap-?%x", command); 17917680Spst break; 18017680Spst } 18198527Sfenner return; 18217680Spsttrunc: 18398527Sfenner printf("[|ipx %d]", length); 18417680Spst} 18517680Spst 18617680Spstvoid 18717680Spstipx_rip_print(const u_short *ipx, u_int length) 18817680Spst{ 18917680Spst int command, i; 19017680Spst 19117680Spst TCHECK(ipx[0]); 19217680Spst command = EXTRACT_16BITS(ipx); 19317680Spst ipx++; 19417680Spst length -= 2; 19517680Spst 19617680Spst switch (command) { 19717680Spst case 1: 19817680Spst (void)printf("ipx-rip-req"); 19917680Spst if (length > 0) { 20017680Spst TCHECK(ipx[3]); 201235530Sdelphij (void)printf(" %08x/%d.%d", EXTRACT_32BITS(&ipx[0]), 20217680Spst EXTRACT_16BITS(&ipx[2]), EXTRACT_16BITS(&ipx[3])); 20317680Spst } 20417680Spst break; 20517680Spst case 2: 20617680Spst (void)printf("ipx-rip-resp"); 20717680Spst for (i = 0; i < 50 && length > 0; i++) { 20817680Spst TCHECK(ipx[3]); 209235530Sdelphij (void)printf(" %08x/%d.%d", EXTRACT_32BITS(&ipx[0]), 21017680Spst EXTRACT_16BITS(&ipx[2]), EXTRACT_16BITS(&ipx[3])); 21117680Spst 21217680Spst ipx += 4; 21317680Spst length -= 8; 21417680Spst } 21517680Spst break; 21617680Spst default: 21798527Sfenner (void)printf("ipx-rip-?%x", command); 21898527Sfenner break; 21917680Spst } 22098527Sfenner return; 22117680Spsttrunc: 22298527Sfenner printf("[|ipx %d]", length); 22317680Spst} 224