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

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