Annotation of linux/net/tcp/arp.c, revision 1.1.1.1

1.1       root        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 [email protected] 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)
                     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)
                     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)
                    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)
                    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)
                    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)
                    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)
                    154: {
                    155:   free_s(ptr, len);
                    156: }
                    157: 
                    158: static  void *
                    159: arp_malloc (unsigned long amount)
                    160: {
                    161:   return (malloc (amount));
                    162: }
                    163: 
                    164: static  int
                    165: arp_response (struct arp *arp1, struct device *dev)
                    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:   if (skb == NULL) return (1);
                    175: 
                    176:   skb->mem_addr = skb;
                    177:   skb->mem_len = sizeof (*skb) + sizeof (*arp2) + 2*arp1->hlen + 
                    178:     2*arp1->plen + dev->hard_header_len;
                    179:   skb->len = sizeof (*arp2) + 2*arp1->hlen + 
                    180:     2*arp1->plen + dev->hard_header_len;
                    181: 
                    182:   tmp = dev->hard_header((unsigned char *)(skb+1), dev,
                    183:                         ETHERTYPE_ARP, *arp_sourcep(arp1),
                    184:                         *arp_targetp(arp1),skb->len);
                    185: 
                    186:   if (tmp < 0) return (1);
                    187: 
                    188:   arp2 =(struct arp *) ((unsigned char *)skb+sizeof (*skb) + tmp );
                    189:   memcpy (arp2, arp1, sizeof (*arp2));
                    190: 
                    191:   /* now swap the addresses. */
                    192:   *arp_sourcep(arp2) = *arp_targetp(arp1);
                    193:   memcpy(arp_sourceh(arp2), dev->dev_addr, arp1->hlen);
                    194: 
                    195:   *arp_targetp(arp2) = *arp_sourcep(arp1);
                    196:   memcpy(arp_targeth(arp2), arp_sourceh(arp1), arp1->hlen);
                    197: 
                    198:   arp2->op = NET16(ARP_REPLY);
                    199:   skb->free = 1;
                    200:   skb->arp = 1; /* so the code will know it's not waiting on an arp. */
                    201:   skb->sk = NULL;
                    202:   skb->next = NULL;
                    203:   PRINTK (">>");
                    204:   print_arp(arp2);
                    205:   /* send it. */
                    206:   dev->queue_xmit (skb, dev, 0);
                    207:   return (0);
                    208: }
                    209: 
                    210: /* This will find an entry in the arp table by looking at the ip
                    211:    address. */
                    212: static  struct arp_table *
                    213: arp_lookup (unsigned long paddr)
                    214: {
                    215:   unsigned long hash;
                    216:   struct arp_table *apt;
                    217:   PRINTK ("arp_lookup(paddr=%X)\n", paddr);
                    218:   /* we don't want to arp ourselves. */
                    219:   if (my_ip_addr(paddr)) return (NULL);
                    220:   hash = net32(paddr) & (ARP_TABLE_SIZE - 1);
                    221:   cli();
                    222:   for (apt = arp_table[hash]; apt != NULL; apt = apt->next)
                    223:     {
                    224:       if (apt->ip == paddr)
                    225:        {
                    226:           sti();
                    227:           return (apt);
                    228:        }
                    229:     }
                    230:   sti();
                    231:   return (NULL);
                    232: }
                    233: 
                    234: void
                    235: arp_destroy(unsigned long paddr)
                    236: {
                    237:   unsigned long hash;
                    238:   struct arp_table *apt;
                    239:   struct arp_table *lapt;
                    240:   PRINTK ("arp_destroy (paddr=%X)\n",paddr);
                    241:   /* we don't want to destroy are own arp */
                    242:   if (my_ip_addr(paddr)) return;
                    243:   hash = net32(paddr) & (ARP_TABLE_SIZE - 1);
                    244: 
                    245:   cli(); /* can't be interrupted. */
                    246:   /* make sure there is something there. */
                    247:   if (arp_table[hash] == NULL) return;
                    248: 
                    249:   /* check the first one. */
                    250:   if (arp_table[hash]->ip == paddr)
                    251:     {
                    252:       apt = arp_table[hash];
                    253:       arp_table[hash] = arp_table[hash]->next;
                    254:       arp_free (apt, sizeof (*apt));
                    255:       sti();
                    256:       return;
                    257:     }
                    258: 
                    259:   /* now deal with it any where else in the chain. */
                    260:   lapt = arp_table[hash];
                    261:   for (apt = arp_table[hash]->next; apt != NULL; apt = apt->next)
                    262:     {
                    263:       if (apt->ip == paddr) 
                    264:        {
                    265:          lapt->next = apt->next;
                    266:          arp_free (apt, sizeof (*apt));
                    267:          sti();
                    268:          return;
                    269:        }
                    270:     }
                    271:   sti();
                    272: }
                    273: 
                    274: /* this routine does not check for duplicates.  It assumes the caller
                    275:    does. */
                    276: static  struct arp_table *
                    277: create_arp (unsigned long paddr, unsigned char *addr, int hlen)
                    278: {
                    279:   struct arp_table *apt;
                    280:   unsigned long hash;
                    281:   apt = arp_malloc (sizeof (*apt));
                    282:   if (apt == NULL) return (NULL);
                    283: 
                    284:   hash = net32(paddr) & (ARP_TABLE_SIZE - 1);
                    285:   apt->ip = paddr;
                    286:   apt->hlen =hlen;
                    287:   memcpy (apt->hard, addr, hlen);
                    288:   apt->last_used=timer_seq;
                    289:   sti();
                    290:   apt->next = arp_table[hash];
                    291:   arp_table[hash]=apt;
                    292:   cli();
                    293:   return (apt);
                    294: }
                    295: 
                    296: int
                    297: arp_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
                    298: {
                    299:    struct arp *arp;
                    300:    struct arp_table *tbl;
                    301:    int ret;
                    302: 
                    303:    PRINTK ("<<\n");
                    304:    arp = skb->h.arp;
                    305:    print_arp(arp);
                    306: 
                    307:   /* if this test doesn't pass, something fishy is going on. */
                    308:   if (arp->hlen != dev->addr_len || dev->type !=NET16( arp->hrd))
                    309:     {
                    310:        free_skb(skb, FREE_READ);
                    311:        return (0);
                    312:     }
                    313: 
                    314:   /* for now we will only deal with ip addresses. */
                    315:   if (arp->pro != NET16(ARP_IP_PROT) || arp->plen != 4)
                    316:     {
                    317:        free_skb (skb, FREE_READ);
                    318:        return (0);
                    319:     }
                    320: 
                    321:   /* now look up the ip address in the table. */
                    322:   tbl = arp_lookup (*arp_sourcep(arp));
                    323:   if (tbl != NULL)
                    324:     {
                    325:        memcpy (tbl->hard, arp+1, arp->hlen);
                    326:        tbl->hlen = arp->hlen;
                    327:        tbl->last_used = timer_seq;
                    328:     }
                    329: 
                    330:   if (!my_ip_addr(*arp_targetp(arp)))
                    331:     {
                    332:        free_skb (skb, FREE_READ);
                    333:        return (0);
                    334:     }
                    335: 
                    336:   if (tbl == NULL)
                    337:     create_arp (*arp_sourcep(arp), arp_sourceh(arp), arp->hlen);
                    338: 
                    339:    /* now see if we can send anything. */
                    340:    send_arp_q();
                    341:      
                    342:   if (arp->op != NET16(ARP_REQUEST))
                    343:     {
                    344:        free_skb (skb, FREE_READ);
                    345:        return (0);
                    346:     }
                    347: 
                    348:   /* now we need to create a new packet. */
                    349:    ret = arp_response(arp, dev);
                    350:    free_skb (skb, FREE_READ);
                    351:    return (ret);
                    352: }
                    353: 
                    354: void
                    355: arp_snd (unsigned long paddr, struct device *dev, unsigned long saddr)
                    356: {
                    357:   struct sk_buff *skb;
                    358:   struct arp *arp;
                    359:   struct arp_table *apt;
                    360:   int tmp;
                    361:   PRINTK ("arp_snd (paddr=%X, dev=%X, saddr=%X)\n",paddr, dev, saddr);
                    362: 
                    363:   /* first we build a dummy arp table entry. */
                    364:   apt = create_arp (paddr, NULL, 0);
                    365:   if (apt == NULL) return;
                    366: 
                    367:   skb = arp_malloc (sizeof (*arp) + sizeof (*skb) + dev->hard_header_len +
                    368:                    2*dev->addr_len+8);
                    369:   if (skb == NULL) return;
                    370:   
                    371:   skb->sk = NULL;
                    372:   skb->mem_addr = skb;
                    373:   skb->mem_len = sizeof (*arp) + sizeof (*skb) + dev->hard_header_len +
                    374:                    2*dev->addr_len+8;
                    375:   skb->arp = 1;
                    376:   skb->dev = dev;
                    377:   skb->len = sizeof (*arp) + dev->hard_header_len + 2*dev->addr_len+8;
                    378:   skb->next = NULL;
                    379: 
                    380:   tmp = dev->hard_header ((unsigned char *)(skb+1), dev,
                    381:                          ETHERTYPE_ARP, 0, saddr, skb->len);
                    382:   if (tmp < 0)
                    383:     {
                    384:        arp_free (skb->mem_addr, skb->mem_len);
                    385:        return;
                    386:     }
                    387: 
                    388:   arp =(struct arp *) ((unsigned char *)skb+sizeof (*skb) + tmp );
                    389:   arp->hrd = net16(dev->type);
                    390:   arp->pro = NET16(ARP_IP_PROT);
                    391:   arp->hlen = dev->addr_len;
                    392:   arp->plen = 4;
                    393:   arp->op = NET16(ARP_REQUEST);
                    394:   *arp_sourcep(arp) = saddr;
                    395:   *arp_targetp(arp) = paddr;
                    396:   memcpy (arp_sourceh(arp), dev->dev_addr, dev->addr_len);
                    397:   memcpy (arp_targeth(arp), dev->broadcast, dev->addr_len);
                    398:   PRINTK(">>\n");
                    399:   print_arp(arp);
                    400:   dev->queue_xmit (skb, dev, 0);
                    401: }
                    402: 
                    403: int
                    404: arp_find(unsigned char *haddr, unsigned long paddr, struct device *dev,
                    405:           unsigned long saddr)
                    406: {
                    407:   struct arp_table *apt;
                    408:   PRINTK ("arp_find(haddr=%X, paddr=%X, dev=%X, saddr=%X)\n",
                    409:          haddr, paddr, dev, saddr);
                    410:   if (my_ip_addr (paddr))
                    411:     {
                    412:       memcpy (haddr, dev->dev_addr, dev->addr_len);
                    413:       return (0);
                    414:     }
                    415:   apt = arp_lookup (paddr);
                    416:   if (apt != NULL)
                    417:     {
                    418:        /* make sure it's not too old. If it is too old, we will
                    419:          just pretend we did not find it, and then arp_snd
                    420:          will verify the address for us. */
                    421:        if (!before (apt->last_used, timer_seq+ARP_TIMEOUT) &&
                    422:           apt->hlen != 0)
                    423:         {
                    424:            apt->last_used=timer_seq;
                    425:            memcpy (haddr, apt->hard, dev->addr_len);
                    426:            return (0);
                    427:         }
                    428:     }
                    429: 
                    430:   /* if we didn't find an entry, we will try to 
                    431:      send an arp packet. */
                    432:   if (apt == NULL || after (timer_seq, apt->last_used+ARP_RES_TIME))
                    433:     arp_snd(paddr,dev,saddr);
                    434: 
                    435:   /* this assume haddr are atleast 4 bytes.
                    436:      If this isn't true we can use a lookup
                    437:      table, one for every dev. */
                    438:   *(unsigned long *)haddr = paddr;
                    439:   return (1);
                    440: }
                    441: 
                    442: 
                    443: void
                    444: arp_add (unsigned long addr, unsigned char *haddr, struct device *dev)
                    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)
                    460: {
                    461:   arp_add (addr,  dev->broadcast , dev);
                    462: }
                    463: 
                    464: 
                    465: void
                    466: arp_queue(struct sk_buff *skb)
                    467: {
                    468:    cli();
                    469:    if (arp_q == NULL)
                    470:      {
                    471:        arp_q = skb;
                    472:        skb->next = skb;
                    473:        skb->prev = skb;
                    474:      }
                    475:    else
                    476:     {
                    477:       skb->next = arp_q;
                    478:       skb->prev = arp_q->prev;
                    479:       skb->next->prev = skb;
                    480:       skb->prev->next = skb;
                    481:     }
                    482:   sti();
                    483: 
                    484: }
                    485: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.