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