Annotation of linux/net/tcp/ip.c, revision 1.1.1.1

1.1       root        1: /* ip.c */
                      2: /*
                      3:     Copyright (C) 1992  Ross Biro
                      4: 
                      5:     This program is free software; you can redistribute it and/or modify
                      6:     it under the terms of the GNU General Public License as published by
                      7:     the Free Software Foundation; either version 2, or (at your option)
                      8:     any later version.
                      9: 
                     10:     This program is distributed in the hope that it will be useful,
                     11:     but WITHOUT ANY WARRANTY; without even the implied warranty of
                     12:     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     13:     GNU General Public License for more details.
                     14: 
                     15:     You should have received a copy of the GNU General Public License
                     16:     along with this program; if not, write to the Free Software
                     17:     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
                     18: 
                     19:     The Author may be reached as [email protected] or
                     20:     C/O Department of Mathematics; Stanford University; Stanford, CA 94305
                     21: */
                     22: 
                     23: #include <asm/segment.h>
                     24: #include <asm/system.h>
                     25: #include <linux/types.h>
                     26: #include <linux/kernel.h>
                     27: #include <linux/sched.h>
                     28: #include <linux/string.h>
                     29: #include <linux/socket.h>
                     30: #include <netinet/in.h>
                     31: #include "timer.h"
                     32: #include "ip.h"
                     33: #include "tcp.h"
                     34: #include "sock.h"
                     35: #include <linux/errno.h>
                     36: #include "arp.h"
                     37: #include "icmp.h"
                     38: 
                     39: unsigned long ip_addr[MAX_IP_ADDRES]={0,0,0};
                     40: 
                     41: #undef IP_DEBUG
                     42: #ifdef IP_DEBUG
                     43: #define PRINTK printk
                     44: #else
                     45: #define PRINTK dummy_routine
                     46: #endif
                     47: 
                     48: static struct rtable *rt_base=NULL; /* used to base all the routing data. */
                     49: 
                     50: struct ip_protocol *ip_protos[MAX_IP_PROTOS] = { NULL, };
                     51: 
                     52: #if 0
                     53: static  struct ip_protocol *
                     54: get_protocol(unsigned char prot)
                     55: {
                     56:    unsigned char hash;
                     57:    struct ip_protocol *p;
                     58:    PRINTK ("get_protocol (%d)\n ", prot);
                     59:    hash = prot & (MAX_IP_PROTOS -1);
                     60:    for (p = ip_protos[hash] ; p != NULL; p=p->next)
                     61:      {
                     62:        PRINTK ("trying protocol %d\n", p->protocol);
                     63:        if (p->protocol == prot)
                     64:             return (p);
                     65:      }
                     66:    return (NULL);
                     67:     
                     68: }
                     69: #endif
                     70: 
                     71: void
                     72: add_ip_protocol (struct ip_protocol *prot)
                     73: {
                     74:    unsigned char hash;
                     75:    struct ip_protocol *p2;
                     76:    hash = prot->protocol & (MAX_IP_PROTOS-1);
                     77:    prot ->next = ip_protos[hash];
                     78:    ip_protos[hash] = prot;
                     79:    prot->copy = 0;
                     80:    /* set the copy bit if we need to. */
                     81:    for (p2 = prot->next; p2 != NULL; p2=p2->next)
                     82:      {
                     83:        if (p2->protocol == prot->protocol)
                     84:          {
                     85:             prot->copy = 1;
                     86:             break;
                     87:          }
                     88:      }
                     89: 
                     90: }
                     91: 
                     92: int
                     93: delete_ip_protocol (struct ip_protocol *prot)
                     94: {
                     95:    struct ip_protocol *p;
                     96:    struct ip_protocol *lp=NULL;
                     97:    unsigned char hash;
                     98: 
                     99: 
                    100:    hash = prot->protocol & (MAX_IP_PROTOS -1);
                    101:    if (prot == ip_protos[hash])
                    102:      {
                    103:         ip_protos[hash]=ip_protos[hash]->next;
                    104:        return (0);
                    105:      }
                    106: 
                    107:    for (p = ip_protos[hash]; p != NULL; p = p->next)
                    108:      {
                    109:        /* we have to worry if the protocol being deleted is the
                    110:           last one on the list, then we may need to reset someones
                    111:           copied bit. */
                    112:        if (p->next != NULL && p->next == prot)
                    113:          {
                    114:             /* if we are the last one with this protocol and
                    115:                there is a previous one, reset its copy bit. */
                    116: 
                    117:             if (p->copy == 0 && lp != NULL)
                    118:               lp->copy = 0;
                    119:             p->next = prot->next;
                    120:             return (0);
                    121:          }
                    122: 
                    123:        if (p->next != NULL && p->next->protocol == prot->protocol)
                    124:          {
                    125:             lp = p;
                    126:          }
                    127:      }
                    128:    return (-1);
                    129: }
                    130: 
                    131: /* addr1 is the address which may or may not be broadcast etc.
                    132:    addr2 is the "real addr." */
                    133: 
                    134: int
                    135: ip_addr_match (unsigned long addr1, unsigned long addr2)
                    136: {
                    137:   int i;
                    138:   if (addr1 == addr2) return (1);
                    139:   for (i = 0; i < 4; i++, addr1 >>= 8, addr2 >>= 8)
                    140:     {
                    141:       if ((addr1 & 0xff) != (addr2 & 0xff))
                    142:        {
                    143:          /* the only way this could be a match is for the rest of
                    144:             addr1 to be 0. */
                    145:          if (addr1 != 0) 
                    146:            {
                    147:              return (0);
                    148:            }
                    149:          return (1);
                    150:        }
                    151:     }
                    152:   return (1);
                    153: }
                    154: 
                    155: int
                    156: my_ip_addr(unsigned long addr)
                    157: {
                    158:   int i;
                    159:   for (i = 0; i < MAX_IP_ADDRES; i++)
                    160:     {
                    161:       if (ip_addr[i] == 0) return (0);
                    162:       if (ip_addr_match (addr, ip_addr[i])) return (1);
                    163:     }
                    164:   return (0);
                    165: }
                    166: 
                    167: /* these two routines will do routining. */
                    168: static  void
                    169: strict_route(struct ip_header *iph, struct options *opt)
                    170: {
                    171: }
                    172: 
                    173: static  void
                    174: loose_route(struct ip_header *iph, struct options *opt)
                    175: {
                    176: }
                    177: 
                    178: void
                    179: print_rt(struct rtable *rt)
                    180: {
                    181:   PRINTK ("net = %08X router = %08X\n",rt->net, rt->router);
                    182:   PRINTK ("dev = %X, next = %X\n",rt->dev, rt->next);
                    183: }
                    184: 
                    185: void
                    186: print_ipprot (struct ip_protocol *ipprot)
                    187: {
                    188:    PRINTK ("handler = %X, protocol = %d\n",
                    189:           ipprot->handler, ipprot->protocol);
                    190: }
                    191: 
                    192: /* This assumes that address are all in net order. */
                    193: static  struct device *
                    194: ip_route(struct options *opt, unsigned long daddr , unsigned long *raddr)
                    195: {
                    196:   struct rtable *rt;
                    197:   /* look through the routing table for some
                    198:      kind of match. */
                    199:   for (rt=rt_base; rt != NULL; rt=rt->next)
                    200:     {
                    201:       /* see if we found one. */
                    202:       if (ip_addr_match (rt->net, daddr))
                    203:        {
                    204:          *raddr = rt->router;
                    205:          return (rt->dev);
                    206:        }
                    207:     }
                    208:   return (NULL);
                    209: };
                    210: 
                    211: void
                    212: add_route (struct rtable *rt)
                    213: {
                    214:   int mask;
                    215:   struct rtable *r;
                    216:   struct rtable *r1;
                    217:   PRINTK ("add_route (rt=%X):\n",rt);
                    218:   print_rt(rt);
                    219: 
                    220:   if (rt_base == NULL)
                    221:     {
                    222:       rt->next = NULL;
                    223:       rt_base = rt;
                    224:       return;
                    225:     }
                    226: 
                    227:   /* what we have to do is loop though this until we have found the
                    228:      first address which has the same generality as the one in rt.  Then
                    229:      we can put rt in after it. */
                    230:   for (mask = 0xff000000; mask != 0xffffffff; mask = (mask >> 8) | mask)
                    231:     {
                    232:       if (mask & rt->net)
                    233:        {
                    234:          mask = mask << 8;
                    235:          break;
                    236:        }
                    237:     }
                    238:   PRINTK ("mask = %X\n",mask);
                    239:   r1=rt_base;
                    240:   for (r=rt_base; r != NULL; r=r->next)
                    241:     {
                    242:        /* see if we are getting a duplicate. */
                    243:        if (r->net == rt->net)
                    244:         {
                    245:            if (r == rt_base)
                    246:              {
                    247:                 rt->next = r->next;
                    248:                 rt_base = rt;
                    249:              }
                    250:            else
                    251:              {
                    252:                 rt->next = r->next;
                    253:                 r1->next = rt;
                    254:              }
                    255:            free_s (r, sizeof (*r));
                    256:            return;
                    257:         }
                    258: 
                    259:       if (!(r->net & mask))
                    260:        {
                    261:           PRINTK("adding before r=%X\n",r);
                    262:           print_rt(r);
                    263:           if (r == rt_base)
                    264:             {
                    265:                rt->next = rt_base;
                    266:                rt_base = rt;
                    267:                return;
                    268:             }
                    269:           rt->next = r;
                    270:           r1->next = rt;
                    271:           return;
                    272:        }
                    273:       r1 = r;
                    274:     }
                    275:   PRINTK ("adding after r1=%X\n",r1);
                    276:   print_rt(r1);
                    277:   /* goes at the end. */
                    278:   rt->next = NULL;
                    279:   r1->next = rt;
                    280: }
                    281: 
                    282: int
                    283: ip_set_dev (struct ip_config *u_ipc)
                    284: {
                    285:   struct rtable *rt;
                    286:   struct device *dev;
                    287:   struct ip_config ipc;
                    288:   static int ip_ads = 0;
                    289: 
                    290:   if (ip_ads >= MAX_IP_ADDRES) return (-EINVAL);
                    291: 
                    292:   verify_area (u_ipc, sizeof (ipc));
                    293:   memcpy_fromfs(&ipc, u_ipc, sizeof (ipc));
                    294:   ipc.name[MAX_IP_NAME-1] = 0;
                    295:   dev = get_dev (ipc.name);
                    296: 
                    297:   if (dev == NULL) return (-EINVAL);
                    298: 
                    299:   /* see if we need to add a broadcast address. */
                    300:   if (ipc.net != -1)
                    301:     {
                    302:        arp_add_broad (ipc.net, dev);
                    303:        rt = malloc (sizeof (*rt));
                    304:        if (rt == NULL) return (-ENOMEM);
                    305: 
                    306:        rt->net = ipc.net;
                    307:        rt->dev = dev;
                    308:        rt->router = 0;
                    309:        add_route (rt);
                    310: /*     dev->net = ipc.net;*/
                    311:     }
                    312: 
                    313:   if (ipc.router != -1)
                    314:     {
                    315:        rt = malloc (sizeof (*rt));
                    316:        if (rt == NULL) return (-ENOMEM);
                    317:        rt->net = 0;
                    318:        rt->dev = dev;
                    319:        rt->router = ipc.router;
                    320:        add_route (rt);
                    321:     }
                    322: 
                    323:   if (dev->loopback)
                    324:     {
                    325:        rt = malloc (sizeof (*rt));
                    326:        if (rt == NULL) return (-ENOMEM);
                    327:        rt->net = ipc.paddr;
                    328:        rt->dev = dev;
                    329:        rt->router = 0;
                    330:        add_route (rt);
                    331: 
                    332:     }
                    333: 
                    334: 
                    335:   if (!my_ip_addr (ipc.paddr))
                    336:     ip_addr[ip_ads++] = ipc.paddr;
                    337: 
                    338:   dev->up = ipc.up;
                    339:   if (dev->up)
                    340:     {
                    341:        if (dev->open)
                    342:         dev->open(dev);
                    343:     }
                    344:   else
                    345:     {
                    346:        if (dev->stop)
                    347:         dev->stop(dev);
                    348:     }
                    349:   return (0);
                    350: 
                    351: }
                    352: 
                    353: /* this routine will check to see if we have lost a gateway. */
                    354: void
                    355: ip_route_check (unsigned long daddr)
                    356: {
                    357: }
                    358: 
                    359: /* this routine puts the options at the end of an ip header. */
                    360: static  int
                    361: build_options (struct ip_header *iph, struct options *opt)
                    362: {
                    363:   unsigned char *ptr;
                    364:   /* currently we don't support any options. */
                    365:   ptr = (unsigned char *)(iph+1);
                    366:   *ptr = 0;
                    367:   return (4);
                    368: }
                    369: 
                    370: /* This routine builds the appropriate hardware/ip headers for
                    371:    the routine.  It assumes that if *prot != NULL then the
                    372:    protocol knows what it's doing, otherwise it uses the
                    373:    routing/arp tables to select a protocol struct. */
                    374: 
                    375: int
                    376: ip_build_header (struct sk_buff *skb, unsigned long saddr,
                    377:                 unsigned long daddr, struct device **dev, int type,
                    378:                 struct options *opt, int len)
                    379: {
                    380:   static struct options optmem;
                    381:   struct ip_header *iph;
                    382:   unsigned char *buff;
                    383:   static int count = 0;
                    384:   unsigned long raddr; /* for the router. */
                    385:   int tmp;
                    386:   if (saddr == 0) saddr = MY_IP_ADDR;
                    387:   PRINTK ("ip_build_header (skb=%X, saddr=%X, daddr=%X, *dev=%X,\n"
                    388:          "                 type=%d, opt=%X, len = %d)\n",
                    389:          skb, saddr, daddr, *dev, type, opt, len);
                    390:   buff = (unsigned char *)(skb + 1);
                    391:   /* see if we need to look up the device. */
                    392:   if (*dev == NULL)
                    393:     {
                    394:       *dev = ip_route(&optmem,daddr, &raddr);
                    395:       if (*dev == NULL)
                    396:        {
                    397:          return (-ENETUNREACH);
                    398:        }
                    399:       opt = &optmem;
                    400:     }
                    401:   else
                    402:     {
                    403:       /* we still need the address of the first hop. */
                    404:       ip_route (&optmem, daddr, &raddr);
                    405:     }
                    406:   if (raddr == 0) raddr = daddr;
                    407:   /* now build the header. */
                    408:   /* we need to worry about routing in here.  daddr should
                    409:      really be the address of the next hop. */
                    410:   /* but raddr is . */
                    411:   if ((*dev)->hard_header)
                    412:     {
                    413:        tmp = (*dev)->hard_header(buff, *dev, ETHERTYPE_IP, raddr, saddr, len);
                    414:     }
                    415:   else
                    416:     {
                    417:        tmp = 0;
                    418:     }
                    419:   if (tmp < 0)
                    420:     {
                    421:        tmp = -tmp;
                    422:        skb->arp = 0;
                    423:     }
                    424:   else
                    425:     {
                    426:        skb->arp = 1;
                    427:     }
                    428:   buff += tmp;
                    429:   len -= tmp;
                    430:   skb->dev = *dev;
                    431:   /* now build the ip header. */
                    432:   iph = (struct ip_header *)buff;
                    433:   iph->version = 4;
                    434:   iph->tos = 0;
                    435:   iph->frag_off = 0;
                    436:   iph->ttl = 32;
                    437:   iph->daddr = daddr;
                    438:   iph->saddr = saddr;
                    439:   iph->protocol=type;
                    440:   iph->ihl = 5;
                    441:   iph->id = net16(count++);
                    442:   /* build_options (iph, opt);*/
                    443:   return (20+tmp);
                    444: }
                    445: 
                    446: static  int
                    447: do_options(struct ip_header *iph, struct options *opt)
                    448: {
                    449:   unsigned char *buff;
                    450:   int done = 0;
                    451:   int len=sizeof (*iph);
                    452:   int i;
                    453:   /* zero  out the options. */
                    454:   opt->record_route.route_size = 0;
                    455:   opt->loose_route.route_size = 0;
                    456:   opt->strict_route.route_size = 0;
                    457:   opt->tstamp.ptr = 0;
                    458:   opt->security = 0;
                    459:   opt->compartment = 0;
                    460:   opt->handling = 0;
                    461:   opt->stream = 0;
                    462:   opt->tcc = 0;
                    463:   return (0);
                    464:   /* advance the pointer to start at the options. */
                    465:   buff = (unsigned char *)(iph + 1);
                    466: 
                    467:   /*now start the processing. */
                    468:   while (!done && len < iph->ihl*4)
                    469:     {
                    470:       switch (*buff)
                    471:        {
                    472:        case IPOPT_END:
                    473:          done=1;
                    474:          break;
                    475: 
                    476:        case IPOPT_NOOP:
                    477:          buff++;
                    478:          len ++;
                    479:          break;
                    480: 
                    481:        case IPOPT_SEC:
                    482:          buff++;
                    483:          if (*buff != 11)
                    484:            return (1);
                    485:          buff++;
                    486:          opt->security = net16(*(unsigned short *)buff);
                    487:          buff += 2;
                    488:          opt->compartment = net16(*(unsigned short *)buff);
                    489:          buff += 2;
                    490:          opt-> handling = net16(*(unsigned short *)buff);
                    491:          buff += 2;
                    492:          opt->tcc = ((*buff) << 16) + net16(*(unsigned short *)(buff+1));
                    493:          buff += 3;
                    494:          len += 11;
                    495:          break;
                    496: 
                    497:        case IPOPT_LSRR:
                    498:          buff ++;
                    499:          if ((*buff - 3)% 4 != 0) return (1);
                    500:          len += *buff;
                    501:          opt->loose_route.route_size = (*buff -3)/4;
                    502:          buff ++;
                    503:          if (*buff % 4 != 0) return (1);
                    504:          opt->loose_route.pointer = *buff/4 - 1;
                    505:          buff ++;
                    506:          buff ++;
                    507:          for (i = 0; i < opt->loose_route.route_size; i++)
                    508:            {
                    509:              opt->loose_route.route[i]=*(unsigned long *)buff;
                    510:              buff += 4;
                    511:            }
                    512:          break;
                    513: 
                    514: 
                    515:        case IPOPT_SSRR:
                    516:          buff ++;
                    517:          if ((*buff - 3)% 4 != 0) return (1);
                    518:          len += *buff;
                    519:          opt->strict_route.route_size = (*buff -3)/4;
                    520:          buff ++;
                    521:          if (*buff % 4 != 0) return (1);
                    522:          opt->strict_route.pointer = *buff/4 - 1;
                    523:          buff ++;
                    524:          buff ++;
                    525:          for (i = 0; i < opt->strict_route.route_size; i++)
                    526:            {
                    527:              opt->strict_route.route[i]=*(unsigned long *)buff;
                    528:              buff += 4;
                    529:            }
                    530:          break;
                    531: 
                    532:        case IPOPT_RR:
                    533:          buff ++;
                    534:          if ((*buff - 3)% 4 != 0) return (1);
                    535:          len += *buff;
                    536:          opt->record_route.route_size = (*buff -3)/4;
                    537:          buff ++;
                    538:          if (*buff % 4 != 0) return (1);
                    539:          opt->record_route.pointer = *buff/4 - 1;
                    540:          buff ++;
                    541:          buff ++;
                    542:          for (i = 0; i < opt->record_route.route_size; i++)
                    543:            {
                    544:              opt->record_route.route[i]=*(unsigned long *)buff;
                    545:              buff += 4;
                    546:            }
                    547:          break;
                    548: 
                    549:        case IPOPT_SID:
                    550:          len += 4;
                    551:          buff +=2;
                    552:          opt->stream = *(unsigned short *)buff;
                    553:          buff += 2;
                    554:          break;
                    555: 
                    556:        case IPOPT_TIMESTAMP:
                    557:          buff ++;
                    558:          len += *buff;
                    559:          if (*buff % 4 != 0) return (1);
                    560:          opt->tstamp.len = *buff / 4 - 1;
                    561:          buff ++;
                    562:          if ((*buff - 1) % 4 != 0) return (1);
                    563:          opt->tstamp.ptr = (*buff-1)/4;
                    564:          buff ++;
                    565:          opt->tstamp.x.full_char = *buff;
                    566:          buff ++;
                    567:          for (i = 0; i < opt->tstamp.len; i++)
                    568:            {
                    569:              opt->tstamp.data[i] = *(unsigned long *)buff;
                    570:              buff += 4;
                    571:            }
                    572:          break;
                    573: 
                    574:        default:
                    575:          return (1);
                    576:        }
                    577:     }
                    578:   if (opt->record_route.route_size == 0)
                    579:     {
                    580:       if (opt->strict_route.route_size != 0)
                    581:        {
                    582:          memcpy (&(opt->record_route), &(opt->strict_route),
                    583:                  sizeof (opt->record_route));
                    584:        }
                    585:       else if (opt->loose_route.route_size != 0)
                    586:        {
                    587:          memcpy (&(opt->record_route), &(opt->loose_route),
                    588:                  sizeof (opt->record_route));
                    589:        }
                    590:     }
                    591: 
                    592:   if (opt->strict_route.route_size != 0 &&
                    593:       opt->strict_route.route_size != opt->strict_route.pointer)
                    594:     {
                    595:       strict_route (iph, opt);
                    596:       return (0);
                    597:     }
                    598: 
                    599:   if (opt->loose_route.route_size != 0 &&
                    600:       opt->loose_route.route_size != opt->loose_route.pointer)
                    601:     {
                    602:       loose_route (iph, opt);
                    603:       return (0);
                    604:     }
                    605: 
                    606:   return (0);
                    607: }
                    608: 
                    609: 
                    610: /* This routine does all the checksum computations that don't require
                    611:    anything special (like copying or special headers.) */
                    612: 
                    613: unsigned short
                    614: ip_compute_csum(unsigned char * buff, int len)
                    615: {
                    616:   unsigned long sum = 0;
                    617:   if (len > 3)
                    618:     {
                    619:        /* do the first multiple of 4 bytes and convert to 16 bits. */
                    620:        __asm__("\t clc\n"
                    621:               "1:\n"
                    622:               "\t lodsl\n"
                    623:               "\t adcl %%eax, %%ebx\n"
                    624:               "\t loop 1b\n"
                    625:               "\t adcl $0, %%ebx\n"
                    626:               "\t movl %%ebx, %%eax\n"
                    627:               "\t shrl $16, %%eax\n"
                    628:               "\t addw %%ax, %%bx\n"
                    629:               "\t adcw $0, %%bx\n"
                    630:               : "=b" (sum) , "=S" (buff)
                    631:               : "0" (sum), "c" (len >> 2) ,"1" (buff)
                    632:               : "ax", "cx", "si", "bx" );
                    633:     }
                    634:   if (len & 2)
                    635:     {
                    636:        __asm__("\t lodsw\n"
                    637:               "\t addw %%ax, %%bx\n"
                    638:               "\t adcw $0, %%bx\n"
                    639:               : "=b" (sum), "=S" (buff)
                    640:               : "0" (sum), "1" (buff)
                    641:               : "bx", "ax", "si");
                    642:     }
                    643:   if (len & 1)
                    644:     {
                    645:        __asm__("\t lodsb\n"
                    646:               "\t movb $0, %%ah\n"
                    647:               "\t addw %%ax, %%bx\n"
                    648:               "\t adcw $0, %%bx\n"
                    649:               : "=b" (sum), "=S" (buff)
                    650:               : "0" (sum), "1" (buff)
                    651:               : "bx", "ax", "si");
                    652:     }
                    653:   sum =~sum;
                    654:   return (sum&0xffff);
                    655: }
                    656: 
                    657: static  int
                    658: ip_csum(struct ip_header *iph)
                    659: {
                    660:   if (iph->check == 0) return (0);
                    661:   if (ip_compute_csum((unsigned char *)iph, iph->ihl*4) == 0)  return (0);
                    662:   return (1);
                    663: }
                    664: 
                    665: static  void
                    666: ip_send_check(struct ip_header *iph)
                    667: {
                    668:    iph->check = 0;
                    669:    iph->check = ip_compute_csum((unsigned char *)iph, iph->ihl*4);
                    670: }
                    671: 
                    672: int
                    673: ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
                    674: {
                    675:   struct ip_header *iph;
                    676:   unsigned char hash;
                    677:   unsigned char flag=0;
                    678:   static struct options opt; /* since we don't use these yet, and they
                    679:                                take up stack space. */
                    680:   struct ip_protocol *ipprot;
                    681: 
                    682:   iph=skb->h.iph;
                    683: 
                    684:   PRINTK("<<\n");
                    685:   print_iph(iph);
                    686: 
                    687:   if (ip_csum (iph) || do_options (iph,&opt) || iph->version != 4)
                    688:     {
                    689:        PRINTK ("ip packet thrown out. \n");
                    690:        skb->sk = NULL;
                    691:        free_skb(skb, 0);
                    692:        return (0);
                    693:     }
                    694: 
                    695:   /* for now we will only deal with packets meant for us. */
                    696:   if (!my_ip_addr(iph->daddr))
                    697:     {
                    698:        PRINTK ("packet meant for someone else.\n");
                    699:        skb->sk = NULL;
                    700:        free_skb(skb, 0);
                    701:        return (0);
                    702:     }
                    703: 
                    704:   /* deal with fragments.  or don't for now.*/
                    705:   if ((iph->frag_off & 64) || (net16(iph->frag_off)&0x1fff))
                    706:     {
                    707:        printk ("packet fragmented. \n");
                    708:        skb->sk = NULL;
                    709:        free_skb(skb, 0);
                    710:        return(0);
                    711:     }
                    712: 
                    713:   skb->h.raw += iph->ihl*4;
                    714: 
                    715:   /* add it to the arp table if it's talking to us.  That way we
                    716:      will be able to talk to them also. */
                    717: 
                    718:   hash = iph->protocol & (MAX_IP_PROTOS -1);
                    719:   for (ipprot = ip_protos[hash]; ipprot != NULL; ipprot=ipprot->next)
                    720:     {
                    721:        struct sk_buff *skb2;
                    722:        PRINTK ("Using protocol = %X:\n", ipprot);
                    723:        print_ipprot (ipprot);
                    724:        /* pass it off to everyone who wants it. */
                    725:        /* we should check the return values here. */
                    726:        /* see if we need to make a copy of it.  This will
                    727:          only be set if more than one protpocol wants it. 
                    728:          and then not for the last one. */
                    729: 
                    730:        if (ipprot->copy)
                    731:         {
                    732:            skb2 = malloc (skb->mem_len);
                    733:            if (skb2 == NULL) continue;
                    734:            memcpy (skb2, skb, skb->mem_len);
                    735:            skb2->mem_addr = skb2;
                    736:         }
                    737:        else
                    738:         {
                    739:            skb2 = skb;
                    740:         }
                    741:        flag = 1;
                    742:        ipprot->handler (skb2, dev, &opt, iph->daddr,
                    743:                        net16(iph->tot_len) - iph->ihl*4,
                    744:                        iph->saddr, 0, ipprot);
                    745: 
                    746:     }
                    747:   if (!flag)
                    748:     {
                    749:        icmp_reply (skb, ICMP_DEST_UNREACH, ICMP_PROT_UNREACH, dev);
                    750:        skb->sk = NULL;
                    751:        free_skb (skb, 0);
                    752:     }
                    753: 
                    754: 
                    755:   return (0);
                    756: }
                    757: 
                    758: 
                    759: /* queues a packet to be sent, and starts the transmitter if
                    760:    necessary.  if free = 1 then we free the block after transmit,
                    761:    otherwise we don't. */
                    762: /* This routine also needs to put in the total length, and compute
                    763:    the checksum. */
                    764: void
                    765: ip_queue_xmit (volatile struct sock *sk, struct device *dev, 
                    766:               struct sk_buff *skb, int free)
                    767: {
                    768:   struct ip_header *iph;
                    769:   unsigned char *ptr;
                    770:   if (sk == NULL) free = 1;
                    771:   skb->free = free;
                    772:   skb->dev = dev;
                    773:   skb->when = jiffies;
                    774:   PRINTK(">>\n");
                    775:   ptr = (unsigned char *)(skb + 1);
                    776:   ptr += dev->hard_header_len;
                    777:   iph = (struct ip_header *)ptr;
                    778:   iph->tot_len = net16(skb->len-dev->hard_header_len);
                    779:   ip_send_check (iph);
                    780:   print_iph(iph);
                    781:   skb->next = NULL;
                    782:   if (!free)
                    783:     {
                    784:       skb->link3 = NULL;
                    785:       sk->packets_out++;
                    786:       cli();
                    787:       if (sk->send_tail == NULL)
                    788:        {
                    789:          sk->send_tail = skb;
                    790:          sk->send_head = skb;
                    791:        }
                    792:       else
                    793:        {
                    794:          sk->send_tail->link3 = skb;
                    795:          sk->send_tail = skb;
                    796:        }
                    797:       sti();
                    798:       sk->time_wait.len = sk->rtt*2;
                    799:       sk->timeout=TIME_WRITE;
                    800:       reset_timer ((struct timer *)&sk->time_wait);
                    801:    }
                    802:   else
                    803:     {
                    804:        skb->sk = sk;
                    805:     }
                    806:   if (dev->up)
                    807:     {
                    808:        if (sk)
                    809:         dev->queue_xmit(skb, dev, sk->priority);
                    810:        else
                    811:         dev->queue_xmit (skb, dev, SOPRI_NORMAL);
                    812:     }
                    813:   else
                    814:     {
                    815:        if (free) 
                    816:         free_skb (skb, FREE_WRITE);
                    817:     }
                    818: }
                    819: 
                    820: void
                    821: ip_retransmit (volatile struct sock *sk, int all)
                    822: {
                    823:   struct sk_buff * skb;
                    824:   struct proto *prot;
                    825:   struct device *dev;
                    826: 
                    827:   prot = sk->prot;
                    828:   skb = sk->send_head;
                    829:   while (skb != NULL)
                    830:     {
                    831:       dev = skb->dev;
                    832:       /* rebuild_header sees if the arp is done.  If not it sends a new
                    833:         arp, and if so it builds the header. */
                    834:       if (!skb->arp)
                    835:        {
                    836:          if (dev->rebuild_header ((struct enet_header *)(skb+1),dev))
                    837:            {
                    838:               if (!all) break;
                    839:               skb=skb->link3;
                    840:               continue;
                    841:            }
                    842:        }
                    843:       skb->arp = 1;
                    844:       skb->when = jiffies;
                    845: 
                    846:       if (dev->up)
                    847:        if (sk)
                    848:          dev->queue_xmit(skb, dev, sk->priority);
                    849:        else
                    850:          dev->queue_xmit(skb, dev, SOPRI_NORMAL );
                    851: 
                    852:       sk->retransmits++;
                    853:       sk->prot->retransmits ++;
                    854:       if (!all) break;
                    855:       /* this should cut it off before we send too
                    856:         many packets. */
                    857:       if (sk->retransmits > sk->cong_window) break;
                    858:       skb=skb->link3;
                    859:     }
                    860:   sk->time_wait.len = sk->rtt*2;
                    861:   sk->timeout = TIME_WRITE;
                    862:   reset_timer ((struct timer *)&sk->time_wait);
                    863: }
                    864: 
                    865: void
                    866: print_iph (struct ip_header *ip)
                    867: {
                    868:   PRINTK ("ip header:\n");
                    869:   PRINTK ("  ihl = %d, version = %d, tos = %d, tot_len = %d\n",
                    870:          ip->ihl, ip->version, ip->tos, net16(ip->tot_len));
                    871:   PRINTK ("  id = %x, ttl = %d, prot = %d, check=%x\n",
                    872:          ip->id, ip->ttl, ip->protocol, ip->check);
                    873:   PRINTK (" frag_off=%d\n", ip->frag_off);
                    874:   PRINTK ("  saddr = %X, daddr = %X\n",ip->saddr, ip->daddr);
                    875: }
                    876: 
                    877: #if 0
                    878: int
                    879: ip_handoff (volatile struct sock *sk)
                    880: {
                    881:    struct ip_protocol *p;
                    882:    struct sk_buff *skb;
                    883:    p = get_protocol (sk->protocol);
                    884: 
                    885:    if (p == NULL)
                    886:      {
                    887:        /* this can never happen. */
                    888:        printk ("sock_ioctl: protocol not found. \n");
                    889:        /* what else can I do, I suppose I could send a sigkill. */
                    890:        return (-EIO);
                    891:      }
                    892: 
                    893:    while (p->handler != sk->prot->rcv)
                    894:      {
                    895:        p=p->next;
                    896:        if (p == NULL)
                    897:          {
                    898:             /* this can never happen. */
                    899:             printk ("sock_ioctl: protocol not found. \n");
                    900:             /* what else can I do, I suppose I could send a sigkill. */
                    901:             return (-EIO);
                    902:          }
                    903:      }
                    904:    p = p-> next;
                    905:    sk->inuse = 1;
                    906:    
                    907:    /* now we have to remove the top sock buff.  If there are none, then
                    908:       we return. */
                    909:    if (sk->rqueue == NULL) return (0);
                    910:    skb = sk->rqueue;
                    911:    if (skb->next == skb)
                    912:      {
                    913:        sk->rqueue = NULL;
                    914:      }
                    915:    else
                    916:      {
                    917:        sk->rqueue = skb->next;
                    918:        skb->next->prev = skb->prev;
                    919:        skb->prev->next = skb->next;
                    920:      }
                    921:    if (p != NULL)
                    922:      {
                    923:        p->handler ((unsigned char *)(skb+1), skb->dev, NULL, skb->saddr,
                    924:                    skb->len, skb->daddr, p->protocol, 0);
                    925:      }
                    926:    free_skb (skb, FREE_READ);
                    927:    release_sock (sk);
                    928:    return (0);
                    929: }
                    930: 
                    931: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.