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

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