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