View | Details | Raw Unified | Return to bug 13374
Collapse All | Expand All

(-)./ipx.h (+1 lines)
Lines 95-100 Link Here
95
#define	SO_ALL_PACKETS		7
95
#define	SO_ALL_PACKETS		7
96
#define SO_MTU			8
96
#define SO_MTU			8
97
#define SO_IPXTUN_ROUTE		9
97
#define SO_IPXTUN_ROUTE		9
98
#define SO_IPX_CHECKSUM		10
98
99
99
/*
100
/*
100
 * IPX addressing
101
 * IPX addressing
(-)./ipx_cksum.c (-160 / +63 lines)
Lines 38-210 Link Here
38
38
39
#include <sys/param.h>
39
#include <sys/param.h>
40
#include <sys/mbuf.h>
40
#include <sys/mbuf.h>
41
#include <sys/libkern.h>
41
42
43
#include <netipx/ipx.h>
42
#include <netipx/ipx_var.h>
44
#include <netipx/ipx_var.h>
43
45
44
/*
45
 * Checksum routine for Network Systems Protocol Packets (Big-Endian).
46
 *
47
 * This routine is very heavily used in the network
48
 * code and should be modified for each CPU to be as fast as possible.
49
 */
50
46
51
#define ADDCARRY(x)  { if ((x) > 65535) (x) -= 65535; }
47
#define SUMADV	sum += *w++
52
#define FOLD(x) {l_util.l = (x); (x) = l_util.s[0] + l_util.s[1]; ADDCARRY(x);}
53
48
54
u_short
49
u_short
55
ipx_cksum(m, len)
50
ipx_cksum(struct mbuf *m, int len) {
56
	struct mbuf *m;
51
	u_int32_t sum = 0;
57
	int len;
52
	u_short *w;
58
{
53
	u_char oldtc;
59
	register u_short *w;
54
	int mlen, words;
60
	register int sum = 0;
55
	struct ipx *ipx;
61
	register int mlen = 0;
62
	register int sum2;
63
64
	union {
56
	union {
65
		u_short s[2];
57
		u_char	b[2];
66
		long	l;
58
		u_short	w;
67
	} l_util;
59
	} buf;
68
60
69
	for (;m != NULL && len; m = m->m_next) {
61
	ipx = mtod(m, struct ipx*);
70
		if (m->m_len == 0)
62
	oldtc = ipx->ipx_tc;
71
			continue;
63
	ipx->ipx_tc = 0;
72
		/*
64
	w = &ipx->ipx_len;
73
		 * Each trip around loop adds in
65
	len -= 2;
74
		 * word from one mbuf segment.
66
	mlen = 2;
75
		 */
67
76
		w = mtod(m, u_short *);
68
	for(;;) {
77
		if (mlen == -1) {
69
		mlen = imin(m->m_len - mlen, len);
78
			/*
70
		words = mlen / 2;
79
			 * There is a byte left from the last segment;
71
		len -= mlen & ~1;
80
			 * ones-complement add it into the checksum.
72
		while (words >= 16) {
81
			 */
73
			SUMADV;	SUMADV;	SUMADV;	SUMADV;
82
#if BYTE_ORDER == BIG_ENDIAN
74
			SUMADV;	SUMADV;	SUMADV;	SUMADV;
83
			sum  += *(u_char *)w;
75
			SUMADV;	SUMADV;	SUMADV;	SUMADV;
84
#else
76
			SUMADV;	SUMADV;	SUMADV;	SUMADV;
85
			sum  += *(u_char *)w << 8;
77
			words -= 16;
86
#endif
78
		}
87
			sum += sum;
79
		while (words--)
88
			w = (u_short *)(1 + (char *)w);
80
			SUMADV;
89
			mlen = m->m_len - 1;
81
		if (len == 0)
90
			len--;
82
			break;
91
			FOLD(sum);
83
		mlen &= 1;
92
		} else
84
		if (mlen) {
93
			mlen = m->m_len;
85
			buf.b[0] = *(u_char*)w;
94
		if (len < mlen)
86
			if (--len == 0) {
95
			mlen = len;
87
				buf.b[1] = 0;
96
		len -= mlen;
88
				sum += buf.w;
97
		/*
89
				break;
98
		 * We can do a 16 bit ones complement sum using
90
			}
99
		 * 32 bit arithmetic registers for adding,
91
		}
100
		 * with carries from the low added
92
		m = m->m_next;
101
		 * into the high (by normal carry-chaining)
93
		if (m == NULL)
102
		 * so long as we fold back before 16 carries have occured.
94
			break;
103
		 */
95
		w = mtod(m, u_short*);
104
		if (1 & (int) w)
96
		if (mlen) {
105
			goto uuuuglyy;
97
			buf.b[1] = *(u_char*)w;
106
#ifndef TINY
98
			sum += buf.w;
107
/* -DTINY reduces the size from 1250 to 550, but slows it down by 22% */
99
			((u_char*)w)++;
108
		while ((mlen -= 32) >= 0) {
100
			if (--len == 0)
109
			sum += w[0]; sum += sum; sum += w[1]; sum += sum;
101
				break;
110
			sum += w[2]; sum += sum; sum += w[3]; sum += sum;
102
		} 
111
			sum += w[4]; sum += sum; sum += w[5]; sum += sum;
112
			sum += w[6]; sum += sum; sum += w[7]; sum += sum;
113
			FOLD(sum);
114
			sum += w[8]; sum += sum; sum += w[9]; sum += sum;
115
			sum += w[10]; sum += sum; sum += w[11]; sum += sum;
116
			sum += w[12]; sum += sum; sum += w[13]; sum += sum;
117
			sum += w[14]; sum += sum; sum += w[15]; sum += sum;
118
			FOLD(sum);
119
			w += 16;
120
		}
121
		mlen += 32;
122
#endif
123
		while ((mlen -= 8) >= 0) {
124
			sum += w[0]; sum += sum; sum += w[1]; sum += sum;
125
			sum += w[2]; sum += sum; sum += w[3]; sum += sum;
126
			FOLD(sum);
127
			w += 4;
128
		}
129
		mlen += 8;
130
		while ((mlen -= 2) >= 0) {
131
			sum += *w++; sum += sum;
132
		}
133
		goto commoncase;
134
uuuuglyy:
135
#if BYTE_ORDER == BIG_ENDIAN
136
#define ww(n) (((u_char *)w)[n + n + 1])
137
#define vv(n) (((u_char *)w)[n + n])
138
#else
139
#if BYTE_ORDER == LITTLE_ENDIAN
140
#define vv(n) (((u_char *)w)[n + n + 1])
141
#define ww(n) (((u_char *)w)[n + n])
142
#endif
143
#endif
144
		sum2 = 0;
145
#ifndef TINY
146
		while ((mlen -= 32) >= 0) {
147
		    sum += ww(0); sum += sum; sum += ww(1); sum += sum;
148
		    sum += ww(2); sum += sum; sum += ww(3); sum += sum;
149
		    sum += ww(4); sum += sum; sum += ww(5); sum += sum;
150
		    sum += ww(6); sum += sum; sum += ww(7); sum += sum;
151
		    FOLD(sum);
152
		    sum += ww(8); sum += sum; sum += ww(9); sum += sum;
153
		    sum += ww(10); sum += sum; sum += ww(11); sum += sum;
154
		    sum += ww(12); sum += sum; sum += ww(13); sum += sum;
155
		    sum += ww(14); sum += sum; sum += ww(15); sum += sum;
156
		    FOLD(sum);
157
		    sum2 += vv(0); sum2 += sum2; sum2 += vv(1); sum2 += sum2;
158
		    sum2 += vv(2); sum2 += sum2; sum2 += vv(3); sum2 += sum2;
159
		    sum2 += vv(4); sum2 += sum2; sum2 += vv(5); sum2 += sum2;
160
		    sum2 += vv(6); sum2 += sum2; sum2 += vv(7); sum2 += sum2;
161
		    FOLD(sum2);
162
		    sum2 += vv(8); sum2 += sum2; sum2 += vv(9); sum2 += sum2;
163
		    sum2 += vv(10); sum2 += sum2; sum2 += vv(11); sum2 += sum2;
164
		    sum2 += vv(12); sum2 += sum2; sum2 += vv(13); sum2 += sum2;
165
		    sum2 += vv(14); sum2 += sum2; sum2 += vv(15); sum2 += sum2;
166
		    FOLD(sum2);
167
		    w += 16;
168
		}
169
		mlen += 32;
170
#endif
171
		while ((mlen -= 8) >= 0) {
172
		    sum += ww(0); sum += sum; sum += ww(1); sum += sum;
173
		    sum += ww(2); sum += sum; sum += ww(3); sum += sum;
174
		    FOLD(sum);
175
		    sum2 += vv(0); sum2 += sum2; sum2 += vv(1); sum2 += sum2;
176
		    sum2 += vv(2); sum2 += sum2; sum2 += vv(3); sum2 += sum2;
177
		    FOLD(sum2);
178
		    w += 4;
179
		}
180
		mlen += 8;
181
		while ((mlen -= 2) >= 0) {
182
			sum += ww(0); sum += sum;
183
			sum2 += vv(0); sum2 += sum2;
184
			w++;
185
		}
186
		sum += (sum2 << 8);
187
commoncase:
188
		if (mlen == -1) {
189
#if BYTE_ORDER == BIG_ENDIAN
190
			sum += *(u_char *)w << 8;
191
#else
192
			sum += *(u_char *)w;
193
#endif
194
		}
195
		FOLD(sum);
196
	}
197
	if (mlen == -1) {
198
		/* We had an odd number of bytes to sum; assume a garbage
199
		   byte of zero and clean up */
200
		sum += sum;
201
		FOLD(sum);
202
	}
103
	}
203
	/*
104
204
	 * sum has already been kept to low sixteen bits.
105
	ipx->ipx_tc = oldtc;
205
	 * just examine result and exit.
106
206
	 */
107
	sum = (sum & 0xffff) + (sum >> 16);
207
	if(sum == 0xffff)
108
	if (sum >= 0x10000)
208
		sum = 0;
109
		sum++;
110
	if (sum)
111
		sum = ~sum;
209
	return (sum);
112
	return (sum);
210
}
113
}
(-)./ipx_input.c (-41 / +9 lines)
Lines 130-138 Link Here
130
	register struct mbuf *m;
130
	register struct mbuf *m;
131
	register struct ipxpcb *ipxp;
131
	register struct ipxpcb *ipxp;
132
	struct ipx_ifaddr *ia;
132
	struct ipx_ifaddr *ia;
133
	register int i;
134
	int len, s;
133
	int len, s;
135
	char oddshortpacket = 0;
136
134
137
next:
135
next:
138
	/*
136
	/*
Lines 171-185 Link Here
171
169
172
	ipx = mtod(m, struct ipx *);
170
	ipx = mtod(m, struct ipx *);
173
	len = ntohs(ipx->ipx_len);
171
	len = ntohs(ipx->ipx_len);
174
	if ((len < m->m_pkthdr.len) && (oddshortpacket = len & 1)) {
175
		/*
176
		 * If this packet is of odd length, and the length
177
		 * inside the header is less than the received packet
178
		 * length, preserve garbage byte for possible checksum.
179
		 */
180
		len++;
181
	}
182
183
	/*
172
	/*
184
	 * Check that the amount of data in the buffers
173
	 * Check that the amount of data in the buffers
185
	 * is as at least much as the IPX header would have us expect.
174
	 * is as at least much as the IPX header would have us expect.
Lines 197-205 Link Here
197
		} else
186
		} else
198
			m_adj(m, len - m->m_pkthdr.len);
187
			m_adj(m, len - m->m_pkthdr.len);
199
	}
188
	}
200
	if (ipxcksum && ((i = ipx->ipx_sum) != 0xffff)) {
189
	if (ipxcksum && ipx->ipx_sum != 0xffff) {
201
		ipx->ipx_sum = 0;
190
		if (ipx->ipx_sum != ipx_cksum(m, len)) {
202
		if (i != (ipx->ipx_sum = ipx_cksum(m, len))) {
203
			ipxstat.ipxs_badsum++;
191
			ipxstat.ipxs_badsum++;
204
			goto bad;
192
			goto bad;
205
		}
193
		}
Lines 274-282 Link Here
274
	 * Switch out to protocol's input routine.
262
	 * Switch out to protocol's input routine.
275
	 */
263
	 */
276
	if (ipxp != NULL) {
264
	if (ipxp != NULL) {
277
		if (oddshortpacket) {
278
			m_adj(m, -1);
279
		}
280
		ipxstat.ipxs_delivered++;
265
		ipxstat.ipxs_delivered++;
281
		if ((ipxp->ipxp_flags & IPXP_ALL_PACKETS) == 0)
266
		if ((ipxp->ipxp_flags & IPXP_ALL_PACKETS) == 0)
282
			switch (ipx->ipx_pt) {
267
			switch (ipx->ipx_pt) {
Lines 396-427 Link Here
396
			goto cleanup;
381
			goto cleanup;
397
		}
382
		}
398
	}
383
	}
399
	/* XXX
384
	/*
400
	 * I think the checksum generation is bogus. According to the NLSP
385
	 * We don't need to recompute checksum because ipx_tc field
401
	 * spec the ipx_tc (hop count) field and the ipx_sum should be
386
	 * is ignored by checksum calculation routine, however
402
	 * zero'ed before generating the checksum, ie. it should not be
387
	 * it may be desirable to reset checksum if ipxcksum == 0
403
	 * necesary to recompute it in the forwarding function.
404
	 */
388
	 */
405
	/* need to adjust checksum */
389
#if 0
406
	if (ipxcksum && ipx->ipx_sum != 0xffff) {
390
	if (!ipxcksum)
407
		union bytes {
408
			u_char c[4];
409
			u_short s[2];
410
			long l;
411
		} x;
412
		register int shift;
413
		x.l = 0;
414
		x.c[0] = agedelta;
415
		shift = (((((int)ntohs(ipx->ipx_len)) + 1) >> 1) - 2) & 0xf;
416
		x.l = ipx->ipx_sum + (x.s[0] << shift);
417
		x.l = x.s[0] + x.s[1];
418
		x.l = x.s[0] + x.s[1];
419
		if (x.l == 0xffff)
420
			ipx->ipx_sum = 0;
421
		else
422
			ipx->ipx_sum = x.l;
423
	} else 
424
		ipx->ipx_sum = 0xffff;
391
		ipx->ipx_sum = 0xffff;
392
#endif
425
393
426
	error = ipx_outputfl(m, &ipx_droute, flags);
394
	error = ipx_outputfl(m, &ipx_droute, flags);
427
	if (error == 0) {
395
	if (error == 0) {
(-)./ipx_outputfl.c (-6 / +2 lines)
Lines 247-258 Link Here
247
			ipx->ipx_dna.x_net = dst.sipx_addr.x_net;
247
			ipx->ipx_dna.x_net = dst.sipx_addr.x_net;
248
			m1 = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
248
			m1 = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
249
249
250
			if(ipx->ipx_sum != 0xffff) {
250
			if(ipx->ipx_sum != 0xffff)
251
				int len = ntohs(ipx->ipx_len);
251
				ipx->ipx_sum = ipx_cksum(m, ntohs(ipx->ipx_len));
252
				ipx->ipx_sum = 0;
253
				len = ((len - 1) | 1) + 1;
254
				ipx->ipx_sum = ipx_cksum(m, len);
255
			}
256
			if(m1) {
252
			if(m1) {
257
				error = (*ifp->if_output)(ifp, m1,
253
				error = (*ifp->if_output)(ifp, m1,
258
					(struct sockaddr *)&dst, NULL);
254
					(struct sockaddr *)&dst, NULL);
(-)./ipx_pcb.c (+2 lines)
Lines 66-71 Link Here
66
		return (ENOBUFS);
66
		return (ENOBUFS);
67
	bzero(ipxp, sizeof *ipxp);
67
	bzero(ipxp, sizeof *ipxp);
68
	ipxp->ipxp_socket = so;
68
	ipxp->ipxp_socket = so;
69
	if (ipxcksum)
70
		ipxp->ipxp_flags |= IPXP_CHECKSUM;
69
	insque(ipxp, head);
71
	insque(ipxp, head);
70
	so->so_pcb = (caddr_t)ipxp;
72
	so->so_pcb = (caddr_t)ipxp;
71
	return (0);
73
	return (0);
(-)./ipx_pcb.h (+1 lines)
Lines 64-69 Link Here
64
#define IPXP_RAWIN		0x2	/* show headers on input */
64
#define IPXP_RAWIN		0x2	/* show headers on input */
65
#define IPXP_RAWOUT		0x4	/* show header on output */
65
#define IPXP_RAWOUT		0x4	/* show header on output */
66
#define IPXP_ALL_PACKETS	0x8	/* Turn off higher proto processing */
66
#define IPXP_ALL_PACKETS	0x8	/* Turn off higher proto processing */
67
#define	IPXP_CHECKSUM		0x10	/* use checksum on this socket */
67
68
68
#define	IPX_WILDCARD		1
69
#define	IPX_WILDCARD		1
69
70
(-)./ipx_usrreq.c (-4 / +9 lines)
Lines 214-220 Link Here
214
		m = mprev;
214
		m = mprev;
215
		if ((m->m_flags & M_EXT) == 0 &&
215
		if ((m->m_flags & M_EXT) == 0 &&
216
			(m->m_len + m->m_data < &m->m_dat[MLEN])) {
216
			(m->m_len + m->m_data < &m->m_dat[MLEN])) {
217
			m->m_len++;
217
			mtod(m, char*)[m->m_len++] = 0;
218
		} else {
218
		} else {
219
			struct mbuf *m1 = m_get(M_DONTWAIT, MT_DATA);
219
			struct mbuf *m1 = m_get(M_DONTWAIT, MT_DATA);
220
220
Lines 250-258 Link Here
250
250
251
	ipx->ipx_len = htons((u_short)len);
251
	ipx->ipx_len = htons((u_short)len);
252
252
253
	if (ipxcksum) {
253
	if (ipxp->ipxp_flags & IPXP_CHECKSUM) {
254
		ipx->ipx_sum = 0;
255
		len = ((len - 1) | 1) + 1;
256
		ipx->ipx_sum = ipx_cksum(m, len);
254
		ipx->ipx_sum = ipx_cksum(m, len);
257
	} else
255
	} else
258
		ipx->ipx_sum = 0xffff;
256
		ipx->ipx_sum = 0xffff;
Lines 333-338 Link Here
333
		case SO_HEADERS_ON_INPUT:
331
		case SO_HEADERS_ON_INPUT:
334
			mask = IPXP_RAWIN;
332
			mask = IPXP_RAWIN;
335
			goto get_flags;
333
			goto get_flags;
334
335
		case SO_IPX_CHECKSUM:
336
			mask = IPXP_CHECKSUM;
337
			goto get_flags;
336
			
338
			
337
		case SO_HEADERS_ON_OUTPUT:
339
		case SO_HEADERS_ON_OUTPUT:
338
			mask = IPXP_RAWOUT;
340
			mask = IPXP_RAWOUT;
Lines 371-376 Link Here
371
		case SO_HEADERS_ON_INPUT:
373
		case SO_HEADERS_ON_INPUT:
372
			mask = IPXP_RAWIN;
374
			mask = IPXP_RAWIN;
373
			goto set_head;
375
			goto set_head;
376
377
		case SO_IPX_CHECKSUM:
378
			mask = IPXP_CHECKSUM;
374
379
375
		case SO_HEADERS_ON_OUTPUT:
380
		case SO_HEADERS_ON_OUTPUT:
376
			mask = IPXP_RAWOUT;
381
			mask = IPXP_RAWOUT;
(-)./spx_usrreq.c (-5 / +1 lines)
Lines 1081-1091 Link Here
1081
		si->si_ack = htons(cb->s_ack);
1081
		si->si_ack = htons(cb->s_ack);
1082
1082
1083
		if (ipxcksum) {
1083
		if (ipxcksum) {
1084
			si->si_sum = 0;
1084
			si->si_sum = ipx_cksum(m, ntohs(si->si_len));
1085
			len = ntohs(si->si_len);
1086
			if (len & 1)
1087
				len++;
1088
			si->si_sum = ipx_cksum(m, len);
1089
		} else
1085
		} else
1090
			si->si_sum = 0xffff;
1086
			si->si_sum = 0xffff;

Return to bug 13374