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