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