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
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.
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>
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>
50 #include <linux/config.h>
51 #include <linux/init.h>
53 #include <asm/system.h>
54 #include <asm/uaccess.h>
56 #include <linux/inet.h>
57 #include <linux/etherdevice.h>
59 #include <net/route.h>
60 #include <net/protocol.h>
62 #include <linux/skbuff.h>
66 #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
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.
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! */
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
));
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
;
126 pentry
= &rarp_tables
;
127 while ((entry
= *pentry
) != NULL
)
129 if (entry
->ip
== ip_addr
)
131 *pentry
= entry
->next
;
133 rarp_release_entry(entry
);
136 pentry
= &entry
->next
;
145 static void rarp_destroy_dev(struct device
*dev
)
147 struct rarp_table
*entry
;
148 struct rarp_table
**pentry
;
151 pentry
= &rarp_tables
;
152 while ((entry
= *pentry
) != NULL
)
154 if (entry
->dev
== dev
)
156 *pentry
= entry
->next
;
157 rarp_release_entry(entry
);
160 pentry
= &entry
->next
;
165 static int rarp_device_event(struct notifier_block
*this, unsigned long event
, void *ptr
)
167 if(event
!=NETDEV_DOWN
)
169 rarp_destroy_dev((struct device
*)ptr
);
174 * Called once when data first added to rarp cache with ioctl.
177 static struct notifier_block rarp_dev_notifier
={
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
);
196 static void rarp_end_pkt(void)
200 dev_remove_pack(&rarp_packet_type
);
201 unregister_netdevice_notifier(&rarp_dev_notifier
);
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
;
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
)
237 * If it's not a RARP request, delete it.
239 if (rarp
->ar_op
!= htons(ARPOP_RREQUEST
))
246 * For now we will only deal with IP addresses.
250 #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
251 (rarp
->ar_pro
!= htons(AX25_P_IP
) && dev
->type
== ARPHRD_AX25
) ||
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.
264 * Extract variable width fields
268 rarp_ptr
+=dev
->addr_len
;
269 memcpy(&sip
,rarp_ptr
,4);
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
))
287 arp_send(ARPOP_RREPLY
, ETH_P_RARP
, sip
, dev
, in_dev
->ifa_list
->ifa_address
, sha
,
297 * Set (create) a RARP cache entry.
300 static int rarp_req_set(struct arpreq
*req
)
303 struct rarp_table
*entry
;
304 struct sockaddr_in
*si
;
311 err
= copy_from_user(&r
, req
, sizeof(r
));
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
)
325 htype
= ARPHRD_ETHER
;
328 #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
335 return -EPFNOSUPPORT
;
338 si
= (struct sockaddr_in
*) &r
.arp_pa
;
339 ip
= si
->sin_addr
.s_addr
;
342 printk(KERN_DEBUG
"RARP: SETRARP: requested PA is 0.0.0.0 !\n");
347 * Is it reachable directly ?
350 err
= ip_route_output(&rt
, ip
, 0, 1, 0);
353 if (rt
->rt_flags
&(RTCF_LOCAL
|RTCF_BROADCAST
|RTCF_MULTICAST
|RTCF_DNAT
)) {
360 * Is there an existing entry for this address? Find out...
363 for (entry
= rarp_tables
; entry
!= NULL
; entry
= entry
->next
)
368 * If no entry was found, create a new one.
373 entry
= (struct rarp_table
*) kmalloc(sizeof(struct rarp_table
),
385 /* Block interrupts until table modification is finished */
388 entry
->next
= rarp_tables
;
394 entry
->htype
= htype
;
395 memcpy(&entry
->ha
, &r
.arp_ha
.sa_data
, hlen
);
399 /* Don't unlink if we have entries to serve. */
407 * Get a RARP cache entry.
410 static int rarp_req_get(struct arpreq
*req
)
413 struct rarp_table
*entry
;
414 struct sockaddr_in
*si
;
419 * We only understand about IP addresses...
422 err
= copy_from_user(&r
, req
, sizeof(r
));
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
)
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
)
467 struct sockaddr_in
*si
;
475 err
= copy_from_user(&r
, arg
, sizeof(r
));
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
);
486 return rarp_req_get((struct arpreq
*)arg
);
490 return rarp_req_set((struct arpreq
*)arg
);
499 #ifdef CONFIG_PROC_FS
500 int rarp_get_info(char *buffer
, char **start
, off_t offset
, int length
, int dummy
)
506 struct rarp_table
*entry
;
511 size
= sprintf(buffer
,"RARP disabled until entries added to cache.\n");
517 size
= sprintf(buffer
,
518 "IP address HW type HW address\n");
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",
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]);
550 if(pos
>offset
+length
)
555 *start
= buffer
+(offset
-begin
); /* Start of wanted data */
556 len
-= (offset
-begin
); /* Start slop */
558 len
= length
; /* Ending slop */
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
,
573 #ifdef CONFIG_PROC_FS
574 proc_net_register(&proc_net_rarp
);
576 rarp_ioctl_hook
= rarp_ioctl
;
581 int init_module(void)
587 void cleanup_module(void)
589 struct rarp_table
*rt
, *rt_next
;
590 #ifdef CONFIG_PROC_FS
591 proc_net_unregister(PROC_NET_RARP
);
593 rarp_ioctl_hook
= NULL
;
595 /* Destroy the RARP-table */
599 /* ... and free it. */
600 for ( ; rt
!= NULL
; rt
= rt_next
) {
602 rarp_release_entry(rt
);