|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.