root/net/inet/arp.c

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

DEFINITIONS

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

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