File: ipx.c

package info (click to toggle)
pktstat 1.8.5-11
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 916 kB
  • sloc: ansic: 9,195; sh: 1,032; makefile: 34
file content (179 lines) | stat: -rw-r--r-- 5,492 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
/* David Leonard, 2002. Public domain. */
/* $Id: ipx.c 1172 2006-11-11 13:32:14Z d $ */

#if HAVE_CONFIG_H
# include "config.h"
#endif

#if HAVE_NETIPX_IPX_H

#if STDC_HEADERS
# include <stdio.h>
# include <string.h>
#endif
#if HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#if HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#if HAVE_SYS_PARAM_H
# include <sys/param.h>
#endif
#if HAVE_NETIPX_IPX_H
# include <netipx/ipx.h>
#endif
#if HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif

#include "compat.h"
#include "tag.h"
#include "flow.h"

#ifndef IPXPROTO_UNKWN
# ifndef IPX_TYPE_UNKNOWN
/* (these defines from OpenBSD <netipx/ipx.h>) */
#  define IPXPROTO_UNKWN          0       /* Unknown */
#  define IPXPROTO_RI             1       /* RIP Routing Information */
#  define IPXPROTO_PXP            4       /* IPX Packet Exchange Protocol */
#  define IPXPROTO_SPX            5       /* SPX Sequenced Packet */
#  define IPXPROTO_NCP            17      /* NCP NetWare Core */
#  define IPXPROTO_NETBIOS        20      /* Propagated Packet */
#  define XXX     __attribute__((__packed__))
typedef struct {
	u_int32_t 	net		XXX;
	u_int8_t 	host[6];
	u_int16_t	port		XXX;
} ipx_address, ipx_addr_t;
struct ipxhdr {
        u_int16_t       ipx_sum XXX;    /* Checksum */
        u_int16_t       ipx_len XXX;    /* Length, in bytes, including header */
        u_int8_t        ipx_tc;         /* Transport Control (i.e. hop count) */
        u_int8_t        ipx_pt;         /* Packet Type (i.e. lev 2 protocol) */
        ipx_addr_t      ipx_dna;        /* Destination Network Address */
        ipx_addr_t      ipx_sna;        /* Source Network Address */
};
#  undef XXX
# else 
#  define IPXPROTO_UNKWN          IPX_TYPE_UNKNOWN
#  define IPXPROTO_RI             IPX_TYPE_RIP
#  define IPXPROTO_PXP            IPX_TYPE_SAP
#  define IPXPROTO_SPX            IPX_TYPE_SPX
#  define IPXPROTO_NCP            IPX_TYPE_NCP
#  define IPXPROTO_NETBIOS        IPX_TYPE_PPROP
/* field name translations for 'struct ipxhdr' */
#  define ipx_sum ipx_checksum
#  define ipx_len ipx_pktsize
#  define ipx_tc  ipx_tctrl
#  define ipx_pt  ipx_type
#  define ipx_dna ipx_dest
#  define ipx_sna ipx_source
# endif
#endif

static const char *my_ipx_ntoa(void *);

static struct {
	u_int8_t pt;
	const char *name;
} prototab[] = {
	{ IPXPROTO_RI,		"ripx" },
	{ IPXPROTO_PXP,		"pxp" },
	{ IPXPROTO_SPX,		"spx" },
	{ IPXPROTO_NCP,		"ncp" },
	{ IPXPROTO_NETBIOS,	"netbios" }
};
#define nproto (sizeof prototab / sizeof prototab[0])

/*
 * Notes on the representation of IPX addresses
 * --------------------------------------------
 *
 * IPX addresses (unlike IP addresses) are essentially unstructured.
 * The format for display IPX addresses varies. Microsoft's WinSNMP parser
 * accepts one of '-', ':', '.' after the 8-digit hex net number.
 * (This is probably because RFC1298, section 2.4, describes just a raw string)
 *
 * Bowever, <http://netcert.tripod.com/ccna/internetworking/ipx.html>
 * gives '4a.0000.0c00.23fe' as an example. Novell themselves, in
 * <www.novell.com/documentation/lg/nw6p/ipx_enu/data/hvvqznoa.html>
 * give the example of 'FEDCBA98 1A2B3C5D7E9F 0453'.
 *
 * A discussion at <www.cs.helsinki.fi/linux/linux-kernel/2001-44/0742.html>
 * notes that ipx addresses look like hex floating point (ie xxx.xxx).
 * And a google-cached network course from boerner.net gives an example
 * IPX host address as '000008A2:0060973E97F3'.
 *
 * Cisco IOS reports IPX addresses in the 'dotted triplet' form,
 * with an example from a CCNA study guide given as '010a.0123.0123.0123'.
 * NetBSD's libc has an ipx_ntoa() that yields representations such as
 * '8A2H.00:60:97:3E:97:F3.65535'.
 *
 * Clearly, this is an insane and exciting world of mental trauma
 * that is as appealling as having a sharp pointy stick jabbed into your
 * eye. Because I am not that familiar with IPX, I would really
 * appreciate feedback/advice on this -- as long as the advice is 
 * NOT "let the user specify". I want to know what the best representation
 * to use for the expected users of pktstat would be. For now, I'll
 * use Cisco's representation, suffixed by a colon and the decimal port number.
 */
static const char *
my_ipx_ntoa(void *addr)
{
	static char buf[] = "00000000.0000.0000.0000:0000";
	u_int32_t ipx_net;
	u_int8_t  ipx_host[6];
	u_int16_t ipx_port;

	memcpy(&ipx_net,  addr, 4);
	memcpy(&ipx_host, addr + 4, 6);
	memcpy(&ipx_port, addr + 10, 2);

	snprintf(buf, sizeof buf, 
		"%8lX.%02X%02X.%02X%02X.%02X%02X:%u",
		(unsigned long) ntohl(ipx_net),
		ipx_host[0], ipx_host[1], ipx_host[2],
		ipx_host[3], ipx_host[4], ipx_host[5],
		ntohs(ipx_port));
	return buf;
}

const char *
ipx_tag(const char *p, const char *end)
{
#if defined(__linux__)
	struct ipxhdr h;
#else /* BSD */
	struct ipx h;
#endif
	static char tag[TAGLEN];
	char src[TAGLEN], dst[TAGLEN], pt[TAGLEN];
	int i;
	const char *ptname;

	memcpy(&h, p, sizeof h);
	snprintf(dst, sizeof src, "%s", my_ipx_ntoa(&h.ipx_dna));
	snprintf(src, sizeof src, "%s", my_ipx_ntoa(&h.ipx_sna));

	ptname = NULL;
	for (i = 0; i < sizeof prototab / sizeof prototab[0]; i++)
		if (prototab[i].pt == h.ipx_pt) {
			ptname = prototab[i].name;
			break;
		}
	if (!ptname) {
		snprintf(pt, sizeof pt, "0x%02x", h.ipx_pt);
		ptname = pt;
	}
	snprintf(tag, sizeof tag, "ipx %s %s -> %s", ptname, src, dst);
	return tag;
}

/* 
 * NOTES
 * - http://www.protocols.com/pbook/novel.htm
 * - 802.2 over IPX: RFC1132
 */

#endif /* HAVE_NETIPX_IPX_H */