root/net/inet/arp.c

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

DEFINITIONS

This source file includes following definitions.
  1. unk_print
  2. eth_aprint
  3. arp_print
  4. arp_send_q
  5. arp_response
  6. arp_lookup
  7. arp_lookup_proxy
  8. arp_destroy
  9. arp_create
  10. arp_rcv
  11. arp_send
  12. arp_find
  13. arp_add
  14. arp_add_broad
  15. arp_queue
  16. arp_get_info
  17. arp_req_set
  18. arp_req_get
  19. arp_req_del
  20. arp_ioctl

   1 /*
   2  * INET         An implementation of the TCP/IP protocol suite for the LINUX
   3  *              operating system.  INET is implemented using the  BSD Socket
   4  *              interface as the means of communication with the user level.
   5  *
   6  *              This file implements the Address Resolution Protocol (ARP),
   7  *              which is used by TCP/IP to map the IP addresses from a host
   8  *              to a low-level hardware address (like an Ethernet address)
   9  *              which it can use to talk to that host.
  10  *
  11  * NOTE:        This module will be rewritten completely in the near future,
  12  *              because I want it to become a multi-address-family address
  13  *              resolver, like it should be.  It will be put in a separate
  14  *              directory under 'net', being a protocol of its own. -FvK
  15  *
  16  * Version:     @(#)arp.c       1.0.15  05/25/93
  17  *
  18  * Authors:     Ross Biro, <bir7@leland.Stanford.Edu>
  19  *              Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  20  *              Stephen A. Wood, <saw@hallc1.cebaf.gov>
  21  *              Arnt Gulbrandsen, <agulbra@pvv.unit.no>
  22  *
  23  * Fixes:
  24  *              'Mr Linux'      :       arp problems.
  25  *              Alan Cox        :       arp_ioctl now checks memory areas with verify_area.
  26  *              Alan Cox        :       Non IP arp message now only appears with debugging on.
  27  *              Alan Cox        :       arp queue is volatile (may be altered by arp messages while doing sends) 
  28  *                                      Generic queue code is urgently needed!
  29  *              Alan Cox        :       Deleting your own ip addr now gives EINVAL not a printk message.
  30  *              Alan Cox        :       Fix to arp linked list error
  31  *              Alan Cox        :       Ignore broadcast arp (Linus' idea 8-))
  32  *              Alan Cox        :       arp_send memory leak removed
  33  *              Alan Cox        :       generic skbuff code fixes.
  34  *              Alan Cox        :       'Bad Packet' only reported on debugging
  35  *              Alan Cox        :       Proxy arp.
  36  *              Alan Cox        :       skb->link3 maintained by letting the other xmit queue kill the packet.
  37  *
  38  * To Fix:
  39  *                              :       arp response allocates an skbuff to send. However there is a perfectly
  40  *                                      good spare skbuff the right size about to be freed (the query). Use the
  41  *                                      query for the reply. This avoids an out of memory case _and_ speeds arp
  42  *                                      up.
  43  *                              :       FREE_READ v FREE_WRITE errors. Not critical as loopback arps don't occur
  44  *
  45  *
  46  *              This program is free software; you can redistribute it and/or
  47  *              modify it under the terms of the GNU General Public License
  48  *              as published by the Free Software Foundation; either version
  49  *              2 of the License, or (at your option) any later version.
  50  */
  51 #include <linux/types.h>
  52 #include <linux/string.h>
  53 #include <linux/kernel.h>
  54 #include <linux/sched.h>
  55 #include <linux/config.h>
  56 #include <linux/socket.h>
  57 #include <linux/sockios.h>
  58 #include <linux/errno.h>
  59 #include <linux/if_arp.h>
  60 #include <linux/in.h>
  61 #include <asm/system.h>
  62 #include <asm/segment.h>
  63 #include <stdarg.h>
  64 #include "inet.h"
  65 #include "dev.h"
  66 #include "eth.h"
  67 #include "ip.h"
  68 #include "route.h"
  69 #include "protocol.h"
  70 #include "tcp.h"
  71 #include "skbuff.h"
  72 #include "sock.h"
  73 #include "arp.h"
  74 
  75 
  76 #define ARP_MAX_TRIES   3
  77 
  78 
  79 static char *unk_print(unsigned char *, int);
  80 static char *eth_aprint(unsigned char *, int);
  81 
  82 
  83 static char *arp_cmds[] = {
  84   "0x%04X",
  85   "REQUEST",
  86   "REPLY",
  87   "REVERSE REQUEST",
  88   "REVERSE REPLY",
  89   NULL
  90 };
  91 #define ARP_MAX_CMDS    (sizeof(arp_cmds) / sizeof(arp_cmds[0]))
  92 
  93 static struct {
  94   char  *name;
  95   char  *(*print)(unsigned char *ptr, int len);
  96 } arp_types[] = {
  97   { "0x%04X",                   unk_print       },
  98   { "10 Mbps Ethernet",         eth_aprint      },
  99   { "3 Mbps Ethernet",          eth_aprint      },
 100   { "AX.25",                    unk_print       },
 101   { "Pronet",                   unk_print       },
 102   { "Chaos",                    unk_print       },
 103   { "IEEE 802.2 Ethernet (?)",  eth_aprint      },
 104   { "Arcnet",                   unk_print       },
 105   { "AppleTalk",                unk_print       },
 106   { NULL,                       NULL            }
 107 };
 108 #define ARP_MAX_TYPE    (sizeof(arp_types) / sizeof(arp_types[0]))
 109 
 110 
 111 struct arp_table *arp_tables[ARP_TABLE_SIZE] = {
 112   NULL,
 113 };
 114 
 115 static int arp_proxies=0;       /* So we can avoid the proxy arp 
 116                                    overhead with the usual case of
 117                                    no proxy arps */
 118 
 119 struct sk_buff * volatile arp_q = NULL;
 120 
 121 static struct arp_table *arp_lookup(unsigned long addr);
 122 static struct arp_table *arp_lookup_proxy(unsigned long addr);
 123 
 124 /* Dump the ADDRESS bytes of an unknown hardware type. */
 125 static char *
 126 unk_print(unsigned char *ptr, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
 127 {
 128   static char buff[32];
 129   char *bufp = buff;
 130   int i;
 131 
 132   for (i = 0; i < len; i++)
 133         bufp += sprintf(bufp, "%02X ", (*ptr++ & 0377));
 134   return(buff);
 135 }
 136 
 137 
 138 /* Dump the ADDRESS bytes of an Ethernet hardware type. */
 139 static char *
 140 eth_aprint(unsigned char *ptr, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
 141 {
 142   if (len != ETH_ALEN) return("");
 143   return(eth_print(ptr));
 144 }
 145 
 146 
 147 /* Dump an ARP packet. Not complete yet for non-Ethernet packets. */
 148 static void
 149 arp_print(struct arphdr *arp)
     /* [previous][next][first][last][top][bottom][index][help] */
 150 {
 151   int len, idx;
 152   unsigned char *ptr;
 153 
 154   if (inet_debug != DBG_ARP) return;
 155 
 156   printk("ARP: ");
 157   if (arp == NULL) {
 158         printk("(null)\n");
 159         return;
 160   }
 161 
 162   /* Print the opcode name. */
 163   len = htons(arp->ar_op);
 164   if (len < ARP_MAX_CMDS) idx = len;
 165     else idx = 0;
 166   printk("op ");
 167   printk(arp_cmds[idx], len);
 168 
 169   /* Print the ARP header. */
 170   len = htons(arp->ar_hrd);
 171   if (len < ARP_MAX_TYPE) idx = len;
 172     else idx = 0;
 173   printk("   hrd = "); printk(arp_types[idx].name, len);
 174   printk("   pro = 0x%04X\n", htons(arp->ar_pro));
 175   printk("   hlen = %d plen = %d\n", arp->ar_hln, arp->ar_pln);
 176 
 177   /*
 178    * Print the variable data.
 179    * When ARP gets redone (after the formal introduction of NET-2),
 180    * this part will be redone.  ARP will then be a multi-family address
 181    * resolver, and the code below will be made more general. -FvK
 182    */
 183   ptr = ((unsigned char *) &arp->ar_op) + sizeof(u_short);
 184   printk("   sender HA = %s ", arp_types[idx].print(ptr, arp->ar_hln));
 185   ptr += arp->ar_hln;
 186   printk("  PA = %s\n", in_ntoa(*(unsigned long *) ptr));
 187   ptr += arp->ar_pln;
 188   printk("   target HA = %s ", arp_types[idx].print(ptr, arp->ar_hln));
 189   ptr += arp->ar_hln;
 190   printk("  PA = %s\n", in_ntoa(*(unsigned long *) ptr));
 191 }
 192 
 193 
 194 /* This will try to retransmit everything on the queue. */
 195 static void
 196 arp_send_q(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 197 {
 198   struct sk_buff *skb;
 199   struct sk_buff *volatile work_q;
 200   cli();
 201   work_q = arp_q;
 202   skb_new_list_head(&work_q);
 203   arp_q = NULL;
 204   sti();
 205   while((skb=skb_dequeue(&work_q))!=NULL)
 206   {
 207         IS_SKB(skb);
 208         skb->magic = 0;
 209         skb->next = NULL;
 210         skb->prev = NULL;
 211 
 212         /* Decrement the 'tries' counter. */
 213         cli();
 214         skb->tries--;
 215         if (skb->tries == 0) {
 216                 /*
 217                  * Grmpf.
 218                  * We have tried ARP_MAX_TRIES to resolve the IP address
 219                  * from this datagram.  This means that the machine does
 220                  * not listen to our ARP requests.  Perhaps someone tur-
 221                  * ned off the thing?
 222                  * In any case, trying further is useless.  So, we kill
 223                  * this packet from the queue.  (grinnik) -FvK
 224                  */
 225                 skb->sk = NULL;
 226                 if(skb->free)
 227                         kfree_skb(skb, FREE_WRITE);
 228                         /* If free was 0, magic is now 0, next is 0 and 
 229                            the write queue will notice and kill */
 230                 sti();
 231                 continue;
 232         }
 233 
 234         /* Can we now complete this packet? */
 235         sti();
 236         if (skb->arp || !skb->dev->rebuild_header(skb+1, skb->dev)) {
 237                 skb->arp  = 1;
 238                 skb->dev->queue_xmit(skb, skb->dev, 0);
 239         } else {
 240                 /* Alas.  Re-queue it... */
 241                 skb->magic = ARP_QUEUE_MAGIC;      
 242                 skb_queue_head(&arp_q,skb);
 243         }
 244   }
 245 }
 246 
 247 
 248 /* Create and send our response to an ARP request. */
 249 static int
 250 arp_response(struct arphdr *arp1, struct device *dev,  int addrtype)
     /* [previous][next][first][last][top][bottom][index][help] */
 251 {
 252   struct arphdr *arp2;
 253   struct sk_buff *skb;
 254   unsigned long src, dst;
 255   unsigned char *ptr1, *ptr2;
 256   int hlen;
 257   struct arp_table *apt = NULL;/* =NULL otherwise the compiler gives warnings */
 258 
 259   /* Decode the source (REQUEST) message. */
 260   ptr1 = ((unsigned char *) &arp1->ar_op) + sizeof(u_short);
 261   src = *((unsigned long *) (ptr1 + arp1->ar_hln));
 262   dst = *((unsigned long *) (ptr1 + (arp1->ar_hln * 2) + arp1->ar_pln));
 263   
 264   if(addrtype!=IS_MYADDR)
 265   {
 266         apt=arp_lookup_proxy(dst);
 267         if(apt==NULL)
 268                 return(1);
 269   }
 270 
 271   /* Get some mem and initialize it for the return trip. */
 272   skb = alloc_skb(sizeof(struct sk_buff) +
 273                 sizeof(struct arphdr) +
 274                 (2 * arp1->ar_hln) + (2 * arp1->ar_pln) +
 275                 dev->hard_header_len, GFP_ATOMIC);
 276   if (skb == NULL) {
 277         printk("ARP: no memory available for ARP REPLY!\n");
 278         return(1);
 279   }
 280 
 281   skb->mem_addr = skb;
 282   skb->len      = sizeof(struct arphdr) + (2 * arp1->ar_hln) + 
 283                   (2 * arp1->ar_pln) + dev->hard_header_len;
 284   skb->mem_len  = sizeof(struct sk_buff) + skb->len;
 285   hlen = dev->hard_header((unsigned char *)(skb+1), dev,
 286                          ETH_P_ARP, src, dst, skb->len);
 287   if (hlen < 0) {
 288         printk("ARP: cannot create HW frame header for REPLY !\n");
 289         kfree_skb(skb, FREE_WRITE);
 290         return(1);
 291   }
 292 
 293   /*
 294    * Fill in the ARP REPLY packet.
 295    * This looks ugly, but we have to deal with the variable-length
 296    * ARP packets and such.  It is not as bad as it looks- FvK
 297    */
 298   arp2 = (struct arphdr *) ((unsigned char *) (skb+1) + hlen);
 299   ptr2 = ((unsigned char *) &arp2->ar_op) + sizeof(u_short);
 300   arp2->ar_hrd = arp1->ar_hrd;
 301   arp2->ar_pro = arp1->ar_pro;
 302   arp2->ar_hln = arp1->ar_hln;
 303   arp2->ar_pln = arp1->ar_pln;
 304   arp2->ar_op = htons(ARPOP_REPLY);
 305   if(addrtype==IS_MYADDR)
 306           memcpy(ptr2, dev->dev_addr, arp2->ar_hln);
 307   else          /* Proxy arp, so pull from the table */
 308           memcpy(ptr2, apt->ha, arp2->ar_hln);
 309   ptr2 += arp2->ar_hln;
 310   memcpy(ptr2, ptr1 + (arp1->ar_hln * 2) + arp1->ar_pln, arp2->ar_pln);
 311   ptr2 += arp2->ar_pln;
 312   memcpy(ptr2, ptr1, arp2->ar_hln);
 313   ptr2 += arp2->ar_hln;
 314   memcpy(ptr2, ptr1 + arp1->ar_hln, arp2->ar_pln);
 315 
 316   skb->free = 1;
 317   skb->arp = 1;
 318   skb->sk = NULL;
 319   skb->next = NULL;
 320 
 321   DPRINTF((DBG_ARP, ">>"));
 322   arp_print(arp2);
 323 
 324   /* Queue the packet for transmission. */
 325   dev->queue_xmit(skb, dev, 0);
 326   return(0);
 327 }
 328 
 329 
 330 /* This will find an entry in the ARP table by looking at the IP address. */
 331 static struct arp_table *
 332 arp_lookup(unsigned long paddr)
     /* [previous][next][first][last][top][bottom][index][help] */
 333 {
 334   struct arp_table *apt;
 335   unsigned long hash;
 336 
 337   DPRINTF((DBG_ARP, "ARP: lookup(%s)\n", in_ntoa(paddr)));
 338 
 339   /* We don't want to ARP ourselves. */
 340   if (chk_addr(paddr) == IS_MYADDR) {
 341         printk("ARP: ARPing my own IP address %s !\n", in_ntoa(paddr));
 342         return(NULL);
 343   }
 344 
 345   /* Loop through the table for the desired address. */
 346   hash = htonl(paddr) & (ARP_TABLE_SIZE - 1);
 347   cli();
 348   apt = arp_tables[hash];
 349   while(apt != NULL) {
 350         if (apt->ip == paddr) {
 351                 sti();
 352                 return(apt);
 353         }
 354         apt = apt->next;
 355   }
 356   sti();
 357   return(NULL);
 358 }
 359 
 360 
 361 /* This will find a proxy in the ARP table by looking at the IP address. */
 362 static struct arp_table *arp_lookup_proxy(unsigned long paddr)
     /* [previous][next][first][last][top][bottom][index][help] */
 363 {
 364   struct arp_table *apt;
 365   unsigned long hash;
 366 
 367   DPRINTF((DBG_ARP, "ARP: lookup proxy(%s)\n", in_ntoa(paddr)));
 368 
 369   /* Loop through the table for the desired address. */
 370   hash = htonl(paddr) & (ARP_TABLE_SIZE - 1);
 371   cli();
 372   apt = arp_tables[hash];
 373   while(apt != NULL) {
 374         if (apt->ip == paddr && (apt->flags & ATF_PUBL) ) {
 375                 sti();
 376                 return(apt);
 377         }
 378         apt = apt->next;
 379   }
 380   sti();
 381   return(NULL);
 382 }
 383 
 384 
 385 /* Delete an ARP mapping entry in the cache. */
 386 void
 387 arp_destroy(unsigned long paddr)
     /* [previous][next][first][last][top][bottom][index][help] */
 388 {
 389   struct arp_table *apt;
 390   struct arp_table **lapt;
 391   unsigned long hash;
 392 
 393   DPRINTF((DBG_ARP, "ARP: destroy(%s)\n", in_ntoa(paddr)));
 394 
 395   /* We cannot destroy our own ARP entry. */
 396   if (chk_addr(paddr) == IS_MYADDR) {
 397         DPRINTF((DBG_ARP, "ARP: Destroying my own IP address %s !\n",
 398                                                         in_ntoa(paddr)));
 399         return;
 400   }
 401   hash = htonl(paddr) & (ARP_TABLE_SIZE - 1);
 402 
 403   cli();
 404   lapt = &arp_tables[hash];
 405   while ((apt = *lapt) != NULL) {
 406         if (apt->ip == paddr) {
 407                 *lapt = apt->next;
 408                 if(apt->flags&ATF_PUBL)
 409                         arp_proxies--;                  
 410                 kfree_s(apt, sizeof(struct arp_table));
 411                 sti();
 412                 return;
 413         }
 414         lapt = &apt->next;
 415   }
 416   sti();
 417 }
 418 
 419 
 420 /* Create an ARP entry.  The caller should check for duplicates! */
 421 static struct arp_table *
 422 arp_create(unsigned long paddr, unsigned char *addr, int hlen, int htype)
     /* [previous][next][first][last][top][bottom][index][help] */
 423 {
 424   struct arp_table *apt;
 425   unsigned long hash;
 426 
 427   DPRINTF((DBG_ARP, "ARP: create(%s, ", in_ntoa(paddr)));
 428   DPRINTF((DBG_ARP, "%s, ", eth_print(addr)));
 429   DPRINTF((DBG_ARP, "%d, %d)\n", hlen, htype));
 430 
 431   apt = (struct arp_table *) kmalloc(sizeof(struct arp_table), GFP_ATOMIC);
 432   if (apt == NULL) {
 433         printk("ARP: no memory available for new ARP entry!\n");
 434         return(NULL);
 435   }
 436 
 437   /* Fill in the allocated ARP cache entry. */
 438   hash = htonl(paddr) & (ARP_TABLE_SIZE - 1);
 439   apt->ip = paddr;
 440   apt->hlen = hlen;
 441   apt->htype = htype;
 442   apt->flags = (ATF_INUSE | ATF_COM);           /* USED and COMPLETED entry */
 443   memcpy(apt->ha, addr, hlen);
 444   apt->last_used = jiffies;
 445   cli();
 446   apt->next = arp_tables[hash];
 447   arp_tables[hash] = apt;
 448   sti();
 449   return(apt);
 450 }
 451 
 452 
 453 /*
 454  * An ARP REQUEST packet has arrived.
 455  * We try to be smart here, and fetch the data of the sender of the
 456  * packet- we might need it later, so fetching it now can save us a
 457  * broadcast later.
 458  * Then, if the packet was meant for us (i.e. the TARGET address was
 459  * one of our own IP addresses), we set up and send out an ARP REPLY
 460  * packet to the sender.
 461  */
 462 int
 463 arp_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
     /* [previous][next][first][last][top][bottom][index][help] */
 464 {
 465   struct arphdr *arp;
 466   struct arp_table *tbl;
 467   unsigned long src, dst;
 468   unsigned char *ptr;
 469   int ret;
 470   int addr_hint;
 471 
 472   DPRINTF((DBG_ARP, "<<\n"));
 473   arp = skb->h.arp;
 474   arp_print(arp);
 475 
 476   /* If this test doesn't pass, its not IP. Might be DECNET or friends */
 477   if (arp->ar_hln != dev->addr_len || dev->type != NET16(arp->ar_hrd)) 
 478   {
 479         DPRINTF((DBG_ARP,"ARP: Bad packet received on device \"%s\" !\n", dev->name));
 480         kfree_skb(skb, FREE_READ);
 481         return(0);
 482   }
 483 
 484   /* For now we will only deal with IP addresses. */
 485   if (arp->ar_pro != NET16(ETH_P_IP) || arp->ar_pln != 4) 
 486   {
 487         if (arp->ar_op != NET16(ARPOP_REQUEST))
 488                 DPRINTF((DBG_ARP,"ARP: Non-IP request on device \"%s\" !\n", dev->name));
 489         kfree_skb(skb, FREE_READ);
 490         return(0);
 491   }
 492 
 493   /*
 494    * As said before, we try to be smart by using the
 495    * info already present in the packet: the sender's
 496    * IP and hardware address.
 497    */
 498   ptr = ((unsigned char *) &arp->ar_op) + sizeof(u_short);
 499   memcpy(&src, ptr + arp->ar_hln, arp->ar_pln);
 500   tbl = arp_lookup(src);
 501   if (tbl != NULL) {
 502         DPRINTF((DBG_ARP, "ARP: udating entry for %s\n", in_ntoa(src)));
 503         memcpy(tbl->ha, ptr, arp->ar_hln);
 504         tbl->hlen = arp->ar_hln;
 505         tbl->flags |= ATF_COM;
 506         tbl->last_used = jiffies;
 507   } else {
 508         memcpy(&dst, ptr + (arp->ar_hln * 2) + arp->ar_pln, arp->ar_pln);
 509         if (chk_addr(dst) != IS_MYADDR) {
 510                 kfree_skb(skb, FREE_READ);
 511                 return(0);
 512         } else {
 513                 tbl = arp_create(src, ptr, arp->ar_hln, arp->ar_hrd);
 514                 if (tbl == NULL) {
 515                         kfree_skb(skb, FREE_READ);
 516                         return(0);
 517                 }
 518         }
 519   }
 520 
 521   /*
 522    * Since we updated the ARP cache, we might have enough
 523    * information to send out some previously queued IP
 524    * datagrams....
 525    */
 526   arp_send_q();
 527 
 528   /*
 529    * OK, we used that part of the info.  Now check if the
 530    * request was an ARP REQUEST for one of our own addresses..
 531    */
 532   if (arp->ar_op != NET16(ARPOP_REQUEST)) {
 533         kfree_skb(skb, FREE_READ);
 534         return(0);
 535   }
 536 
 537   /*
 538    * A broadcast arp, ignore it
 539    */
 540 
 541   if((dst&0xFF)==0xFF)
 542   {
 543         kfree_skb(skb, FREE_READ);
 544         return 0;
 545   }
 546 
 547   memcpy(&dst, ptr + (arp->ar_hln * 2) + arp->ar_pln, arp->ar_pln);
 548   if ((addr_hint=chk_addr(dst)) != IS_MYADDR && arp_proxies==0) {
 549         DPRINTF((DBG_ARP, "ARP: request was not for me!\n"));
 550         kfree_skb(skb, FREE_READ);
 551         return(0);
 552   }
 553 
 554   /*
 555    * Yes, it is for us.
 556    * Allocate, fill in and send an ARP REPLY packet.
 557    */
 558   ret = arp_response(arp, dev, addr_hint);
 559   kfree_skb(skb, FREE_READ);
 560   return(ret);
 561 }
 562 
 563 
 564 /* Create and send an ARP REQUEST packet. */
 565 void
 566 arp_send(unsigned long paddr, struct device *dev, unsigned long saddr)
     /* [previous][next][first][last][top][bottom][index][help] */
 567 {
 568   struct sk_buff *skb;
 569   struct arphdr *arp;
 570   unsigned char *ptr;
 571   int tmp;
 572 
 573   DPRINTF((DBG_ARP, "ARP: send(paddr=%s, ", in_ntoa(paddr)));
 574   DPRINTF((DBG_ARP, "dev=%s, ", dev->name));
 575   DPRINTF((DBG_ARP, "saddr=%s)\n", in_ntoa(saddr)));
 576 
 577   skb = alloc_skb(sizeof(struct sk_buff) +
 578                 sizeof(struct arphdr) + (2 * dev->addr_len) +
 579                 dev->hard_header_len +
 580                 (2 * 4 /* arp->plen */), GFP_ATOMIC);
 581   if (skb == NULL) {
 582         printk("ARP: No memory available for REQUEST %s\n", in_ntoa(paddr));
 583         return;
 584   }
 585   
 586   /* Fill in the request. */
 587   skb->sk = NULL;
 588   skb->mem_addr = skb;
 589   skb->len = sizeof(struct arphdr) +
 590              dev->hard_header_len + (2 * dev->addr_len) + 8;
 591   skb->mem_len = sizeof(struct sk_buff) + skb->len;
 592   skb->arp = 1;
 593   skb->dev = dev;
 594   skb->next = NULL;
 595   skb->free = 1;
 596   tmp = dev->hard_header((unsigned char *)(skb+1), dev,
 597                           ETH_P_ARP, 0, saddr, skb->len);
 598   if (tmp < 0) {
 599         kfree_skb(skb,FREE_WRITE);
 600         return;
 601   }
 602   arp = (struct arphdr *) ((unsigned char *) (skb+1) + tmp);
 603   arp->ar_hrd = htons(dev->type);
 604   arp->ar_pro = htons(ETH_P_IP);
 605   arp->ar_hln = dev->addr_len;
 606   arp->ar_pln = 4;
 607   arp->ar_op = htons(ARPOP_REQUEST);
 608 
 609   ptr = ((unsigned char *) &arp->ar_op) + sizeof(u_short);
 610   memcpy(ptr, dev->dev_addr, arp->ar_hln);
 611   ptr += arp->ar_hln;
 612   memcpy(ptr, &saddr, arp->ar_pln);
 613   ptr += arp->ar_pln;
 614   /*memcpy(ptr, dev->broadcast, arp->ar_hln);*/
 615   memset(ptr,0,arp->ar_hln);
 616   ptr += arp->ar_hln;
 617   memcpy(ptr, &paddr, arp->ar_pln);
 618 
 619   DPRINTF((DBG_ARP, ">>\n"));
 620   arp_print(arp);
 621   dev->queue_xmit(skb, dev, 0);
 622 }
 623 
 624 
 625 /* Find an ARP mapping in the cache. If not found, post a REQUEST. */
 626 int
 627 arp_find(unsigned char *haddr, unsigned long paddr, struct device *dev,
     /* [previous][next][first][last][top][bottom][index][help] */
 628            unsigned long saddr)
 629 {
 630   struct arp_table *apt;
 631 
 632   DPRINTF((DBG_ARP, "ARP: find(haddr=%s, ", eth_print(haddr)));
 633   DPRINTF((DBG_ARP, "paddr=%s, ", in_ntoa(paddr)));
 634   DPRINTF((DBG_ARP, "dev=%s, saddr=%s)\n", dev->name, in_ntoa(saddr)));
 635 
 636   switch(chk_addr(paddr)) {
 637         case IS_MYADDR:
 638                 memcpy(haddr, dev->dev_addr, dev->addr_len);
 639                 return(0);
 640         case IS_BROADCAST:
 641                 memcpy(haddr, dev->broadcast, dev->addr_len);
 642                 return(0);
 643   }
 644                 
 645   apt = arp_lookup(paddr);
 646   if (apt != NULL) {
 647         /*
 648          * Make sure it's not too old. If it is too old, we will
 649          * just pretend we did not find it, and then arp_send will
 650          * verify the address for us.
 651          */
 652         if ((!(apt->flags & ATF_PERM)) ||
 653             (!before(apt->last_used, jiffies+ARP_TIMEOUT) && apt->hlen != 0)) {
 654                 apt->last_used = jiffies;
 655                 memcpy(haddr, apt->ha, dev->addr_len);
 656                 return(0);
 657         } else {
 658                 DPRINTF((DBG_ARP, "ARP: find: found expired entry for %s\n",
 659                                                         in_ntoa(apt->ip)));
 660         }
 661   }
 662 
 663   /*
 664    * This assume haddr are at least 4 bytes.
 665    * If this isn't true we can use a lookup table, one for every dev.
 666    * NOTE: this bit of code still looks fishy to me- FvK
 667    */
 668   *(unsigned long *)haddr = paddr;
 669 
 670   /* If we didn't find an entry, we will try to send an ARP packet. */
 671   arp_send(paddr, dev, saddr);
 672 
 673   return(1);
 674 }
 675 
 676 
 677 /* Add an entry to the ARP cache.  Check for dupes! */
 678 void
 679 arp_add(unsigned long addr, unsigned char *haddr, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 680 {
 681   struct arp_table *apt;
 682 
 683   DPRINTF((DBG_ARP, "ARP: add(%s, ", in_ntoa(addr)));
 684   DPRINTF((DBG_ARP, "%s, ", eth_print(haddr)));
 685   DPRINTF((DBG_ARP, "%d, %d)\n", dev->hard_header_len, dev->type));
 686 
 687   /* This is probably a good check... */
 688   if (addr == 0) {
 689         printk("ARP: add: will not add entry for 0.0.0.0 !\n");
 690         return;
 691   }
 692 
 693   /* First see if the address is already in the table. */
 694   apt = arp_lookup(addr);
 695   if (apt != NULL) {
 696         DPRINTF((DBG_ARP, "ARP: updating entry for %s\n", in_ntoa(addr)));
 697         apt->last_used = jiffies;
 698         memcpy(apt->ha, haddr , dev->addr_len);
 699         return;
 700   }
 701   arp_create(addr, haddr, dev->addr_len, dev->type);
 702 }
 703 
 704 
 705 /* Create an ARP entry for a device's broadcast address. */
 706 void
 707 arp_add_broad(unsigned long addr, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 708 {
 709   struct arp_table *apt;
 710 
 711   arp_add(addr, dev->broadcast, dev);
 712   apt = arp_lookup(addr);
 713   if (apt != NULL) {
 714         apt->flags |= ATF_PERM;
 715   }
 716 }
 717 
 718 
 719 /* Queue an IP packet, while waiting for the ARP reply packet. */
 720 void
 721 arp_queue(struct sk_buff *skb)
     /* [previous][next][first][last][top][bottom][index][help] */
 722 {
 723   cli();
 724   skb->tries = ARP_MAX_TRIES;
 725 
 726   if (skb->next != NULL) {
 727         sti();
 728         printk("ARP: arp_queue skb already on queue magic=%X.\n", skb->magic);
 729         return;
 730   }
 731   skb_queue_tail(&arp_q,skb);
 732   skb->magic = ARP_QUEUE_MAGIC;
 733   sti();
 734 }
 735 
 736 
 737 /*
 738  * Write the contents of the ARP cache to a PROCfs file.
 739  * This is not by long perfect, as the internal ARP table doesn't
 740  * have all the info we would like to have.  Oh well, it works for
 741  * now, eh? - FvK
 742  * Also note, that due to space limits, we cannot generate more than
 743  * 4Kbyte worth of data.  This usually is enough, but I have seen
 744  * machines die from under me because of a *very* large ARP cache.
 745  * This can be simply tested by doing:
 746  *
 747  *      # ping 255.255.255.255
 748  *      # arp -a
 749  *
 750  * Perhaps we should redo PROCfs to handle larger buffers?  Michael?
 751  */
 752 int
 753 arp_get_info(char *buffer)
     /* [previous][next][first][last][top][bottom][index][help] */
 754 {
 755   struct arpreq *req;
 756   struct arp_table *apt;
 757   int i;
 758   char *pos;
 759 
 760   /* Loop over the ARP table and copy structures to the buffer. */
 761   pos = buffer;
 762   i = 0;
 763   for (i = 0; i < ARP_TABLE_SIZE; i++) {
 764         cli();
 765         apt = arp_tables[i];
 766         sti();
 767         while (apt != NULL) {
 768                 if (pos < (buffer + 4000)) {
 769                         req = (struct arpreq *) pos;
 770                         memset((char *) req, 0, sizeof(struct arpreq));
 771                         req->arp_pa.sa_family = AF_INET;
 772                         memcpy((char *) req->arp_pa.sa_data, (char *) &apt->ip, 4);
 773                                 req->arp_ha.sa_family = apt->htype;
 774                         memcpy((char *) req->arp_ha.sa_data,
 775                                 (char *) &apt->ha, apt->hlen);
 776                 }
 777                 pos += sizeof(struct arpreq);
 778                 cli();
 779                 apt = apt->next;
 780                 sti();
 781         }
 782   }
 783   return(pos - buffer);
 784 }
 785 
 786 
 787 /* Set (create) an ARP cache entry. */
 788 static int
 789 arp_req_set(struct arpreq *req)
     /* [previous][next][first][last][top][bottom][index][help] */
 790 {
 791   struct arpreq r;
 792   struct arp_table *apt;
 793   struct sockaddr_in *si;
 794   int htype, hlen;
 795 
 796   /* We only understand about IP addresses... */
 797   memcpy_fromfs(&r, req, sizeof(r));
 798   if (r.arp_pa.sa_family != AF_INET) return(-EPFNOSUPPORT);
 799 
 800   /*
 801    * Find out about the hardware type.
 802    * We have to be compatible with BSD UNIX, so we have to
 803    * assume that a "not set" value (i.e. 0) means Ethernet.
 804    */
 805   si = (struct sockaddr_in *) &r.arp_pa;
 806   switch(r.arp_ha.sa_family) {
 807         case 0:
 808         case ARPHRD_ETHER:
 809                 htype = ARPHRD_ETHER;
 810                 hlen = ETH_ALEN;
 811                 break;
 812         default:
 813                 return(-EPFNOSUPPORT);
 814   }
 815 
 816   /* Is there an existing entry for this address? */
 817   if (si->sin_addr.s_addr == 0) {
 818         printk("ARP: SETARP: requested PA is 0.0.0.0 !\n");
 819         return(-EINVAL);
 820   }
 821   apt = arp_lookup(si->sin_addr.s_addr);
 822   if (apt == NULL) {
 823         apt = arp_create(si->sin_addr.s_addr,
 824                 (unsigned char *) r.arp_ha.sa_data, hlen, htype);
 825         if (apt == NULL) return(-ENOMEM);
 826   }
 827 
 828   /* We now have a pointer to an ARP entry.  Update it! */
 829   memcpy((char *) &apt->ha, (char *) &r.arp_ha.sa_data, hlen);
 830   apt->last_used = jiffies;
 831   apt->flags = r.arp_flags;
 832   if(apt->flags&ATF_PUBL)
 833         arp_proxies++;          /* Count proxy arps so we know if to use it */
 834 
 835   return(0);
 836 }
 837 
 838 
 839 /* Get an ARP cache entry. */
 840 static int
 841 arp_req_get(struct arpreq *req)
     /* [previous][next][first][last][top][bottom][index][help] */
 842 {
 843   struct arpreq r;
 844   struct arp_table *apt;
 845   struct sockaddr_in *si;
 846 
 847   /* We only understand about IP addresses... */
 848   memcpy_fromfs(&r, req, sizeof(r));
 849   if (r.arp_pa.sa_family != AF_INET) return(-EPFNOSUPPORT);
 850 
 851   /* Is there an existing entry for this address? */
 852   si = (struct sockaddr_in *) &r.arp_pa;
 853   apt = arp_lookup(si->sin_addr.s_addr);
 854   if (apt == NULL) return(-ENXIO);
 855 
 856   /* We found it; copy into structure. */
 857   memcpy((char *) r.arp_ha.sa_data, (char *) &apt->ha, apt->hlen);
 858   r.arp_ha.sa_family = apt->htype;
 859 
 860   /* Copy the information back */
 861   memcpy_tofs(req, &r, sizeof(r));
 862   return(0);
 863 }
 864 
 865 
 866 /* Delete an ARP cache entry. */
 867 static int
 868 arp_req_del(struct arpreq *req)
     /* [previous][next][first][last][top][bottom][index][help] */
 869 {
 870   struct arpreq r;
 871   struct sockaddr_in *si;
 872 
 873   /* We only understand about IP addresses... */
 874   memcpy_fromfs(&r, req, sizeof(r));
 875   if (r.arp_pa.sa_family != AF_INET) return(-EPFNOSUPPORT);
 876 
 877   si = (struct sockaddr_in *) &r.arp_pa;
 878   
 879   /* The system cope with this but splats up a nasty kernel message 
 880      We trap it beforehand and tell the user off */
 881   if(chk_addr(si->sin_addr.s_addr)==IS_MYADDR)
 882         return -EINVAL;
 883         
 884   arp_destroy(si->sin_addr.s_addr);
 885 
 886   return(0);
 887 }
 888 
 889 
 890 /* Handle an ARP layer I/O control request. */
 891 int
 892 arp_ioctl(unsigned int cmd, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 893 {
 894   int err;
 895   switch(cmd) {
 896         case DDIOCSDBG:
 897                 return(dbg_ioctl(arg, DBG_ARP));
 898         case SIOCDARP:
 899                 if (!suser()) return(-EPERM);
 900                 err=verify_area(VERIFY_READ,arg,sizeof(struct arpreq));
 901                 if(err)
 902                         return err;
 903                 return(arp_req_del((struct arpreq *)arg));
 904         case SIOCGARP:
 905                 err=verify_area(VERIFY_WRITE,arg,sizeof(struct arpreq));
 906                 if(err)
 907                         return err;
 908                 return(arp_req_get((struct arpreq *)arg));
 909         case SIOCSARP:
 910                 if (!suser()) return(-EPERM);
 911                 err=verify_area(VERIFY_READ,arg,sizeof(struct arpreq));
 912                 if(err)
 913                         return err;
 914                 return(arp_req_set((struct arpreq *)arg));
 915         default:
 916                 return(-EINVAL);
 917   }
 918   /*NOTREACHED*/
 919   return(0);
 920 }

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