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