This source file includes following definitions.
- rarp_release_entry
- rarp_destroy
- rarp_destroy_dev
- rarp_device_event
- rarp_init_pkt
- rarp_rcv
- rarp_req_set
- rarp_req_get
- rarp_ioctl
- rarp_get_info
- rarp_init
- init_module
- cleanup_module
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 #include <linux/module.h>
35
36 #include <linux/types.h>
37 #include <linux/string.h>
38 #include <linux/kernel.h>
39 #include <linux/sched.h>
40 #include <linux/mm.h>
41 #include <linux/socket.h>
42 #include <linux/sockios.h>
43 #include <linux/errno.h>
44 #include <linux/if_arp.h>
45 #include <linux/in.h>
46 #include <linux/config.h>
47
48 #include <asm/system.h>
49 #include <asm/segment.h>
50 #include <stdarg.h>
51 #include <linux/inet.h>
52 #include <linux/netdevice.h>
53 #include <linux/etherdevice.h>
54 #include <net/ip.h>
55 #include <net/route.h>
56 #include <net/protocol.h>
57 #include <net/tcp.h>
58 #include <linux/skbuff.h>
59 #include <net/sock.h>
60 #include <net/arp.h>
61 #include <net/rarp.h>
62 #ifdef CONFIG_AX25
63 #include <net/ax25.h>
64 #endif
65 #include <linux/proc_fs.h>
66 #include <linux/stat.h>
67
68 extern int (*rarp_ioctl_hook)(unsigned int,void*);
69
70
71
72
73
74
75 struct rarp_table
76 {
77 struct rarp_table *next;
78 unsigned long ip;
79 unsigned char ha[MAX_ADDR_LEN];
80 unsigned char hlen;
81 unsigned char htype;
82 struct device *dev;
83 };
84
85 struct rarp_table *rarp_tables = NULL;
86
87 static int rarp_rcv(struct sk_buff *, struct device *, struct packet_type *);
88
89 static struct packet_type rarp_packet_type =
90 {
91 0,
92 0,
93 rarp_rcv,
94 NULL,
95 NULL
96 };
97
98 static initflag = 1;
99
100
101
102
103
104
105 static inline void rarp_release_entry(struct rarp_table *entry)
106 {
107 kfree_s(entry, sizeof(struct rarp_table));
108 return;
109 }
110
111
112
113
114
115 static void rarp_destroy(unsigned long ip_addr)
116 {
117 struct rarp_table *entry;
118 struct rarp_table **pentry;
119
120 cli();
121 pentry = &rarp_tables;
122 while ((entry = *pentry) != NULL)
123 {
124 if (entry->ip == ip_addr)
125 {
126 *pentry = entry->next;
127 sti();
128 rarp_release_entry(entry);
129 return;
130 }
131 pentry = &entry->next;
132 }
133 sti();
134 }
135
136
137
138
139
140 static void rarp_destroy_dev(struct device *dev)
141 {
142 struct rarp_table *entry;
143 struct rarp_table **pentry;
144
145 cli();
146 pentry = &rarp_tables;
147 while ((entry = *pentry) != NULL)
148 {
149 if (entry->dev == dev)
150 {
151 *pentry = entry->next;
152 sti();
153 rarp_release_entry(entry);
154 }
155 else
156 pentry = &entry->next;
157 }
158 sti();
159 }
160
161 static int rarp_device_event(struct notifier_block *this, unsigned long event, void *ptr)
162 {
163 if(event!=NETDEV_DOWN)
164 return NOTIFY_DONE;
165 rarp_destroy_dev((struct device *)ptr);
166 return NOTIFY_DONE;
167 }
168
169
170
171
172
173 static struct notifier_block rarp_dev_notifier={
174 rarp_device_event,
175 NULL,
176 0
177 };
178
179 static void rarp_init_pkt (void)
180 {
181
182 rarp_packet_type.type=htons(ETH_P_RARP);
183 dev_add_pack(&rarp_packet_type);
184 register_netdevice_notifier(&rarp_dev_notifier);
185 }
186
187
188
189
190
191
192
193 static int rarp_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
194 {
195
196
197
198 struct arphdr *rarp = (struct arphdr *) skb->data;
199 unsigned char *rarp_ptr = skb_pull(skb,sizeof(struct arphdr));
200 struct rarp_table *entry;
201 long sip,tip;
202 unsigned char *sha,*tha;
203
204
205
206
207
208 if (rarp->ar_hln != dev->addr_len || dev->type != ntohs(rarp->ar_hrd)
209 || dev->flags&IFF_NOARP)
210 {
211 kfree_skb(skb, FREE_READ);
212 return 0;
213 }
214
215
216
217
218 if (rarp->ar_op != htons(ARPOP_RREQUEST))
219 {
220 kfree_skb(skb, FREE_READ);
221 return 0;
222 }
223
224
225
226
227
228 if (
229 #ifdef CONFIG_AX25
230 (rarp->ar_pro != htons(AX25_P_IP) && dev->type == ARPHRD_AX25) ||
231 #endif
232 (rarp->ar_pro != htons(ETH_P_IP) && dev->type != ARPHRD_AX25)
233 || rarp->ar_pln != 4)
234 {
235
236
237
238 kfree_skb(skb, FREE_READ);
239 return 0;
240 }
241
242
243
244
245
246 sha=rarp_ptr;
247 rarp_ptr+=dev->addr_len;
248 memcpy(&sip,rarp_ptr,4);
249 rarp_ptr+=4;
250 tha=rarp_ptr;
251 rarp_ptr+=dev->addr_len;
252 memcpy(&tip,rarp_ptr,4);
253
254
255
256
257
258 cli();
259 for (entry = rarp_tables; entry != NULL; entry = entry->next)
260 if (!memcmp(entry->ha, tha, rarp->ar_hln))
261 break;
262
263 if (entry != NULL)
264 {
265 sip=entry->ip;
266 sti();
267
268 arp_send(ARPOP_RREPLY, ETH_P_RARP, sip, dev, dev->pa_addr, sha,
269 dev->dev_addr, sha);
270 }
271 else
272 sti();
273
274 kfree_skb(skb, FREE_READ);
275 return 0;
276 }
277
278
279
280
281
282
283 static int rarp_req_set(struct arpreq *req)
284 {
285 struct arpreq r;
286 struct rarp_table *entry;
287 struct sockaddr_in *si;
288 int htype, hlen;
289 unsigned long ip;
290 struct rtable *rt;
291 struct device * dev;
292
293 memcpy_fromfs(&r, req, sizeof(r));
294
295
296
297
298
299 if (r.arp_pa.sa_family != AF_INET)
300 return -EPFNOSUPPORT;
301
302 switch (r.arp_ha.sa_family)
303 {
304 case ARPHRD_ETHER:
305 htype = ARPHRD_ETHER;
306 hlen = ETH_ALEN;
307 break;
308 #ifdef CONFIG_AX25
309 case ARPHRD_AX25:
310 htype = ARPHRD_AX25;
311 hlen = 7;
312 break;
313 #endif
314 default:
315 return -EPFNOSUPPORT;
316 }
317
318 si = (struct sockaddr_in *) &r.arp_pa;
319 ip = si->sin_addr.s_addr;
320 if (ip == 0)
321 {
322 printk("RARP: SETRARP: requested PA is 0.0.0.0 !\n");
323 return -EINVAL;
324 }
325
326
327
328
329
330 rt = ip_rt_route(ip, 0);
331 if (rt == NULL)
332 return -ENETUNREACH;
333 dev = rt->rt_dev;
334 ip_rt_put(rt);
335
336
337
338
339
340 cli();
341 for (entry = rarp_tables; entry != NULL; entry = entry->next)
342 if (entry->ip == ip)
343 break;
344
345
346
347
348
349 if (entry == NULL)
350 {
351 entry = (struct rarp_table *) kmalloc(sizeof(struct rarp_table),
352 GFP_ATOMIC);
353 if (entry == NULL)
354 {
355 sti();
356 return -ENOMEM;
357 }
358 if (initflag)
359 {
360 rarp_init_pkt();
361 initflag=0;
362 }
363
364 entry->next = rarp_tables;
365 rarp_tables = entry;
366 }
367
368 entry->ip = ip;
369 entry->hlen = hlen;
370 entry->htype = htype;
371 memcpy(&entry->ha, &r.arp_ha.sa_data, hlen);
372 entry->dev = dev;
373
374 sti();
375
376 return 0;
377 }
378
379
380
381
382
383
384 static int rarp_req_get(struct arpreq *req)
385 {
386 struct arpreq r;
387 struct rarp_table *entry;
388 struct sockaddr_in *si;
389 unsigned long ip;
390
391
392
393
394
395 memcpy_fromfs(&r, req, sizeof(r));
396
397 if (r.arp_pa.sa_family != AF_INET)
398 return -EPFNOSUPPORT;
399
400
401
402
403
404 si = (struct sockaddr_in *) &r.arp_pa;
405 ip = si->sin_addr.s_addr;
406
407 cli();
408 for (entry = rarp_tables; entry != NULL; entry = entry->next)
409 if (entry->ip == ip)
410 break;
411
412 if (entry == NULL)
413 {
414 sti();
415 return -ENXIO;
416 }
417
418
419
420
421
422 memcpy(r.arp_ha.sa_data, &entry->ha, entry->hlen);
423 r.arp_ha.sa_family = entry->htype;
424 sti();
425
426
427
428
429
430 memcpy_tofs(req, &r, sizeof(r));
431 return 0;
432 }
433
434
435
436
437
438
439 int rarp_ioctl(unsigned int cmd, void *arg)
440 {
441 struct arpreq r;
442 struct sockaddr_in *si;
443 int err;
444
445 switch(cmd)
446 {
447 case SIOCDRARP:
448 if (!suser())
449 return -EPERM;
450 err = verify_area(VERIFY_READ, arg, sizeof(struct arpreq));
451 if(err)
452 return err;
453 memcpy_fromfs(&r, arg, sizeof(r));
454 if (r.arp_pa.sa_family != AF_INET)
455 return -EPFNOSUPPORT;
456 si = (struct sockaddr_in *) &r.arp_pa;
457 rarp_destroy(si->sin_addr.s_addr);
458 return 0;
459
460 case SIOCGRARP:
461 err = verify_area(VERIFY_WRITE, arg, sizeof(struct arpreq));
462 if(err)
463 return err;
464 return rarp_req_get((struct arpreq *)arg);
465 case SIOCSRARP:
466 if (!suser())
467 return -EPERM;
468 err = verify_area(VERIFY_READ, arg, sizeof(struct arpreq));
469 if(err)
470 return err;
471 return rarp_req_set((struct arpreq *)arg);
472 default:
473 return -EINVAL;
474 }
475
476
477 return 0;
478 }
479
480 int rarp_get_info(char *buffer, char **start, off_t offset, int length, int dummy)
481 {
482 int len=0;
483 off_t begin=0;
484 off_t pos=0;
485 int size;
486 struct rarp_table *entry;
487 char ipbuffer[20];
488 unsigned long netip;
489 if (initflag)
490 {
491 size = sprintf(buffer,"RARP disabled until entries added to cache.\n");
492 pos+=size;
493 len+=size;
494 }
495 else
496 {
497 size = sprintf(buffer,
498 "IP address HW type HW address\n");
499 pos+=size;
500 len+=size;
501
502 cli();
503 for(entry=rarp_tables; entry!=NULL; entry=entry->next)
504 {
505 netip=htonl(entry->ip);
506 sprintf(ipbuffer,"%d.%d.%d.%d",
507 (unsigned int)(netip>>24)&255,
508 (unsigned int)(netip>>16)&255,
509 (unsigned int)(netip>>8)&255,
510 (unsigned int)(netip)&255);
511
512 size = sprintf(buffer+len,
513 "%-17s%-20s%02x:%02x:%02x:%02x:%02x:%02x\n",
514 ipbuffer,
515 "10Mbps Ethernet",
516 (unsigned int)entry->ha[0],
517 (unsigned int)entry->ha[1],
518 (unsigned int)entry->ha[2],
519 (unsigned int)entry->ha[3],
520 (unsigned int)entry->ha[4],
521 (unsigned int)entry->ha[5]);
522
523 len+=size;
524 pos=begin+len;
525
526 if(pos<offset)
527 {
528 len=0;
529 begin=pos;
530 }
531 if(pos>offset+length)
532 break;
533 }
534 sti();
535 }
536
537 *start = buffer+(offset-begin);
538 len -= (offset-begin);
539 if (len>length)
540 len = length;
541 return len;
542 }
543
544 void
545 rarp_init(void)
546 {
547 proc_net_register(&(struct proc_dir_entry) {
548 PROC_NET_RARP, 4, "rarp",
549 S_IFREG | S_IRUGO, 1, 0, 0,
550 0, &proc_net_inode_operations,
551 rarp_get_info
552 });
553 rarp_ioctl_hook = rarp_ioctl;
554 }
555
556 #ifdef MODULE
557
558 int init_module(void)
559 {
560 rarp_init();
561 return 0;
562 }
563
564 void cleanup_module(void)
565 {
566 struct rarp_table *rt, *rt_next;
567 proc_net_unregister(PROC_NET_RARP);
568 rarp_ioctl_hook = NULL;
569 cli();
570
571 rt = rarp_tables;
572 rarp_tables = NULL;
573 sti();
574
575 for ( ; rt != NULL; rt = rt_next) {
576 rt_next = rt->next;
577 rarp_release_entry(rt);
578 }
579 }
580 #endif