The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/ip/ipaux.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 #include        "u.h"
    2 #include        "../port/lib.h"
    3 #include        "mem.h"
    4 #include        "dat.h"
    5 #include        "fns.h"
    6 #include        "../port/error.h"
    7 #include        "ip.h"
    8 #include        "ipv6.h"
    9 
   10 char *v6hdrtypes[Maxhdrtype] =
   11 {
   12         [HBH]           "HopbyHop",
   13         [ICMP]          "ICMP",
   14         [IGMP]          "IGMP",
   15         [GGP]           "GGP",
   16         [IPINIP]        "IP",
   17         [ST]            "ST",
   18         [TCP]           "TCP",
   19         [UDP]           "UDP",
   20         [ISO_TP4]       "ISO_TP4",
   21         [RH]            "Routinghdr",
   22         [FH]            "Fraghdr",
   23         [IDRP]          "IDRP",
   24         [RSVP]          "RSVP",
   25         [AH]            "Authhdr",
   26         [ESP]           "ESP",
   27         [ICMPv6]        "ICMPv6",
   28         [NNH]           "Nonexthdr",
   29         [ISO_IP]        "ISO_IP",
   30         [IGRP]          "IGRP",
   31         [OSPF]          "OSPF",
   32 };
   33 
   34 /*
   35  *  well known IPv6 addresses
   36  */
   37 uchar v6Unspecified[IPaddrlen] = {
   38         0, 0, 0, 0,
   39         0, 0, 0, 0,
   40         0, 0, 0, 0,
   41         0, 0, 0, 0
   42 };
   43 uchar v6loopback[IPaddrlen] = {
   44         0, 0, 0, 0,
   45         0, 0, 0, 0,
   46         0, 0, 0, 0,
   47         0, 0, 0, 0x01
   48 };
   49 
   50 uchar v6linklocal[IPaddrlen] = {
   51         0xfe, 0x80, 0, 0,
   52         0, 0, 0, 0,
   53         0, 0, 0, 0,
   54         0, 0, 0, 0
   55 };
   56 uchar v6linklocalmask[IPaddrlen] = {
   57         0xff, 0xff, 0xff, 0xff,
   58         0xff, 0xff, 0xff, 0xff,
   59         0, 0, 0, 0,
   60         0, 0, 0, 0
   61 };
   62 int v6llpreflen = 8;    /* link-local prefix length in bytes */
   63 
   64 uchar v6multicast[IPaddrlen] = {
   65         0xff, 0, 0, 0,
   66         0, 0, 0, 0,
   67         0, 0, 0, 0,
   68         0, 0, 0, 0
   69 };
   70 uchar v6multicastmask[IPaddrlen] = {
   71         0xff, 0, 0, 0,
   72         0, 0, 0, 0,
   73         0, 0, 0, 0,
   74         0, 0, 0, 0
   75 };
   76 int v6mcpreflen = 1;    /* multicast prefix length */
   77 
   78 uchar v6allnodesN[IPaddrlen] = {
   79         0xff, 0x01, 0, 0,
   80         0, 0, 0, 0,
   81         0, 0, 0, 0,
   82         0, 0, 0, 0x01
   83 };
   84 uchar v6allroutersN[IPaddrlen] = {
   85         0xff, 0x01, 0, 0,
   86         0, 0, 0, 0,
   87         0, 0, 0, 0,
   88         0, 0, 0, 0x02
   89 };
   90 uchar v6allnodesNmask[IPaddrlen] = {
   91         0xff, 0xff, 0, 0,
   92         0, 0, 0, 0,
   93         0, 0, 0, 0,
   94         0, 0, 0, 0
   95 };
   96 int v6aNpreflen = 2;    /* all nodes (N) prefix */
   97 
   98 uchar v6allnodesL[IPaddrlen] = {
   99         0xff, 0x02, 0, 0,
  100         0, 0, 0, 0,
  101         0, 0, 0, 0,
  102         0, 0, 0, 0x01
  103 };
  104 uchar v6allroutersL[IPaddrlen] = {
  105         0xff, 0x02, 0, 0,
  106         0, 0, 0, 0,
  107         0, 0, 0, 0,
  108         0, 0, 0, 0x02
  109 };
  110 uchar v6allnodesLmask[IPaddrlen] = {
  111         0xff, 0xff, 0, 0,
  112         0, 0, 0, 0,
  113         0, 0, 0, 0,
  114         0, 0, 0, 0
  115 };
  116 int v6aLpreflen = 2;    /* all nodes (L) prefix */
  117 
  118 uchar v6solicitednode[IPaddrlen] = {
  119         0xff, 0x02, 0, 0,
  120         0, 0, 0, 0,
  121         0, 0, 0, 0x01,
  122         0xff, 0, 0, 0
  123 };
  124 uchar v6solicitednodemask[IPaddrlen] = {
  125         0xff, 0xff, 0xff, 0xff,
  126         0xff, 0xff, 0xff, 0xff,
  127         0xff, 0xff, 0xff, 0xff,
  128         0xff, 0x0, 0x0, 0x0
  129 };
  130 int v6snpreflen = 13;
  131 
  132 ushort
  133 ptclcsum(Block *bp, int offset, int len)
  134 {
  135         uchar *addr;
  136         ulong losum, hisum;
  137         ushort csum;
  138         int odd, blocklen, x;
  139 
  140         /* Correct to front of data area */
  141         while(bp != nil && offset && offset >= BLEN(bp)) {
  142                 offset -= BLEN(bp);
  143                 bp = bp->next;
  144         }
  145         if(bp == nil)
  146                 return 0;
  147 
  148         addr = bp->rp + offset;
  149         blocklen = BLEN(bp) - offset;
  150 
  151         if(bp->next == nil) {
  152                 if(blocklen < len)
  153                         len = blocklen;
  154                 return ~ptclbsum(addr, len) & 0xffff;
  155         }
  156 
  157         losum = 0;
  158         hisum = 0;
  159 
  160         odd = 0;
  161         while(len) {
  162                 x = blocklen;
  163                 if(len < x)
  164                         x = len;
  165 
  166                 csum = ptclbsum(addr, x);
  167                 if(odd)
  168                         hisum += csum;
  169                 else
  170                         losum += csum;
  171                 odd = (odd+x) & 1;
  172                 len -= x;
  173 
  174                 bp = bp->next;
  175                 if(bp == nil)
  176                         break;
  177                 blocklen = BLEN(bp);
  178                 addr = bp->rp;
  179         }
  180 
  181         losum += hisum>>8;
  182         losum += (hisum&0xff)<<8;
  183         while((csum = losum>>16) != 0)
  184                 losum = csum + (losum & 0xffff);
  185 
  186         return ~losum & 0xffff;
  187 }
  188 
  189 enum
  190 {
  191         Isprefix= 16,
  192 };
  193 
  194 #define CLASS(p) ((*(uchar*)(p))>>6)
  195 
  196 void
  197 ipv62smcast(uchar *smcast, uchar *a)
  198 {
  199         assert(IPaddrlen == 16);
  200         memmove(smcast, v6solicitednode, IPaddrlen);
  201         smcast[13] = a[13];
  202         smcast[14] = a[14];
  203         smcast[15] = a[15];
  204 }
  205 
  206 
  207 /*
  208  *  parse a hex mac address
  209  */
  210 int
  211 parsemac(uchar *to, char *from, int len)
  212 {
  213         char nip[4];
  214         char *p;
  215         int i;
  216 
  217         p = from;
  218         memset(to, 0, len);
  219         for(i = 0; i < len; i++){
  220                 if(p[0] == '\0' || p[1] == '\0')
  221                         break;
  222 
  223                 nip[0] = p[0];
  224                 nip[1] = p[1];
  225                 nip[2] = '\0';
  226                 p += 2;
  227 
  228                 to[i] = strtoul(nip, 0, 16);
  229                 if(*p == ':')
  230                         p++;
  231         }
  232         return i;
  233 }
  234 
  235 /*
  236  *  hashing tcp, udp, ... connections
  237  */
  238 ulong
  239 iphash(uchar *sa, ushort sp, uchar *da, ushort dp)
  240 {
  241         return ((sa[IPaddrlen-1]<<24) ^ (sp << 16) ^ (da[IPaddrlen-1]<<8) ^ dp ) % Nhash;
  242 }
  243 
  244 void
  245 iphtadd(Ipht *ht, Conv *c)
  246 {
  247         ulong hv;
  248         Iphash *h;
  249 
  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;
  254         else {
  255                 if(ipcmp(c->laddr, IPnoaddr) != 0){
  256                         if(c->lport == 0)
  257                                 h->match = IPmatchaddr;
  258                         else
  259                                 h->match = IPmatchpa;
  260                 } else {
  261                         if(c->lport == 0)
  262                                 h->match = IPmatchany;
  263                         else
  264                                 h->match = IPmatchport;
  265                 }
  266         }
  267         h->c = c;
  268 
  269         lock(ht);
  270         h->next = ht->tab[hv];
  271         ht->tab[hv] = h;
  272         unlock(ht);
  273 }
  274 
  275 void
  276 iphtrem(Ipht *ht, Conv *c)
  277 {
  278         ulong hv;
  279         Iphash **l, *h;
  280 
  281         hv = iphash(c->raddr, c->rport, c->laddr, c->lport);
  282         lock(ht);
  283         for(l = &ht->tab[hv]; (*l) != nil; l = &(*l)->next)
  284                 if((*l)->c == c){
  285                         h = *l;
  286                         (*l) = h->next;
  287                         free(h);
  288                         break;
  289                 }
  290         unlock(ht);
  291 }
  292 
  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,*
  298  *      announced && *,*
  299  */
  300 Conv*
  301 iphtlook(Ipht *ht, uchar *sa, ushort sp, uchar *da, ushort dp)
  302 {
  303         ulong hv;
  304         Iphash *h;
  305         Conv *c;
  306 
  307         /* exact 4 pair match (connection) */
  308         hv = iphash(sa, sp, da, dp);
  309         lock(ht);
  310         for(h = ht->tab[hv]; h != nil; h = h->next){
  311                 if(h->match != IPmatchexact)
  312                         continue;
  313                 c = h->c;
  314                 if(sp == c->rport && dp == c->lport
  315                 && ipcmp(sa, c->raddr) == 0 && ipcmp(da, c->laddr) == 0){
  316                         unlock(ht);
  317                         return c;
  318                 }
  319         }
  320 
  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)
  325                         continue;
  326                 c = h->c;
  327                 if(dp == c->lport && ipcmp(da, c->laddr) == 0){
  328                         unlock(ht);
  329                         return c;
  330                 }
  331         }
  332 
  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)
  337                         continue;
  338                 c = h->c;
  339                 if(dp == c->lport){
  340                         unlock(ht);
  341                         return c;
  342                 }
  343         }
  344 
  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)
  349                         continue;
  350                 c = h->c;
  351                 if(ipcmp(da, c->laddr) == 0){
  352                         unlock(ht);
  353                         return c;
  354                 }
  355         }
  356 
  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)
  361                         continue;
  362                 c = h->c;
  363                 unlock(ht);
  364                 return c;
  365         }
  366         unlock(ht);
  367         return nil;
  368 }

Cache object: 4098cb58b4d40a69392b5564f4dd97e0


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.