Linux 2.2.0
[davej-history.git] / net / ipv4 / rarp.c
blob7f7c7e3f2674523c0ec7da4b083f6e74076f6480
1 /* linux/net/inet/rarp.c
3 * Copyright (C) 1994 by Ross Martin
4 * Based on linux/net/inet/arp.c, Copyright (C) 1994 by Florian La Roche
6 * $Id: rarp.c,v 1.25 1998/06/19 13:22:34 davem Exp $
8 * This module implements the Reverse Address Resolution Protocol
9 * (RARP, RFC 903), which is used to convert low level addresses such
10 * as Ethernet addresses into high level addresses such as IP addresses.
11 * The most common use of RARP is as a means for a diskless workstation
12 * to discover its IP address during a network boot.
15 *** WARNING:::::::::::::::::::::::::::::::::WARNING
16 ****
17 ***** SUN machines seem determined to boot solely from the person who
18 **** answered their RARP query. NEVER add a SUN to your RARP table
19 *** unless you have all the rest to boot the box from it.
22 * Currently, only Ethernet address -> IP address is likely to work.
23 * (Is RARP ever used for anything else?)
25 * This code is free software; you can redistribute it and/or
26 * modify it under the terms of the GNU General Public License
27 * as published by the Free Software Foundation; either version
28 * 2 of the License, or (at your option) any later version.
30 * Fixes
31 * Alan Cox : Rarp delete on device down needed as
32 * reported by Walter Wolfgang.
33 * Mike McLagan : Routing by source
37 #include <linux/module.h>
39 #include <linux/types.h>
40 #include <linux/string.h>
41 #include <linux/kernel.h>
42 #include <linux/sched.h>
43 #include <linux/mm.h>
44 #include <linux/socket.h>
45 #include <linux/sockios.h>
46 #include <linux/errno.h>
47 #include <linux/netdevice.h>
48 #include <linux/if_arp.h>
49 #include <linux/in.h>
50 #include <linux/config.h>
51 #include <linux/init.h>
53 #include <asm/system.h>
54 #include <asm/uaccess.h>
55 #include <stdarg.h>
56 #include <linux/inet.h>
57 #include <linux/etherdevice.h>
58 #include <net/ip.h>
59 #include <net/route.h>
60 #include <net/protocol.h>
61 #include <net/tcp.h>
62 #include <linux/skbuff.h>
63 #include <net/sock.h>
64 #include <net/arp.h>
65 #include <net/rarp.h>
66 #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
67 #include <net/ax25.h>
68 #endif
69 #include <linux/proc_fs.h>
70 #include <linux/stat.h>
72 extern int (*rarp_ioctl_hook)(unsigned int,void*);
75 * This structure defines the RARP mapping cache. As long as we make
76 * changes in this structure, we keep interrupts off.
79 struct rarp_table
81 struct rarp_table *next; /* Linked entry list */
82 unsigned long ip; /* ip address of entry */
83 unsigned char ha[MAX_ADDR_LEN]; /* Hardware address */
84 unsigned char hlen; /* Length of hardware address */
85 unsigned char htype; /* Type of hardware in use */
86 struct device *dev; /* Device the entry is tied to */
89 struct rarp_table *rarp_tables = NULL;
91 static int rarp_rcv(struct sk_buff *, struct device *, struct packet_type *);
93 static struct packet_type rarp_packet_type =
95 0, /* Should be: __constant_htons(ETH_P_RARP) - but this _doesn't_ come out constant! */
96 0, /* copy */
97 rarp_rcv,
98 NULL,
99 NULL
102 static int initflag = 1;
106 * Release the memory for this entry.
109 static inline void rarp_release_entry(struct rarp_table *entry)
111 kfree_s(entry, sizeof(struct rarp_table));
112 MOD_DEC_USE_COUNT;
113 return;
117 * Delete a RARP mapping entry in the cache.
120 static void rarp_destroy(unsigned long ip_addr)
122 struct rarp_table *entry;
123 struct rarp_table **pentry;
125 start_bh_atomic();
126 pentry = &rarp_tables;
127 while ((entry = *pentry) != NULL)
129 if (entry->ip == ip_addr)
131 *pentry = entry->next;
132 end_bh_atomic();
133 rarp_release_entry(entry);
134 return;
136 pentry = &entry->next;
138 end_bh_atomic();
142 * Flush a device.
145 static void rarp_destroy_dev(struct device *dev)
147 struct rarp_table *entry;
148 struct rarp_table **pentry;
150 start_bh_atomic();
151 pentry = &rarp_tables;
152 while ((entry = *pentry) != NULL)
154 if (entry->dev == dev)
156 *pentry = entry->next;
157 rarp_release_entry(entry);
159 else
160 pentry = &entry->next;
162 end_bh_atomic();
165 static int rarp_device_event(struct notifier_block *this, unsigned long event, void *ptr)
167 if(event!=NETDEV_DOWN)
168 return NOTIFY_DONE;
169 rarp_destroy_dev((struct device *)ptr);
170 return NOTIFY_DONE;
174 * Called once when data first added to rarp cache with ioctl.
177 static struct notifier_block rarp_dev_notifier={
178 rarp_device_event,
179 NULL,
183 static int rarp_pkt_inited=0;
185 static void rarp_init_pkt (void)
187 /* Register the packet type */
188 rarp_packet_type.type=htons(ETH_P_RARP);
189 dev_add_pack(&rarp_packet_type);
190 register_netdevice_notifier(&rarp_dev_notifier);
191 rarp_pkt_inited=1;
194 #ifdef MODULE
196 static void rarp_end_pkt(void)
198 if(!rarp_pkt_inited)
199 return;
200 dev_remove_pack(&rarp_packet_type);
201 unregister_netdevice_notifier(&rarp_dev_notifier);
202 rarp_pkt_inited=0;
205 #endif
208 * Receive an arp request by the device layer. Maybe it should be
209 * rewritten to use the incoming packet for the reply. The current
210 * "overhead" time isn't that high...
213 static int rarp_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
216 * We shouldn't use this type conversion. Check later.
218 struct arphdr *rarp = (struct arphdr *) skb->data;
219 unsigned char *rarp_ptr = skb_pull(skb,sizeof(struct arphdr));
220 struct rarp_table *entry;
221 struct in_device *in_dev = dev->ip_ptr;
222 long sip,tip;
223 unsigned char *sha,*tha; /* s for "source", t for "target" */
226 * If this test doesn't pass, it's not IP, or we should ignore it anyway
229 if (rarp->ar_hln != dev->addr_len || dev->type != ntohs(rarp->ar_hrd)
230 || dev->flags&IFF_NOARP || !in_dev || !in_dev->ifa_list)
232 kfree_skb(skb);
233 return 0;
237 * If it's not a RARP request, delete it.
239 if (rarp->ar_op != htons(ARPOP_RREQUEST))
241 kfree_skb(skb);
242 return 0;
246 * For now we will only deal with IP addresses.
249 if (
250 #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
251 (rarp->ar_pro != htons(AX25_P_IP) && dev->type == ARPHRD_AX25) ||
252 #endif
253 (rarp->ar_pro != htons(ETH_P_IP) && dev->type != ARPHRD_AX25)
254 || rarp->ar_pln != 4)
257 * This packet is not for us. Remove it.
259 kfree_skb(skb);
260 return 0;
264 * Extract variable width fields
267 sha=rarp_ptr;
268 rarp_ptr+=dev->addr_len;
269 memcpy(&sip,rarp_ptr,4);
270 rarp_ptr+=4;
271 tha=rarp_ptr;
272 rarp_ptr+=dev->addr_len;
273 memcpy(&tip,rarp_ptr,4);
276 * Process entry. Use tha for table lookup according to RFC903.
279 for (entry = rarp_tables; entry != NULL; entry = entry->next)
280 if (!memcmp(entry->ha, tha, rarp->ar_hln))
281 break;
283 if (entry != NULL)
285 sip=entry->ip;
287 arp_send(ARPOP_RREPLY, ETH_P_RARP, sip, dev, in_dev->ifa_list->ifa_address, sha,
288 dev->dev_addr, sha);
291 kfree_skb(skb);
292 return 0;
297 * Set (create) a RARP cache entry.
300 static int rarp_req_set(struct arpreq *req)
302 struct arpreq r;
303 struct rarp_table *entry;
304 struct sockaddr_in *si;
305 int htype, hlen;
306 unsigned long ip;
307 struct rtable *rt;
308 struct device * dev;
309 int err;
311 err = copy_from_user(&r, req, sizeof(r));
312 if (err)
313 return -EFAULT;
316 * We only understand about IP addresses...
319 if (r.arp_pa.sa_family != AF_INET)
320 return -EPFNOSUPPORT;
322 switch (r.arp_ha.sa_family)
324 case ARPHRD_ETHER:
325 htype = ARPHRD_ETHER;
326 hlen = ETH_ALEN;
327 break;
328 #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
329 case ARPHRD_AX25:
330 htype = ARPHRD_AX25;
331 hlen = 7;
332 break;
333 #endif
334 default:
335 return -EPFNOSUPPORT;
338 si = (struct sockaddr_in *) &r.arp_pa;
339 ip = si->sin_addr.s_addr;
340 if (ip == 0)
342 printk(KERN_DEBUG "RARP: SETRARP: requested PA is 0.0.0.0 !\n");
343 return -EINVAL;
347 * Is it reachable directly ?
350 err = ip_route_output(&rt, ip, 0, 1, 0);
351 if (err)
352 return err;
353 if (rt->rt_flags&(RTCF_LOCAL|RTCF_BROADCAST|RTCF_MULTICAST|RTCF_DNAT)) {
354 ip_rt_put(rt);
355 return -EINVAL;
357 dev = rt->u.dst.dev;
360 * Is there an existing entry for this address? Find out...
363 for (entry = rarp_tables; entry != NULL; entry = entry->next)
364 if (entry->ip == ip)
365 break;
368 * If no entry was found, create a new one.
371 if (entry == NULL)
373 entry = (struct rarp_table *) kmalloc(sizeof(struct rarp_table),
374 GFP_ATOMIC);
375 if (entry == NULL)
377 return -ENOMEM;
379 if (initflag)
381 rarp_init_pkt();
382 initflag=0;
385 /* Block interrupts until table modification is finished */
387 cli();
388 entry->next = rarp_tables;
389 rarp_tables = entry;
391 cli();
392 entry->ip = ip;
393 entry->hlen = hlen;
394 entry->htype = htype;
395 memcpy(&entry->ha, &r.arp_ha.sa_data, hlen);
396 entry->dev = dev;
397 sti();
399 /* Don't unlink if we have entries to serve. */
400 MOD_INC_USE_COUNT;
402 return 0;
407 * Get a RARP cache entry.
410 static int rarp_req_get(struct arpreq *req)
412 struct arpreq r;
413 struct rarp_table *entry;
414 struct sockaddr_in *si;
415 unsigned long ip;
416 int err;
419 * We only understand about IP addresses...
422 err = copy_from_user(&r, req, sizeof(r));
423 if (err)
424 return -EFAULT;
426 if (r.arp_pa.sa_family != AF_INET)
427 return -EPFNOSUPPORT;
430 * Is there an existing entry for this address?
433 si = (struct sockaddr_in *) &r.arp_pa;
434 ip = si->sin_addr.s_addr;
436 for (entry = rarp_tables; entry != NULL; entry = entry->next)
437 if (entry->ip == ip)
438 break;
440 if (entry == NULL)
442 return -ENXIO;
446 * We found it; copy into structure.
449 memcpy(r.arp_ha.sa_data, &entry->ha, entry->hlen);
450 r.arp_ha.sa_family = entry->htype;
453 * Copy the information back
456 return copy_to_user(req, &r, sizeof(r)) ? -EFAULT : 0;
461 * Handle a RARP layer I/O control request.
464 int rarp_ioctl(unsigned int cmd, void *arg)
466 struct arpreq r;
467 struct sockaddr_in *si;
468 int err;
470 switch(cmd)
472 case SIOCDRARP:
473 if (!suser())
474 return -EPERM;
475 err = copy_from_user(&r, arg, sizeof(r));
476 if (err)
477 return -EFAULT;
478 if (r.arp_pa.sa_family != AF_INET)
479 return -EPFNOSUPPORT;
480 si = (struct sockaddr_in *) &r.arp_pa;
481 rarp_destroy(si->sin_addr.s_addr);
482 return 0;
484 case SIOCGRARP:
486 return rarp_req_get((struct arpreq *)arg);
487 case SIOCSRARP:
488 if (!suser())
489 return -EPERM;
490 return rarp_req_set((struct arpreq *)arg);
491 default:
492 return -EINVAL;
495 /*NOTREACHED*/
496 return 0;
499 #ifdef CONFIG_PROC_FS
500 int rarp_get_info(char *buffer, char **start, off_t offset, int length, int dummy)
502 int len=0;
503 off_t begin=0;
504 off_t pos=0;
505 int size;
506 struct rarp_table *entry;
507 char ipbuffer[20];
508 unsigned long netip;
509 if (initflag)
511 size = sprintf(buffer,"RARP disabled until entries added to cache.\n");
512 pos+=size;
513 len+=size;
515 else
517 size = sprintf(buffer,
518 "IP address HW type HW address\n");
519 pos+=size;
520 len+=size;
522 for(entry=rarp_tables; entry!=NULL; entry=entry->next)
524 netip=htonl(entry->ip); /* switch to network order */
525 sprintf(ipbuffer,"%d.%d.%d.%d",
526 (unsigned int)(netip>>24)&255,
527 (unsigned int)(netip>>16)&255,
528 (unsigned int)(netip>>8)&255,
529 (unsigned int)(netip)&255);
531 size = sprintf(buffer+len,
532 "%-17s%-20s%02x:%02x:%02x:%02x:%02x:%02x\n",
533 ipbuffer,
534 "10Mbps Ethernet",
535 (unsigned int)entry->ha[0],
536 (unsigned int)entry->ha[1],
537 (unsigned int)entry->ha[2],
538 (unsigned int)entry->ha[3],
539 (unsigned int)entry->ha[4],
540 (unsigned int)entry->ha[5]);
542 len+=size;
543 pos=begin+len;
545 if(pos<offset)
547 len=0;
548 begin=pos;
550 if(pos>offset+length)
551 break;
555 *start = buffer+(offset-begin); /* Start of wanted data */
556 len -= (offset-begin); /* Start slop */
557 if (len>length)
558 len = length; /* Ending slop */
559 return len;
562 struct proc_dir_entry proc_net_rarp = {
563 PROC_NET_RARP, 4, "rarp",
564 S_IFREG | S_IRUGO, 1, 0, 0,
565 0, &proc_net_inode_operations,
566 rarp_get_info
568 #endif
570 __initfunc(void
571 rarp_init(void))
573 #ifdef CONFIG_PROC_FS
574 proc_net_register(&proc_net_rarp);
575 #endif
576 rarp_ioctl_hook = rarp_ioctl;
579 #ifdef MODULE
581 int init_module(void)
583 rarp_init();
584 return 0;
587 void cleanup_module(void)
589 struct rarp_table *rt, *rt_next;
590 #ifdef CONFIG_PROC_FS
591 proc_net_unregister(PROC_NET_RARP);
592 #endif
593 rarp_ioctl_hook = NULL;
594 cli();
595 /* Destroy the RARP-table */
596 rt = rarp_tables;
597 rarp_tables = NULL;
598 sti();
599 /* ... and free it. */
600 for ( ; rt != NULL; rt = rt_next) {
601 rt_next = rt->next;
602 rarp_release_entry(rt);
604 rarp_end_pkt();
606 #endif