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