root/net/tcp/arp.c

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

DEFINITIONS

This source file includes following definitions.
  1. send_arp_q
  2. print_arp
  3. arp_sourceh
  4. arp_targeth
  5. arp_sourcep
  6. arp_targetp
  7. arp_free
  8. arp_malloc
  9. arp_response
  10. arp_lookup
  11. arp_destroy
  12. create_arp
  13. arp_rcv
  14. arp_snd
  15. arp_find
  16. arp_add
  17. arp_add_broad
  18. arp_queue

   1 /* arp.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: arp.c,v 0.8.4.5 1992/12/12 19:25:04 bir7 Exp $ */
  23 /* $Log: arp.c,v $
  24  * Revision 0.8.4.5  1992/12/12  19:25:04  bir7
  25  * Cleaned up Log messages.
  26  *
  27  * Revision 0.8.4.4  1992/12/03  19:52:20  bir7
  28  * Added paranoid queue checking.
  29  *
  30  * Revision 0.8.4.3  1992/11/15  14:55:30  bir7
  31  * Put more cli/sti pairs in send_q and another sanity check
  32  * in arp_queue.
  33  *
  34  * Revision 0.8.4.2  1992/11/10  10:38:48  bir7
  35  * Change free_s to kfree_s and accidently changed free_skb to kfree_skb.
  36  *
  37  * Revision 0.8.4.1  1992/11/10  00:17:18  bir7
  38  * version change only.
  39  *
  40  * Revision 0.8.3.3  1992/11/10  00:14:47  bir7
  41  * Changed malloc to kmalloc and added Id and Log
  42  *
  43  */
  44 
  45 #include <linux/types.h>
  46 #include <linux/string.h>
  47 #include <linux/kernel.h>
  48 #include <linux/sched.h>
  49 #include <linux/config.h>
  50 
  51 #include <linux/socket.h>
  52 #include <netinet/in.h>
  53 #include <asm/system.h>
  54 
  55 #include "timer.h"
  56 #include "ip.h"
  57 #include "tcp.h"
  58 #include "sock.h"
  59 #include "arp.h"
  60 
  61 #undef ARP_DEBUG
  62 #ifdef  ARP_DEBUG
  63 #define PRINTK printk
  64 #else
  65 #define PRINTK dummy_routine
  66 #endif
  67 
  68 static struct arp_table *arp_table[ARP_TABLE_SIZE] ={NULL, };
  69 struct sk_buff *arp_q=NULL;
  70 
  71 /* this will try to retransmit everything on the queue. */
  72 static void
  73 send_arp_q(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  74 {
  75    struct sk_buff *skb;
  76    struct sk_buff *skb2;
  77 
  78    cli();
  79    if (arp_q == NULL) return;
  80 
  81    skb = arp_q;
  82    do {
  83      if (skb->magic != ARP_QUEUE_MAGIC)
  84        {
  85          printk ("arp.c skb with bad magic - %X: squashing queue\n");
  86          cli();
  87          arp_q = NULL;
  88          sti();
  89          return;
  90        }
  91      /* extra consistancy check. */
  92      if (skb->next == NULL
  93 #ifdef CONFIG_MAX_16M
  94          || (unsigned long)(skb->next) > 16*1024*1024
  95 #endif
  96          )
  97 
  98        {
  99          printk ("dev.c: *** bug bad skb->next, squashing queue \n");
 100          cli();
 101          arp_q = NULL;
 102          sti();
 103          return;
 104        }
 105 
 106      skb->magic = 0;
 107      skb2=skb->next;
 108 
 109      sti();
 110      if (!skb->dev->rebuild_header (skb+1, skb->dev))
 111        {
 112           cli();
 113            if (skb->next == skb)
 114              {
 115                 arp_q = NULL;
 116              }
 117            else
 118              {
 119                 skb->next->prev = skb->prev;
 120                 skb->prev->next = skb->next;
 121                 arp_q = skb->next;
 122              }
 123            skb->next = NULL;
 124            skb->prev = NULL;
 125            skb->arp  = 1;
 126           sti();
 127            skb->dev->queue_xmit (skb, skb->dev, 0);
 128 
 129           if (arp_q == NULL) break;
 130 
 131            cli();
 132         }
 133       skb=skb2;
 134    } while (skb != arp_q);
 135    sti();
 136 
 137 }
 138 
 139 static  void
 140 print_arp(struct arp *arp)
     /* [previous][next][first][last][top][bottom][index][help] */
 141 {
 142   int i;
 143   unsigned long *lptr;
 144   unsigned char *ptr;
 145   PRINTK ("arp: \n");
 146   if (arp == NULL)
 147     {
 148       PRINTK ("(null)\n");
 149       return;
 150     }
 151   PRINTK ("   hrd = %d\n",net16(arp->hrd));
 152   PRINTK ("   pro = %d\n",net16(arp->pro));
 153   PRINTK ("   hlen = %d plen = %d\n",arp->hlen, arp->plen);
 154   PRINTK ("   op = %d\n", net16(arp->op));
 155   ptr = (unsigned char *)(arp+1);
 156   PRINTK ("   sender haddr = ");
 157   for (i = 0; i < arp->hlen; i++)
 158     {
 159       PRINTK ("0x%02X ",*ptr++);
 160     }
 161   lptr = (void *)ptr;
 162   PRINTK (" send paddr = %X\n",*lptr);
 163   lptr ++;
 164   ptr = (void *)lptr;
 165   PRINTK ("   destination haddr = ");
 166   for (i = 0; i < arp->hlen; i++)
 167     {
 168       PRINTK ("0x%02X ",*ptr++);
 169     }
 170   lptr = (void *)ptr;
 171   PRINTK (" destination paddr = %X\n",*lptr);
 172 }
 173 
 174 static  unsigned char *
 175 arp_sourceh(struct arp *arp)
     /* [previous][next][first][last][top][bottom][index][help] */
 176 {
 177   unsigned char *ptr;
 178   ptr = (unsigned char *)(arp + 1);
 179   return (ptr);
 180 }
 181 
 182 static  unsigned char *
 183 arp_targeth(struct arp *arp)
     /* [previous][next][first][last][top][bottom][index][help] */
 184 {
 185   unsigned char *ptr;
 186   ptr = (unsigned char *)(arp + 1);
 187   ptr += arp->hlen+4;
 188   return (ptr);
 189 }
 190 
 191 static  unsigned long *
 192 arp_sourcep(struct arp *arp)
     /* [previous][next][first][last][top][bottom][index][help] */
 193 {
 194   unsigned long *lptr;
 195   unsigned char *ptr;
 196   ptr = (unsigned char *)(arp + 1);
 197   ptr += arp->hlen;
 198   lptr = (unsigned long *)ptr;
 199   return (lptr);
 200 }
 201 
 202 
 203 static  unsigned long *
 204 arp_targetp(struct arp *arp)
     /* [previous][next][first][last][top][bottom][index][help] */
 205 {
 206   unsigned long *lptr;
 207   unsigned char *ptr;
 208   ptr = (unsigned char *)(arp + 1);
 209   ptr += 2*arp->hlen+4;
 210   lptr = (unsigned long *)ptr;
 211   return (lptr);
 212 }
 213 
 214 static  void
 215 arp_free (void *ptr, unsigned long len)
     /* [previous][next][first][last][top][bottom][index][help] */
 216 {
 217   kfree_s(ptr, len);
 218 }
 219 
 220 static  void *
 221 arp_malloc (unsigned long amount, int priority)
     /* [previous][next][first][last][top][bottom][index][help] */
 222 {
 223   return (kmalloc (amount, priority));
 224 }
 225 
 226 static  int
 227 arp_response (struct arp *arp1, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 228 {
 229   struct arp *arp2;
 230   struct sk_buff *skb;
 231   int tmp;
 232 
 233   /* get some mem and initialize it for the return trip. */
 234   skb = arp_malloc (sizeof (*skb) + sizeof (*arp2) +
 235                     2*arp1->hlen + 2*arp1->plen + dev->hard_header_len,
 236                     GFP_ATOMIC);
 237   if (skb == NULL) return (1);
 238 
 239   skb->lock = 0;
 240   skb->mem_addr = skb;
 241   skb->mem_len = sizeof (*skb) + sizeof (*arp2) + 2*arp1->hlen + 
 242     2*arp1->plen + dev->hard_header_len;
 243   skb->len = sizeof (*arp2) + 2*arp1->hlen + 
 244     2*arp1->plen + dev->hard_header_len;
 245 
 246   tmp = dev->hard_header((unsigned char *)(skb+1), dev,
 247                          ETHERTYPE_ARP, *arp_sourcep(arp1),
 248                          *arp_targetp(arp1),skb->len);
 249 
 250   if (tmp < 0) return (1);
 251 
 252   arp2 =(struct arp *) ((unsigned char *)skb+sizeof (*skb) + tmp );
 253   memcpy (arp2, arp1, sizeof (*arp2));
 254 
 255   /* now swap the addresses. */
 256   *arp_sourcep(arp2) = *arp_targetp(arp1);
 257   memcpy(arp_sourceh(arp2), dev->dev_addr, arp1->hlen);
 258 
 259   *arp_targetp(arp2) = *arp_sourcep(arp1);
 260   memcpy(arp_targeth(arp2), arp_sourceh(arp1), arp1->hlen);
 261 
 262   arp2->op = NET16(ARP_REPLY);
 263   skb->free = 1;
 264   skb->arp = 1; /* so the code will know it's not waiting on an arp. */
 265   skb->sk = NULL;
 266   skb->next = NULL;
 267   PRINTK (">>");
 268   print_arp(arp2);
 269   /* send it. */
 270   dev->queue_xmit (skb, dev, 0);
 271   return (0);
 272 }
 273 
 274 /* This will find an entry in the arp table by looking at the ip
 275    address. */
 276 static  struct arp_table *
 277 arp_lookup (unsigned long paddr)
     /* [previous][next][first][last][top][bottom][index][help] */
 278 {
 279   unsigned long hash;
 280   struct arp_table *apt;
 281   PRINTK ("arp_lookup(paddr=%X)\n", paddr);
 282   /* we don't want to arp ourselves. */
 283   if (my_ip_addr(paddr)) return (NULL);
 284   hash = net32(paddr) & (ARP_TABLE_SIZE - 1);
 285   cli();
 286   for (apt = arp_table[hash]; apt != NULL; apt = apt->next)
 287     {
 288       if (apt->ip == paddr)
 289         {
 290            sti();
 291            return (apt);
 292         }
 293     }
 294   sti();
 295   return (NULL);
 296 }
 297 
 298 void
 299 arp_destroy(unsigned long paddr)
     /* [previous][next][first][last][top][bottom][index][help] */
 300 {
 301   unsigned long hash;
 302   struct arp_table *apt;
 303   struct arp_table *lapt;
 304   PRINTK ("arp_destroy (paddr=%X)\n",paddr);
 305   /* we don't want to destroy are own arp */
 306   if (my_ip_addr(paddr)) return;
 307   hash = net32(paddr) & (ARP_TABLE_SIZE - 1);
 308 
 309   cli(); /* can't be interrupted. */
 310   /* make sure there is something there. */
 311   if (arp_table[hash] == NULL) return;
 312 
 313   /* check the first one. */
 314   if (arp_table[hash]->ip == paddr)
 315     {
 316       apt = arp_table[hash];
 317       arp_table[hash] = arp_table[hash]->next;
 318       arp_free (apt, sizeof (*apt));
 319       sti();
 320       return;
 321     }
 322 
 323   /* now deal with it any where else in the chain. */
 324   lapt = arp_table[hash];
 325   for (apt = arp_table[hash]->next; apt != NULL; apt = apt->next)
 326     {
 327       if (apt->ip == paddr) 
 328         {
 329           lapt->next = apt->next;
 330           arp_free (apt, sizeof (*apt));
 331           sti();
 332           return;
 333         }
 334     }
 335   sti();
 336 }
 337 
 338 /* this routine does not check for duplicates.  It assumes the caller
 339    does. */
 340 static  struct arp_table *
 341 create_arp (unsigned long paddr, unsigned char *addr, int hlen)
     /* [previous][next][first][last][top][bottom][index][help] */
 342 {
 343   struct arp_table *apt;
 344   unsigned long hash;
 345   apt = arp_malloc (sizeof (*apt), GFP_ATOMIC);
 346   if (apt == NULL) return (NULL);
 347 
 348   hash = net32(paddr) & (ARP_TABLE_SIZE - 1);
 349   apt->ip = paddr;
 350   apt->hlen =hlen;
 351   memcpy (apt->hard, addr, hlen);
 352   apt->last_used=timer_seq;
 353   cli();
 354   apt->next = arp_table[hash];
 355   arp_table[hash] = apt;
 356   sti();
 357   return (apt);
 358 }
 359 
 360 int
 361 arp_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
     /* [previous][next][first][last][top][bottom][index][help] */
 362 {
 363    struct arp *arp;
 364    struct arp_table *tbl;
 365    int ret;
 366 
 367    PRINTK ("<<\n");
 368    arp = skb->h.arp;
 369    print_arp(arp);
 370 
 371   /* if this test doesn't pass, something fishy is going on. */
 372   if (arp->hlen != dev->addr_len || dev->type !=NET16( arp->hrd))
 373     {
 374        kfree_skb(skb, FREE_READ);
 375        return (0);
 376     }
 377 
 378   /* for now we will only deal with ip addresses. */
 379   if (arp->pro != NET16(ARP_IP_PROT) || arp->plen != 4)
 380     {
 381        kfree_skb (skb, FREE_READ);
 382        return (0);
 383     }
 384 
 385   /* now look up the ip address in the table. */
 386   tbl = arp_lookup (*arp_sourcep(arp));
 387   if (tbl != NULL)
 388     {
 389        memcpy (tbl->hard, arp+1, arp->hlen);
 390        tbl->hlen = arp->hlen;
 391        tbl->last_used = timer_seq;
 392     }
 393 
 394   if (!my_ip_addr(*arp_targetp(arp)))
 395     {
 396        kfree_skb (skb, FREE_READ);
 397        return (0);
 398     }
 399 
 400   if (tbl == NULL)
 401     create_arp (*arp_sourcep(arp), arp_sourceh(arp), arp->hlen);
 402 
 403    /* now see if we can send anything. */
 404    send_arp_q();
 405      
 406   if (arp->op != NET16(ARP_REQUEST))
 407     {
 408        kfree_skb (skb, FREE_READ);
 409        return (0);
 410     }
 411 
 412   /* now we need to create a new packet. */
 413    ret = arp_response(arp, dev);
 414    kfree_skb (skb, FREE_READ);
 415    return (ret);
 416 }
 417 
 418 void
 419 arp_snd (unsigned long paddr, struct device *dev, unsigned long saddr)
     /* [previous][next][first][last][top][bottom][index][help] */
 420 {
 421   struct sk_buff *skb;
 422   struct arp *arp;
 423   struct arp_table *apt;
 424   int tmp;
 425   PRINTK ("arp_snd (paddr=%X, dev=%X, saddr=%X)\n",paddr, dev, saddr);
 426 
 427   /* first we build a dummy arp table entry. */
 428   apt = create_arp (paddr, NULL, 0);
 429   if (apt == NULL) return;
 430 
 431   skb = arp_malloc (sizeof (*arp) + sizeof (*skb) + dev->hard_header_len +
 432                     2*dev->addr_len+8, GFP_ATOMIC);
 433   if (skb == NULL) return;
 434   
 435   skb->lock = 0;
 436   skb->sk = NULL;
 437   skb->mem_addr = skb;
 438   skb->mem_len = sizeof (*arp) + sizeof (*skb) + dev->hard_header_len +
 439                     2*dev->addr_len+8;
 440   skb->arp = 1;
 441   skb->dev = dev;
 442   skb->len = sizeof (*arp) + dev->hard_header_len + 2*dev->addr_len+8;
 443   skb->next = NULL;
 444 
 445   tmp = dev->hard_header ((unsigned char *)(skb+1), dev,
 446                           ETHERTYPE_ARP, 0, saddr, skb->len);
 447   if (tmp < 0)
 448     {
 449        arp_free (skb->mem_addr, skb->mem_len);
 450        return;
 451     }
 452 
 453   arp =(struct arp *) ((unsigned char *)skb+sizeof (*skb) + tmp );
 454   arp->hrd = net16(dev->type);
 455   arp->pro = NET16(ARP_IP_PROT);
 456   arp->hlen = dev->addr_len;
 457   arp->plen = 4;
 458   arp->op = NET16(ARP_REQUEST);
 459   *arp_sourcep(arp) = saddr;
 460   *arp_targetp(arp) = paddr;
 461   memcpy (arp_sourceh(arp), dev->dev_addr, dev->addr_len);
 462   memcpy (arp_targeth(arp), dev->broadcast, dev->addr_len);
 463   PRINTK(">>\n");
 464   print_arp(arp);
 465   dev->queue_xmit (skb, dev, 0);
 466 }
 467 
 468 int
 469 arp_find(unsigned char *haddr, unsigned long paddr, struct device *dev,
     /* [previous][next][first][last][top][bottom][index][help] */
 470            unsigned long saddr)
 471 {
 472   struct arp_table *apt;
 473   PRINTK ("arp_find(haddr=%X, paddr=%X, dev=%X, saddr=%X)\n",
 474           haddr, paddr, dev, saddr);
 475   if (my_ip_addr (paddr))
 476     {
 477       memcpy (haddr, dev->dev_addr, dev->addr_len);
 478       return (0);
 479     }
 480   apt = arp_lookup (paddr);
 481   if (apt != NULL)
 482     {
 483        /* make sure it's not too old. If it is too old, we will
 484           just pretend we did not find it, and then arp_snd
 485           will verify the address for us. */
 486        if (!before (apt->last_used, timer_seq+ARP_TIMEOUT) &&
 487            apt->hlen != 0)
 488          {
 489             apt->last_used=timer_seq;
 490             memcpy (haddr, apt->hard, dev->addr_len);
 491             return (0);
 492          }
 493     }
 494 
 495   /* this assume haddr are at least 4 bytes.
 496      If this isn't true we can use a lookup
 497      table, one for every dev. */
 498   *(unsigned long *)haddr = paddr;
 499 
 500   /* if we didn't find an entry, we will try to 
 501      send an arp packet. */
 502   arp_snd(paddr,dev,saddr);
 503 
 504   return (1);
 505 }
 506 
 507 void
 508 arp_add (unsigned long addr, unsigned char *haddr, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 509 {
 510    struct arp_table *apt;
 511    /* first see if the address is already in the table. */
 512    apt = arp_lookup (addr);
 513    if (apt != NULL)
 514      {
 515         apt->last_used = timer_seq;
 516         memcpy (apt->hard, haddr , dev->addr_len);
 517         return;
 518      }
 519    create_arp (addr, haddr, dev->addr_len);
 520 }
 521 
 522 void
 523 arp_add_broad (unsigned long addr, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 524 {
 525   arp_add (addr,  dev->broadcast , dev);
 526 }
 527 
 528 void
 529 arp_queue(struct sk_buff *skb)
     /* [previous][next][first][last][top][bottom][index][help] */
 530 {
 531   cli();
 532   if (skb->next != NULL)
 533     {
 534       sti();
 535       printk ("arp.c: arp_queue skb already on queue magic=%X. \n",
 536               skb->magic);
 537       return;
 538     }
 539    if (arp_q == NULL)
 540      {
 541         arp_q = skb;
 542         skb->next = skb;
 543         skb->prev = skb;
 544      }
 545    else
 546      {
 547         skb->next = arp_q;
 548         skb->prev = arp_q->prev;
 549         skb->next->prev = skb;
 550         skb->prev->next = skb;
 551      }
 552   skb->magic = ARP_QUEUE_MAGIC;
 553    sti();
 554 }

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