root/net/tcp/ip.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. in_ntoa
  2. get_protocol
  3. add_ip_protocol
  4. delete_ip_protocol
  5. ip_addr_match
  6. my_ip_addr
  7. strict_route
  8. loose_route
  9. print_rt
  10. print_ipprot
  11. ip_route
  12. del_devroute
  13. add_route
  14. ip_set_dev
  15. ip_route_check
  16. build_options
  17. ip_build_header
  18. do_options
  19. ip_compute_csum
  20. ip_csum
  21. ip_send_check
  22. ip_rcv
  23. ip_queue_xmit
  24. ip_retransmit
  25. print_iph

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

/* [previous][next][first][last][top][bottom][index][help] */