📄 arp.c
字号:
1 /*
2 * INET An implementation of the TCP/IP protocol suite for the LINUX
3 * operating system. INET is implemented using the BSD Socket
4 * interface as the means of communication with the user level.
5 *
6 * This file implements the Address Resolution Protocol (ARP),
7 * which is used by TCP/IP to map the IP addresses from a host
8 * to a low-level hardware address (like an Ethernet address)
9 * which it can use to talk to that host.
10 *
11 * NOTE: This module will be rewritten completely in the near future,
12 * because I want it to become a multi-address-family address
13 * resolver, like it should be. It will be put in a separate
14 * directory under 'net', being a protocol of its own. -FvK
15 *
16 * Version: @(#)arp.c 1.0.15 05/25/93
17 *
18 * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
19 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
20 * Arnt Gulbrandsen, <agulbra@pvv.unit.no>
21 *
22 * Fixes:
23 * Stephen A. Wood : arp problems
24 * 'Mr Linux' : arp problems.
25 * Alan Cox : arp_ioctl now checks memory areas with verify_area.
26 * Alan Cox : Non IP arp message now only appears with debugging on.
27 * Alan Cox : arp queue is volatile (may be altered by arp messages while doing sends)
28 * Generic queue code is urgently needed!
29 * Alan Cox : Deleting your own ip addr now gives EINVAL not a printk message.
30 * Alan Cox : Fix to arp linked list error
31 * Alan Cox : Ignore broadcast arp (Linus' idea 8-))
32 * Alan Cox : arp_send memory leak removed
33 * Alan Cox : generic skbuff code fixes.
34 * Alan Cox : 'Bad Packet' only reported on debugging
35 * Alan Cox : Proxy arp.
36 * Alan Cox : skb->link3 maintained by letting the other xmit queue kill the packet.
37 * Alan Cox : Knows about type 3 devices (AX.25) using an AX.25 protocol ID not the ethernet
38 * one.
39 * Dominik Kubla : Better checking
40 * Tegge : Assorted corrections on cross port stuff
41 * Alan Cox : ATF_PERM was backwards! - might be useful now (sigh)
42 * Alan Cox : Arp timer added.
43 *
44 * To Fix:
45 * : arp response allocates an skbuff to send. However there is a perfectly
46 * good spare skbuff the right size about to be freed (the query). Use the
47 * query for the reply. This avoids an out of memory case _and_ speeds arp
48 * up.
49 * : FREE_READ v FREE_WRITE errors. Not critical as loopback arps don't occur
50 *
51 *
52 * This program is free software; you can redistribute it and/or
53 * modify it under the terms of the GNU General Public License
54 * as published by the Free Software Foundation; either version
55 * 2 of the License, or (at your option) any later version.
56 */
57 #include <linux/types.h>
58 #include <linux/string.h>
59 #include <linux/kernel.h>
60 #include <linux/sched.h>
61 #include <linux/config.h>
62 #include <linux/socket.h>
63 #include <linux/sockios.h>
64 #include <linux/timer.h>
65 #include <linux/errno.h>
66 #include <linux/if_arp.h>
67 #include <linux/in.h>
68 #include <asm/system.h>
69 #include <asm/segment.h>
70 #include <stdarg.h>
71 #include "inet.h"
72 #include "dev.h"
73 #include "eth.h"
74 #include "ip.h"
75 #include "route.h"
76 #include "protocol.h"
77 #include "tcp.h"
78 #include "skbuff.h"
79 #include "sock.h"
80 #include "arp.h"
81
82
83 #define ARP_MAX_TRIES 3
84
85
86 static char *unk_print(unsigned char *, int);
87 static char *eth_aprint(unsigned char *, int);
88
89
90 static char *arp_cmds[] = {
91 "0x%04X",
92 "REQUEST",
93 "REPLY",
94 "REVERSE REQUEST",
95 "REVERSE REPLY",
96 NULL
97 };
98 #define ARP_MAX_CMDS (sizeof(arp_cmds) / sizeof(arp_cmds[0]))
99
100 static struct {
101 char *name;
102 char *(*print)(unsigned char *ptr, int len);
103 } arp_types[] = {
104 { "0x%04X", unk_print },
105 { "10 Mbps Ethernet", eth_aprint },
106 { "3 Mbps Ethernet", eth_aprint },
107 { "AX.25", unk_print },
108 { "Pronet", unk_print },
109 { "Chaos", unk_print },
110 { "IEEE 802.2 Ethernet (?)", eth_aprint },
111 { "Arcnet", unk_print },
112 { "AppleTalk", unk_print },
113 { NULL, NULL }
114 };
115 #define ARP_MAX_TYPE (sizeof(arp_types) / sizeof(arp_types[0]))
116
117
118 struct arp_table *arp_tables[ARP_TABLE_SIZE] = {
119 NULL,
120 };
121
122 static int arp_proxies=0; /* So we can avoid the proxy arp
123 overhead with the usual case of
124 no proxy arps */
125
126 struct sk_buff * volatile arp_q = NULL;
127
128 static struct arp_table *arp_lookup(unsigned long addr);
129 static struct arp_table *arp_lookup_proxy(unsigned long addr);
130
131 /* Dump the ADDRESS bytes of an unknown hardware type. */
132 static char *
133 unk_print(unsigned char *ptr, int len)
134 {
135 static char buff[32];
136 char *bufp = buff;
137 int i;
138
139 for (i = 0; i < len; i++)
140 bufp += sprintf(bufp, "%02X ", (*ptr++ & 0377));
141 return(buff);
142 }
143
144
145 /* Dump the ADDRESS bytes of an Ethernet hardware type. */
146 static char *
147 eth_aprint(unsigned char *ptr, int len)
148 {
149 if (len != ETH_ALEN) return("");
150 return(eth_print(ptr));
151 }
152
153
154 /* Dump an ARP packet. Not complete yet for non-Ethernet packets. */
155 static void
156 arp_print(struct arphdr *arp)
157 {
158 int len, idx;
159 unsigned char *ptr;
160
161 if (inet_debug != DBG_ARP) return;
162
163 printk("ARP: ");
164 if (arp == NULL) {
165 printk("(null)\n");
166 return;
167 }
168
169 /* Print the opcode name. */
170 len = htons(arp->ar_op);
171 if (len < ARP_MAX_CMDS) idx = len;
172 else idx = 0;
173 printk("op ");
174 printk(arp_cmds[idx], len);
175
176 /* Print the ARP header. */
177 len = htons(arp->ar_hrd);
178 if (len < ARP_MAX_TYPE) idx = len;
179 else idx = 0;
180 printk(" hrd = "); printk(arp_types[idx].name, len);
181 printk(" pro = 0x%04X\n", htons(arp->ar_pro));
182 printk(" hlen = %d plen = %d\n", arp->ar_hln, arp->ar_pln);
183
184 /*
185 * Print the variable data.
186 * When ARP gets redone (after the formal introduction of NET-2),
187 * this part will be redone. ARP will then be a multi-family address
188 * resolver, and the code below will be made more general. -FvK
189 */
190 ptr = ((unsigned char *) &arp->ar_op) + sizeof(u_short);
191 printk(" sender HA = %s ", arp_types[idx].print(ptr, arp->ar_hln));
192 ptr += arp->ar_hln;
193 printk(" PA = %s\n", in_ntoa(*(unsigned long *) ptr));
194 ptr += arp->ar_pln;
195 printk(" target HA = %s ", arp_types[idx].print(ptr, arp->ar_hln));
196 ptr += arp->ar_hln;
197 printk(" PA = %s\n", in_ntoa(*(unsigned long *) ptr));
198 }
199
200
201 /* This will try to retransmit everything on the queue. */
202 static void
203 arp_send_q(void)
204 {
205 struct sk_buff *skb;
206 struct sk_buff *volatile work_q;
207 cli();
208 work_q = arp_q;
209 skb_new_list_head(&work_q);
210 arp_q = NULL;
211 sti();
212 while((skb=skb_dequeue(&work_q))!=NULL)
213 {
214 IS_SKB(skb);
215 skb->magic = 0;
216 skb->next = NULL;
217 skb->prev = NULL;
218
219 /* Decrement the 'tries' counter. */
220 cli();
221 skb->tries--;
222 if (skb->tries == 0) {
223 /*
224 * Grmpf.
225 * We have tried ARP_MAX_TRIES to resolve the IP address
226 * from this datagram. This means that the machine does
227 * not listen to our ARP requests. Perhaps someone tur-
228 * ned off the thing?
229 * In any case, trying further is useless. So, we kill
230 * this packet from the queue. (grinnik) -FvK
231 */
232 skb->sk = NULL;
233 if(skb->free)
234 kfree_skb(skb, FREE_WRITE);
235 /* If free was 0, magic is now 0, next is 0 and
236 the write queue will notice and kill */
237 sti();
238 continue;
239 }
240
241 /* Can we now complete this packet? */
242 sti();
243 if (skb->arp || !skb->dev->rebuild_header(skb->data, skb->dev)) {
244 skb->arp = 1;
245 skb->dev->queue_xmit(skb, skb->dev, 0);
246 } else {
247 /* Alas. Re-queue it... */
248 skb->magic = ARP_QUEUE_MAGIC;
249 skb_queue_head(&arp_q,skb);
250 }
251 }
252 }
253
254
255 static struct timer_list arp_timer;
256
257 static void arp_queue_ticker(unsigned long data);
258
259 static void arp_queue_kick(void)
260 {
261 arp_timer.expires = 500; /* 5 seconds */
262 arp_timer.data = 0;
263 arp_timer.function = arp_queue_ticker;
264 del_timer(&arp_timer);
265 add_timer(&arp_timer);
266 }
267
268 static void arp_queue_ticker(unsigned long data/*UNUSED*/)
269 {
270 arp_send_q();
271 if (skb_peek(&arp_q))
272 arp_queue_kick();
273 }
274
275
276
277 /* Create and send our response to an ARP request. */
278 static int
279 arp_response(struct arphdr *arp1, struct device *dev, int addrtype)
280 {
281 struct arphdr *arp2;
282 struct sk_buff *skb;
283 unsigned long src, dst;
284 unsigned char *ptr1, *ptr2;
285 int hlen;
286 struct arp_table *apt = NULL;/* =NULL otherwise the compiler gives warnings */
287
288 /* Decode the source (REQUEST) message. */
289 ptr1 = ((unsigned char *) &arp1->ar_op) + sizeof(u_short);
290 src = *((unsigned long *) (ptr1 + arp1->ar_hln));
291 dst = *((unsigned long *) (ptr1 + (arp1->ar_hln * 2) + arp1->ar_pln));
292
293 if(addrtype!=IS_MYADDR)
294 {
295 apt=arp_lookup_proxy(dst);
296 if(apt==NULL)
297 return(1);
298 }
299
300 /* Get some mem and initialize it for the return trip. */
301 skb = alloc_skb(sizeof(struct sk_buff) +
302 sizeof(struct arphdr) +
303 (2 * arp1->ar_hln) + (2 * arp1->ar_pln) +
304 dev->hard_header_len, GFP_ATOMIC);
305 if (skb == NULL) {
306 printk("ARP: no memory available for ARP REPLY!\n");
307 return(1);
308 }
309
310 skb->mem_addr = skb;
311 skb->len = sizeof(struct arphdr) + (2 * arp1->ar_hln) +
312 (2 * arp1->ar_pln) + dev->hard_header_len;
313 skb->mem_len = sizeof(struct sk_buff) + skb->len;
314 hlen = dev->hard_header(skb->data, dev, ETH_P_ARP, src, dst, skb->len);
315 if (hlen < 0) {
316 printk("ARP: cannot create HW frame header for REPLY !\n");
317 kfree_skb(skb, FREE_WRITE);
318 return(1);
319 }
320
321 /*
322 * Fill in the ARP REPLY packet.
323 * This looks ugly, but we have to deal with the variable-length
324 * ARP packets and such. It is not as bad as it looks- FvK
325 */
326 arp2 = (struct arphdr *) (skb->data + hlen);
327 ptr2 = ((unsigned char *) &arp2->ar_op) + sizeof(u_short);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -