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

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