Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <u.h>
2
#include <libc.h>
3
#include <ip.h>
4
#include <auth.h>
5
#include "ppp.h"
6
 
7
static	ushort	endian	= 1;
8
static	uchar*	aendian	= (uchar*)&endian;
9
#define	LITTLE	*aendian
10
 
11
ushort
12
ptclbsum(uchar *addr, int len)
13
{
14
	ulong losum, hisum, mdsum, x;
15
	ulong t1, t2;
16
 
17
	losum = 0;
18
	hisum = 0;
19
	mdsum = 0;
20
 
21
	x = 0;
22
	if((uintptr)addr & 1) {
23
		if(len) {
24
			hisum += addr[0];
25
			len--;
26
			addr++;
27
		}
28
		x = 1;
29
	}
30
	while(len >= 16) {
31
		t1 = *(ushort*)(addr+0);
32
		t2 = *(ushort*)(addr+2);	mdsum += t1;
33
		t1 = *(ushort*)(addr+4);	mdsum += t2;
34
		t2 = *(ushort*)(addr+6);	mdsum += t1;
35
		t1 = *(ushort*)(addr+8);	mdsum += t2;
36
		t2 = *(ushort*)(addr+10);	mdsum += t1;
37
		t1 = *(ushort*)(addr+12);	mdsum += t2;
38
		t2 = *(ushort*)(addr+14);	mdsum += t1;
39
		mdsum += t2;
40
		len -= 16;
41
		addr += 16;
42
	}
43
	while(len >= 2) {
44
		mdsum += *(ushort*)addr;
45
		len -= 2;
46
		addr += 2;
47
	}
48
	if(x) {
49
		if(len)
50
			losum += addr[0];
51
		if(LITTLE)
52
			losum += mdsum;
53
		else
54
			hisum += mdsum;
55
	} else {
56
		if(len)
57
			hisum += addr[0];
58
		if(LITTLE)
59
			hisum += mdsum;
60
		else
61
			losum += mdsum;
62
	}
63
 
64
	losum += hisum >> 8;
65
	losum += (hisum & 0xff) << 8;
66
	while(hisum = losum>>16)
67
		losum = hisum + (losum & 0xffff);
68
 
69
	return losum & 0xffff;
70
}
71
 
72
ushort
73
ptclcsum(Block *bp, int offset, int len)
74
{
75
	uchar *addr;
76
	ulong losum, hisum;
77
	ushort csum;
78
	int odd, blen, x;
79
 
80
	/* Correct to front of data area */
81
	while(bp != nil && offset && offset >= BLEN(bp)) {
82
		offset -= BLEN(bp);
83
		bp = bp->next;
84
	}
85
	if(bp == nil)
86
		return 0;
87
 
88
	addr = bp->rptr + offset;
89
	blen = BLEN(bp) - offset;
90
 
91
	if(bp->next == nil) {
92
		if(blen < len)
93
			len = blen;
94
		return ~ptclbsum(addr, len) & 0xffff;
95
	}
96
 
97
	losum = 0;
98
	hisum = 0;
99
 
100
	odd = 0;
101
	while(len) {
102
		x = blen;
103
		if(len < x)
104
			x = len;
105
 
106
		csum = ptclbsum(addr, x);
107
		if(odd)
108
			hisum += csum;
109
		else
110
			losum += csum;
111
		odd = (odd+x) & 1;
112
		len -= x;
113
 
114
		bp = bp->next;
115
		if(bp == nil)
116
			break;
117
		blen = BLEN(bp);
118
		addr = bp->rptr;
119
	}
120
 
121
	losum += hisum>>8;
122
	losum += (hisum&0xff)<<8;
123
	while((csum = losum>>16) != 0)
124
		losum = csum + (losum & 0xffff);
125
 
126
	return ~losum & 0xffff;
127
}
128
 
129
ushort
130
ipcsum(uchar *addr)
131
{
132
	int len;
133
	ulong sum;
134
 
135
	sum = 0;
136
	len = (addr[0]&0xf)<<2;
137
 
138
	while(len > 0) {
139
		sum += (addr[0]<<8) | addr[1] ;
140
		len -= 2;
141
		addr += 2;
142
	}
143
 
144
	sum = (sum & 0xffff) + (sum >> 16);
145
	sum = (sum & 0xffff) + (sum >> 16);
146
 
147
	return (sum^0xffff);
148
}