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);
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
292 memcpy_fromfs(&r, req, sizeof(r));
293
294
295
296
297
298 if (r.arp_pa.sa_family != AF_INET)
299 return -EPFNOSUPPORT;
300
301 switch (r.arp_ha.sa_family)
302 {
303 case ARPHRD_ETHER:
304 htype = ARPHRD_ETHER;
305 hlen = ETH_ALEN;
306 break;
307 #ifdef CONFIG_AX25
308 case ARPHRD_AX25:
309 htype = ARPHRD_AX25;
310 hlen = 7;
311 break;
312 #endif
313 default:
314 return -EPFNOSUPPORT;
315 }
316
317 si = (struct sockaddr_in *) &r.arp_pa;
318 ip = si->sin_addr.s_addr;
319 if (ip == 0)
320 {
321 printk("RARP: SETRARP: requested PA is 0.0.0.0 !\n");
322 return -EINVAL;
323 }
324
325
326
327
328
329 rt = ip_rt_route(ip, NULL, NULL);
330 if (rt == NULL)
331 return -ENETUNREACH;
332
333
334
335
336
337 cli();
338 for (entry = rarp_tables; entry != NULL; entry = entry->next)
339 if (entry->ip == ip)
340 break;
341
342
343
344
345
346 if (entry == NULL)
347 {
348 entry = (struct rarp_table *) kmalloc(sizeof(struct rarp_table),
349 GFP_ATOMIC);
350 if (entry == NULL)
351 {
352 sti();
353 return -ENOMEM;
354 }
355 if (initflag)
356 {
357 rarp_init_pkt();
358 initflag=0;
359 }
360
361 entry->next = rarp_tables;
362 rarp_tables = entry;
363 }
364
365 entry->ip = ip;
366 entry->hlen = hlen;
367 entry->htype = htype;
368 memcpy(&entry->ha, &r.arp_ha.sa_data, hlen);
369 entry->dev = rt->rt_dev;
370
371 sti();
372
373 return 0;
374 }
375
376
377
378
379
380
381 static int rarp_req_get(struct arpreq *req)
382 {
383 struct arpreq r;
384 struct rarp_table *entry;
385 struct sockaddr_in *si;
386 unsigned long ip;
387
388
389
390
391
392 memcpy_fromfs(&r, req, sizeof(r));
393
394 if (r.arp_pa.sa_family != AF_INET)
395 return -EPFNOSUPPORT;
396
397
398
399
400
401 si = (struct sockaddr_in *) &r.arp_pa;
402 ip = si->sin_addr.s_addr;
403
404 cli();
405 for (entry = rarp_tables; entry != NULL; entry = entry->next)
406 if (entry->ip == ip)
407 break;
408
409 if (entry == NULL)
410 {
411 sti();
412 return -ENXIO;
413 }
414
415
416
417
418
419 memcpy(r.arp_ha.sa_data, &entry->ha, entry->hlen);
420 r.arp_ha.sa_family = entry->htype;
421 sti();
422
423
424
425
426
427 memcpy_tofs(req, &r, sizeof(r));
428 return 0;
429 }
430
431
432
433
434
435
436 int rarp_ioctl(unsigned int cmd, void *arg)
437 {
438 struct arpreq r;
439 struct sockaddr_in *si;
440 int err;
441
442 switch(cmd)
443 {
444 case SIOCDRARP:
445 if (!suser())
446 return -EPERM;
447 err = verify_area(VERIFY_READ, arg, sizeof(struct arpreq));
448 if(err)
449 return err;
450 memcpy_fromfs(&r, arg, sizeof(r));
451 if (r.arp_pa.sa_family != AF_INET)
452 return -EPFNOSUPPORT;
453 si = (struct sockaddr_in *) &r.arp_pa;
454 rarp_destroy(si->sin_addr.s_addr);
455 return 0;
456
457 case SIOCGRARP:
458 err = verify_area(VERIFY_WRITE, arg, sizeof(struct arpreq));
459 if(err)
460 return err;
461 return rarp_req_get((struct arpreq *)arg);
462 case SIOCSRARP:
463 if (!suser())
464 return -EPERM;
465 err = verify_area(VERIFY_READ, arg, sizeof(struct arpreq));
466 if(err)
467 return err;
468 return rarp_req_set((struct arpreq *)arg);
469 default:
470 return -EINVAL;
471 }
472
473
474 return 0;
475 }
476
477 int rarp_get_info(char *buffer, char **start, off_t offset, int length, int dummy)
478 {
479 int len=0;
480 off_t begin=0;
481 off_t pos=0;
482 int size;
483 struct rarp_table *entry;
484 char ipbuffer[20];
485 unsigned long netip;
486 if (initflag)
487 {
488 size = sprintf(buffer,"RARP disabled until entries added to cache.\n");
489 pos+=size;
490 len+=size;
491 }
492 else
493 {
494 size = sprintf(buffer,
495 "IP address HW type HW address\n");
496 pos+=size;
497 len+=size;
498
499 cli();
500 for(entry=rarp_tables; entry!=NULL; entry=entry->next)
501 {
502 netip=htonl(entry->ip);
503 sprintf(ipbuffer,"%d.%d.%d.%d",
504 (unsigned int)(netip>>24)&255,
505 (unsigned int)(netip>>16)&255,
506 (unsigned int)(netip>>8)&255,
507 (unsigned int)(netip)&255);
508
509 size = sprintf(buffer+len,
510 "%-17s%-20s%02x:%02x:%02x:%02x:%02x:%02x\n",
511 ipbuffer,
512 "10Mbps Ethernet",
513 (unsigned int)entry->ha[0],
514 (unsigned int)entry->ha[1],
515 (unsigned int)entry->ha[2],
516 (unsigned int)entry->ha[3],
517 (unsigned int)entry->ha[4],
518 (unsigned int)entry->ha[5]);
519
520 len+=size;
521 pos=begin+len;
522
523 if(pos<offset)
524 {
525 len=0;
526 begin=pos;
527 }
528 if(pos>offset+length)
529 break;
530 }
531 sti();
532 }
533
534 *start = buffer+(offset-begin);
535 len -= (offset-begin);
536 if (len>length)
537 len = length;
538 return len;
539 }
540
541 void
542 rarp_init(void)
543 {
544 proc_net_register(&(struct proc_dir_entry) {
545 PROC_NET_RARP, 4, "rarp",
546 S_IFREG | S_IRUGO, 1, 0, 0,
547 0, &proc_net_inode_operations,
548 rarp_get_info
549 });
550 rarp_ioctl_hook = rarp_ioctl;
551 }
552
553 #ifdef MODULE
554
555 int init_module(void)
556 {
557 rarp_init();
558 return 0;
559 }
560
561 void cleanup_module(void)
562 {
563 struct rarp_table *rt, *rt_next;
564 proc_net_unregister(PROC_NET_RARP);
565 rarp_ioctl_hook = NULL;
566 cli();
567
568 rt = rarp_tables;
569 rarp_tables = NULL;
570 sti();
571
572 for ( ; rt != NULL; rt = rt_next) {
573 rt_next = rt->next;
574 rarp_release_entry(rt);
575 }
576 }
577
578 #endif