2 #include "../port/lib.h"
6 #include "../port/error.h"
10 char *v6hdrtypes[Maxhdrtype] =
35 * well known IPv6 addresses
37 uchar v6Unspecified[IPaddrlen] = {
43 uchar v6loopback[IPaddrlen] = {
50 uchar v6linklocal[IPaddrlen] = {
56 uchar v6linklocalmask[IPaddrlen] = {
57 0xff, 0xff, 0xff, 0xff,
58 0xff, 0xff, 0xff, 0xff,
62 int v6llpreflen = 8; /* link-local prefix length in bytes */
64 uchar v6multicast[IPaddrlen] = {
70 uchar v6multicastmask[IPaddrlen] = {
76 int v6mcpreflen = 1; /* multicast prefix length */
78 uchar v6allnodesN[IPaddrlen] = {
84 uchar v6allroutersN[IPaddrlen] = {
90 uchar v6allnodesNmask[IPaddrlen] = {
96 int v6aNpreflen = 2; /* all nodes (N) prefix */
98 uchar v6allnodesL[IPaddrlen] = {
104 uchar v6allroutersL[IPaddrlen] = {
110 uchar v6allnodesLmask[IPaddrlen] = {
116 int v6aLpreflen = 2; /* all nodes (L) prefix */
118 uchar v6solicitednode[IPaddrlen] = {
124 uchar v6solicitednodemask[IPaddrlen] = {
125 0xff, 0xff, 0xff, 0xff,
126 0xff, 0xff, 0xff, 0xff,
127 0xff, 0xff, 0xff, 0xff,
130 int v6snpreflen = 13;
133 ptclcsum(Block *bp, int offset, int len)
138 int odd, blocklen, x;
140 /* Correct to front of data area */
141 while(bp != nil && offset && offset >= BLEN(bp)) {
148 addr = bp->rp + offset;
149 blocklen = BLEN(bp) - offset;
151 if(bp->next == nil) {
154 return ~ptclbsum(addr, len) & 0xffff;
166 csum = ptclbsum(addr, x);
182 losum += (hisum&0xff)<<8;
183 while((csum = losum>>16) != 0)
184 losum = csum + (losum & 0xffff);
186 return ~losum & 0xffff;
194 #define CLASS(p) ((*(uchar*)(p))>>6)
197 ipv62smcast(uchar *smcast, uchar *a)
199 assert(IPaddrlen == 16);
200 memmove(smcast, v6solicitednode, IPaddrlen);
208 * parse a hex mac address
211 parsemac(uchar *to, char *from, int len)
219 for(i = 0; i < len; i++){
220 if(p[0] == '\0' || p[1] == '\0')
228 to[i] = strtoul(nip, 0, 16);
236 * hashing tcp, udp, ... connections
239 iphash(uchar *sa, ushort sp, uchar *da, ushort dp)
241 return ((sa[IPaddrlen-1]<<24) ^ (sp << 16) ^ (da[IPaddrlen-1]<<8) ^ dp ) % Nipht;
245 iphtadd(Ipht *ht, Conv *c)
250 hv = iphash(c->raddr, c->rport, c->laddr, c->lport);
251 h = smalloc(sizeof(*h));
252 if(ipcmp(c->raddr, IPnoaddr) != 0)
253 h->match = IPmatchexact;
255 if(ipcmp(c->laddr, IPnoaddr) != 0){
257 h->match = IPmatchaddr;
259 h->match = IPmatchpa;
262 h->match = IPmatchany;
264 h->match = IPmatchport;
270 h->next = ht->tab[hv];
276 iphtrem(Ipht *ht, Conv *c)
281 hv = iphash(c->raddr, c->rport, c->laddr, c->lport);
283 for(l = &ht->tab[hv]; (*l) != nil; l = &(*l)->next)
293 /* look for a matching conversation with the following precedence
294 * connected && raddr,rport,laddr,lport
295 * announced && laddr,lport
296 * announced && *,lport
297 * announced && laddr,*
301 iphtlook(Ipht *ht, uchar *sa, ushort sp, uchar *da, ushort dp)
307 /* exact 4 pair match (connection) */
308 hv = iphash(sa, sp, da, dp);
310 for(h = ht->tab[hv]; h != nil; h = h->next){
311 if(h->match != IPmatchexact)
314 if(sp == c->rport && dp == c->lport
315 && ipcmp(sa, c->raddr) == 0 && ipcmp(da, c->laddr) == 0){
321 /* match local address and port */
322 hv = iphash(IPnoaddr, 0, da, dp);
323 for(h = ht->tab[hv]; h != nil; h = h->next){
324 if(h->match != IPmatchpa)
327 if(dp == c->lport && ipcmp(da, c->laddr) == 0){
333 /* match just port */
334 hv = iphash(IPnoaddr, 0, IPnoaddr, dp);
335 for(h = ht->tab[hv]; h != nil; h = h->next){
336 if(h->match != IPmatchport)
345 /* match local address */
346 hv = iphash(IPnoaddr, 0, da, 0);
347 for(h = ht->tab[hv]; h != nil; h = h->next){
348 if(h->match != IPmatchaddr)
351 if(ipcmp(da, c->laddr) == 0){
357 /* look for something that matches anything */
358 hv = iphash(IPnoaddr, 0, IPnoaddr, 0);
359 for(h = ht->tab[hv]; h != nil; h = h->next){
360 if(h->match != IPmatchany)
373 if(isv4(c->raddr) && isv4(c->laddr) || ipcmp(c->raddr, IPnoaddr) == 0)