root/net/tcp/ip.c

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

DEFINITIONS

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

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

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