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 #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
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 kfree_s(ptr, len);
156 }
157
158 static void *
159 arp_malloc (unsigned long amount, int priority)
160 {
161 return (kmalloc (amount, priority));
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
172 skb = arp_malloc (sizeof (*skb) + sizeof (*arp2) +
173 2*arp1->hlen + 2*arp1->plen + dev->hard_header_len,
174 GFP_ATOMIC);
175 if (skb == NULL) return (1);
176
177 skb->mem_addr = skb;
178 skb->mem_len = sizeof (*skb) + sizeof (*arp2) + 2*arp1->hlen +
179 2*arp1->plen + dev->hard_header_len;
180 skb->len = sizeof (*arp2) + 2*arp1->hlen +
181 2*arp1->plen + dev->hard_header_len;
182
183 tmp = dev->hard_header((unsigned char *)(skb+1), dev,
184 ETHERTYPE_ARP, *arp_sourcep(arp1),
185 *arp_targetp(arp1),skb->len);
186
187 if (tmp < 0) return (1);
188
189 arp2 =(struct arp *) ((unsigned char *)skb+sizeof (*skb) + tmp );
190 memcpy (arp2, arp1, sizeof (*arp2));
191
192
193 *arp_sourcep(arp2) = *arp_targetp(arp1);
194 memcpy(arp_sourceh(arp2), dev->dev_addr, arp1->hlen);
195
196 *arp_targetp(arp2) = *arp_sourcep(arp1);
197 memcpy(arp_targeth(arp2), arp_sourceh(arp1), arp1->hlen);
198
199 arp2->op = NET16(ARP_REPLY);
200 skb->free = 1;
201 skb->arp = 1;
202 skb->sk = NULL;
203 skb->next = NULL;
204 PRINTK (">>");
205 print_arp(arp2);
206
207 dev->queue_xmit (skb, dev, 0);
208 return (0);
209 }
210
211
212
213 static struct arp_table *
214 arp_lookup (unsigned long paddr)
215 {
216 unsigned long hash;
217 struct arp_table *apt;
218 PRINTK ("arp_lookup(paddr=%X)\n", paddr);
219
220 if (my_ip_addr(paddr)) return (NULL);
221 hash = net32(paddr) & (ARP_TABLE_SIZE - 1);
222 cli();
223 for (apt = arp_table[hash]; apt != NULL; apt = apt->next)
224 {
225 if (apt->ip == paddr)
226 {
227 sti();
228 return (apt);
229 }
230 }
231 sti();
232 return (NULL);
233 }
234
235 void
236 arp_destroy(unsigned long paddr)
237 {
238 unsigned long hash;
239 struct arp_table *apt;
240 struct arp_table *lapt;
241 PRINTK ("arp_destroy (paddr=%X)\n",paddr);
242
243 if (my_ip_addr(paddr)) return;
244 hash = net32(paddr) & (ARP_TABLE_SIZE - 1);
245
246 cli();
247
248 if (arp_table[hash] == NULL) return;
249
250
251 if (arp_table[hash]->ip == paddr)
252 {
253 apt = arp_table[hash];
254 arp_table[hash] = arp_table[hash]->next;
255 arp_free (apt, sizeof (*apt));
256 sti();
257 return;
258 }
259
260
261 lapt = arp_table[hash];
262 for (apt = arp_table[hash]->next; apt != NULL; apt = apt->next)
263 {
264 if (apt->ip == paddr)
265 {
266 lapt->next = apt->next;
267 arp_free (apt, sizeof (*apt));
268 sti();
269 return;
270 }
271 }
272 sti();
273 }
274
275
276
277 static struct arp_table *
278 create_arp (unsigned long paddr, unsigned char *addr, int hlen)
279 {
280 struct arp_table *apt;
281 unsigned long hash;
282 apt = arp_malloc (sizeof (*apt), GFP_ATOMIC);
283 if (apt == NULL) return (NULL);
284
285 hash = net32(paddr) & (ARP_TABLE_SIZE - 1);
286 apt->ip = paddr;
287 apt->hlen =hlen;
288 memcpy (apt->hard, addr, hlen);
289 apt->last_used=timer_seq;
290 cli();
291 apt->next = arp_table[hash];
292 arp_table[hash] = apt;
293 sti();
294 return (apt);
295 }
296
297 int
298 arp_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
299 {
300 struct arp *arp;
301 struct arp_table *tbl;
302 int ret;
303
304 PRINTK ("<<\n");
305 arp = skb->h.arp;
306 print_arp(arp);
307
308
309 if (arp->hlen != dev->addr_len || dev->type !=NET16( arp->hrd))
310 {
311 free_skb(skb, FREE_READ);
312 return (0);
313 }
314
315
316 if (arp->pro != NET16(ARP_IP_PROT) || arp->plen != 4)
317 {
318 free_skb (skb, FREE_READ);
319 return (0);
320 }
321
322
323 tbl = arp_lookup (*arp_sourcep(arp));
324 if (tbl != NULL)
325 {
326 memcpy (tbl->hard, arp+1, arp->hlen);
327 tbl->hlen = arp->hlen;
328 tbl->last_used = timer_seq;
329 }
330
331 if (!my_ip_addr(*arp_targetp(arp)))
332 {
333 free_skb (skb, FREE_READ);
334 return (0);
335 }
336
337 if (tbl == NULL)
338 create_arp (*arp_sourcep(arp), arp_sourceh(arp), arp->hlen);
339
340
341 send_arp_q();
342
343 if (arp->op != NET16(ARP_REQUEST))
344 {
345 free_skb (skb, FREE_READ);
346 return (0);
347 }
348
349
350 ret = arp_response(arp, dev);
351 free_skb (skb, FREE_READ);
352 return (ret);
353 }
354
355 void
356 arp_snd (unsigned long paddr, struct device *dev, unsigned long saddr)
357 {
358 struct sk_buff *skb;
359 struct arp *arp;
360 struct arp_table *apt;
361 int tmp;
362 PRINTK ("arp_snd (paddr=%X, dev=%X, saddr=%X)\n",paddr, dev, saddr);
363
364
365 apt = create_arp (paddr, NULL, 0);
366 if (apt == NULL) return;
367
368 skb = arp_malloc (sizeof (*arp) + sizeof (*skb) + dev->hard_header_len +
369 2*dev->addr_len+8, GFP_ATOMIC);
370 if (skb == NULL) return;
371
372 skb->sk = NULL;
373 skb->mem_addr = skb;
374 skb->mem_len = sizeof (*arp) + sizeof (*skb) + dev->hard_header_len +
375 2*dev->addr_len+8;
376 skb->arp = 1;
377 skb->dev = dev;
378 skb->len = sizeof (*arp) + dev->hard_header_len + 2*dev->addr_len+8;
379 skb->next = NULL;
380
381 tmp = dev->hard_header ((unsigned char *)(skb+1), dev,
382 ETHERTYPE_ARP, 0, saddr, skb->len);
383 if (tmp < 0)
384 {
385 arp_free (skb->mem_addr, skb->mem_len);
386 return;
387 }
388
389 arp =(struct arp *) ((unsigned char *)skb+sizeof (*skb) + tmp );
390 arp->hrd = net16(dev->type);
391 arp->pro = NET16(ARP_IP_PROT);
392 arp->hlen = dev->addr_len;
393 arp->plen = 4;
394 arp->op = NET16(ARP_REQUEST);
395 *arp_sourcep(arp) = saddr;
396 *arp_targetp(arp) = paddr;
397 memcpy (arp_sourceh(arp), dev->dev_addr, dev->addr_len);
398 memcpy (arp_targeth(arp), dev->broadcast, dev->addr_len);
399 PRINTK(">>\n");
400 print_arp(arp);
401 dev->queue_xmit (skb, dev, 0);
402 }
403
404 int
405 arp_find(unsigned char *haddr, unsigned long paddr, struct device *dev,
406 unsigned long saddr)
407 {
408 struct arp_table *apt;
409 PRINTK ("arp_find(haddr=%X, paddr=%X, dev=%X, saddr=%X)\n",
410 haddr, paddr, dev, saddr);
411 if (my_ip_addr (paddr))
412 {
413 memcpy (haddr, dev->dev_addr, dev->addr_len);
414 return (0);
415 }
416 apt = arp_lookup (paddr);
417 if (apt != NULL)
418 {
419
420
421
422 if (!before (apt->last_used, timer_seq+ARP_TIMEOUT) &&
423 apt->hlen != 0)
424 {
425 apt->last_used=timer_seq;
426 memcpy (haddr, apt->hard, dev->addr_len);
427 return (0);
428 }
429 }
430
431
432
433 if (apt == NULL || after (timer_seq, apt->last_used+ARP_RES_TIME))
434 arp_snd(paddr,dev,saddr);
435
436
437
438
439 *(unsigned long *)haddr = paddr;
440 return (1);
441 }
442
443 void
444 arp_add (unsigned long addr, unsigned char *haddr, struct device *dev)
445 {
446 struct arp_table *apt;
447
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 void
465 arp_queue(struct sk_buff *skb)
466 {
467 cli();
468 if (arp_q == NULL)
469 {
470 arp_q = skb;
471 skb->next = skb;
472 skb->prev = skb;
473 }
474 else
475 {
476 skb->next = arp_q;
477 skb->prev = arp_q->prev;
478 skb->next->prev = skb;
479 skb->prev->next = skb;
480 }
481 sti();
482 }