📄 arp.lst
字号:
C51 COMPILER V6.12 ARP 05/31/2006 19:17:24 PAGE 1
C51 COMPILER V6.12, COMPILATION OF MODULE ARP
OBJECT MODULE PLACED IN arp.OBJ
COMPILER INVOKED BY: C:\Keil\C51\BIN\c51.exe arp.c DB OE
stmt level source
1 //* Address Resolution Protocol (ARP) functions. Sits between IP and
2 //* Level 2, mapping IP to Level 2 addresses for all outgoing datagrams.
3 #include "global.h"
*** WARNING C259 IN LINE 154 OF GLOBAL.H: pointer: different mspace
*** ERROR C231 IN LINE 168 OF GLOBAL.H: '_malloc': redefinition
4 #include "mbuf.h"
*** ERROR C141 IN LINE 22 OF MBUF.H: syntax error near ';'
*** ERROR C141 IN LINE 24 OF MBUF.H: syntax error near '}'
*** ERROR C141 IN LINE 41 OF MBUF.H: syntax error near '*', expected ')'
*** ERROR C141 IN LINE 48 OF MBUF.H: syntax error near ','
5 #include "timer.h"
6 #include "iface.h"
*** ERROR C141 IN LINE 38 OF PROC.H: syntax error near 'FILE'
*** ERROR C129 IN LINE 38 OF PROC.H: missing ';' before '*'
7 #include "enet.h"
8 #include "ax25.h"
9 #include "icmp.h"
10 #include "ip.h"
11 #include "arp.h"
12 #include "icmp.h"
13
14 static void arp_output(struct iface *iface,enum arp_hwtype hardware,int32 target);
15
16 /* Hash table headers */
17 struct arp_tab *Arp_tab[HASHMOD];
18
19 struct arp_stat Arp_stat;
20
21 //********************************************************************************
22 //* Resolve an IP address to a hardware address; if not found,initiate query
23 //* and return NULL. If an address is returned, the interface driver may
24 //* send the packet; if NULL is returned,res_arp() will have saved the packet
25 //* on its pending queue,so no further action (like freeing the packet) is
26 //* necessary.
27 uint8 * res_arp(
28 struct iface *iface, /* Pointer to interface block */
29 enum arp_hwtype hardware, /* Hardware type */
30 int32 target, /* Target IP address */
31 struct mbuf **bpp) /* IP datagram to be queued if unresolved */
32 {
33 register struct arp_tab *arp;
34 struct ip ip;
35
36 if((arp = arp_lookup(hardware,target)) != NULL && arp->state == ARP_VALID)
37 return arp->hw_addr;
38 if(arp != NULL){
39 /* Earlier packets are already pending, kick this one back
40 * as a source quench
41 */
42 ntohip(&ip,bpp);
43 icmp_output(&ip,*bpp,ICMP_QUENCH,0,NULL);
44 free_p(bpp);
45 } else {
46 /* Create an entry and put the datagram on the
47 * queue pending an answer
C51 COMPILER V6.12 ARP 05/31/2006 19:17:24 PAGE 2
48 */
49 arp = arp_add(target,hardware,NULL,0);
50 enqueue(&arp->pending,bpp);
51 arp_output(iface,hardware,target);
52 }
53 return NULL;
54 }
55 /* Handle incoming ARP packets. This is almost a direct implementation of
56 * the algorithm on page 5 of RFC 826, except for:
57 * 1. Outgoing datagrams to unresolved addresses are kept on a queue
58 * pending a reply to our ARP request.
59 * 2. The names of the fields in the ARP packet were made more mnemonic.
60 * 3. Requests for IP addresses listed in our table as "published" are
61 * responded to, even if the address is not our own.
62 */
63 void
64 arp_input(
65 struct iface *iface,
66 struct mbuf **bpp
67 ){
68 struct arp arp;
69 struct arp_tab *ap;
70 struct arp_type *at;
71 int i;
72
73 Arp_stat.recv++;
74 if(ntoharp(&arp,bpp) == -1) /* Convert into host format */
75 return;
76 if(arp.hardware >= NHWTYPES){
77 /* Unknown hardware type, ignore */
78 Arp_stat.badtype++;
79 return;
80 }
81 at = &Arp_type[arp.hardware];
82 if(arp.protocol != at->iptype){
83 /* Unsupported protocol type, ignore */
84 Arp_stat.badtype++;
85 return;
86 }
87 if(arp.hwalen > MAXHWALEN || arp.pralen != sizeof(int32)){
88 /* Incorrect protocol addr length (different hw addr lengths
89 * are OK since AX.25 addresses can be of variable length)
90 */
91 Arp_stat.badlen++;
92 return;
93 }
94 if(memcmp(arp.shwaddr,at->bdcst,at->hwalen) == 0){
95 /* This guy is trying to say he's got the broadcast address! */
96 Arp_stat.badaddr++;
97 return;
98 }
99 /* If this guy is already in the table, update its entry
100 * unless it's a manual entry (noted by the lack of a timer)
101 */
102 ap = NULL; /* ap plays the role of merge_flag in the spec */
103 if((ap = arp_lookup(arp.hardware,arp.sprotaddr)) != NULL
104 && dur_timer(&ap->timer) != 0){
105 ap = arp_add(arp.sprotaddr,arp.hardware,arp.shwaddr,0);
106 }
107 /* See if we're the address they're looking for */
108 if(ismyaddr(arp.tprotaddr) != NULL){
109 if(ap == NULL) /* Only if not already in the table */
C51 COMPILER V6.12 ARP 05/31/2006 19:17:24 PAGE 3
110 arp_add(arp.sprotaddr,arp.hardware,arp.shwaddr,0);
111
112 if(arp.opcode == ARP_REQUEST){
113 /* Swap sender's and target's (us) hardware and protocol
114 * fields, and send the packet back as a reply
115 */
116 memcpy(arp.thwaddr,arp.shwaddr,(uint16)arp.hwalen);
117 /* Mark the end of the sender's AX.25 address
118 * in case he didn't
119 */
120 if(arp.hardware == ARP_AX25)
121 arp.thwaddr[arp.hwalen-1] |= E;
122
123 memcpy(arp.shwaddr,iface->hwaddr,at->hwalen);
124 arp.tprotaddr = arp.sprotaddr;
125 arp.sprotaddr = iface->addr;
126 arp.opcode = ARP_REPLY;
127 if((*bpp = htonarp(&arp)) == NULL)
128 return;
129
130 if(iface->forw != NULL)
131 (*iface->forw->output)(iface->forw,
132 arp.thwaddr,iface->forw->hwaddr,at->arptype,bpp);
133 else
134 (*iface->output)(iface,arp.thwaddr,
135 iface->hwaddr,at->arptype,bpp);
136 Arp_stat.inreq++;
137 } else {
138 Arp_stat.replies++;
139 }
140 } else if(arp.opcode == ARP_REQUEST
141 && (ap = arp_lookup(arp.hardware,arp.tprotaddr)) != NULL
142 && ap->pub){
143 /* Otherwise, respond if the guy he's looking for is
144 * published in our table.
145 */
146 memcpy(arp.thwaddr,arp.shwaddr,(uint16)arp.hwalen);
147 memcpy(arp.shwaddr,ap->hw_addr,at->hwalen);
148 arp.tprotaddr = arp.sprotaddr;
149 arp.sprotaddr = ap->ip_addr;
150 arp.opcode = ARP_REPLY;
151 if((*bpp = htonarp(&arp)) == NULL)
152 return;
153 if(iface->forw != NULL)
154 (*iface->forw->output)(iface->forw,
155 arp.thwaddr,iface->forw->hwaddr,at->arptype,bpp);
156 else
157 (*iface->output)(iface,arp.thwaddr,
158 iface->hwaddr,at->arptype,bpp);
159 Arp_stat.inreq++;
160 } else if(arp.opcode == REVARP_REQUEST){
161 for(i=0;i<HASHMOD;i++)
162 for(ap = Arp_tab[i];ap != NULL;ap = ap->next)
163 if(memcmp(ap->hw_addr,arp.thwaddr,at->hwalen) == 0)
164 goto found;
165 found: if(ap != NULL && ap->pub){
166 memcpy(arp.shwaddr,iface->hwaddr,at->hwalen);
167 arp.tprotaddr = ap->ip_addr;
168 arp.sprotaddr = iface->addr;
169 arp.opcode = REVARP_REPLY;
170 if((*bpp = htonarp(&arp)) == NULL)
171 return;
C51 COMPILER V6.12 ARP 05/31/2006 19:17:24 PAGE 4
172 if(iface->forw != NULL)
173 (*iface->forw->output)(iface->forw,
174 arp.thwaddr,iface->forw->hwaddr,REVARP_TYPE,bpp);
175 else
176 (*iface->output)(iface,arp.thwaddr,
177 iface->hwaddr,REVARP_TYPE,bpp);
178 Arp_stat.inreq++;
179 }
180 }
181 }
182 /* Add an IP-addr / hardware-addr pair to the ARP table */
183 struct arp_tab *
184 arp_add(ipaddr,hardware,hw_addr,pub)
185 int32 ipaddr; /* IP address, host order */
186 enum arp_hwtype hardware; /* Hardware type */
187 uint8 *hw_addr; /* Hardware address, if known; NULL otherwise */
188 int pub; /* Publish this entry? */
189 {
190 struct mbuf *bp;
191 register struct arp_tab *ap;
192 struct arp_type *at;
193 unsigned hashval;
194
195 if(hardware >=NHWTYPES)
196 return NULL; /* Invalid hardware type */
197 at = &Arp_type[hardware];
198
199 if((ap = arp_lookup(hardware,ipaddr)) == NULL){
200 /* New entry */
201 ap = (struct arp_tab *)callocw(1,sizeof(struct arp_tab));
202 ap->hw_addr = mallocw(at->hwalen);
203 ap->timer.func = arp_drop;
204 ap->timer.arg = ap;
205 ap->hardware = hardware;
206 ap->ip_addr = ipaddr;
207
208 /* Put on head of hash chain */
209 hashval = hash_ip(ipaddr);
210 ap->prev = NULL;
211 ap->next = Arp_tab[hashval];
212 Arp_tab[hashval] = ap;
213 if(ap->next != NULL){
214 ap->next->prev = ap;
215 }
216 }
217 if(hw_addr == NULL){
218 /* Await response */
219 ap->state = ARP_PENDING;
220 set_timer(&ap->timer,Arp_type[hardware].pendtime * 1000L);
221 } else {
222 /* Response has come in, update entry and run through queue */
223 ap->state = ARP_VALID;
224 set_timer(&ap->timer,ARPLIFE*1000L);
225 memcpy(ap->hw_addr,hw_addr,at->hwalen);
226 ap->pub = pub;
227 while((bp = dequeue(&ap->pending)) != NULL)
228 ip_route(NULL,&bp,0);
229 }
230 start_timer(&ap->timer);
231 return ap;
232 }
233
C51 COMPILER V6.12 ARP 05/31/2006 19:17:24 PAGE 5
234 /* Remove an entry from the ARP table */
235 void
236 arp_drop(p)
237 void *p;
238 {
239 register struct arp_tab *ap;
240
241 ap = (struct arp_tab *)p;
242 if(ap == NULL)
243 return;
244 stop_timer(&ap->timer); /* Shouldn't be necessary */
245 if(ap->next != NULL)
246 ap->next->prev = ap->prev;
247 if(ap->prev != NULL)
248 ap->prev->next = ap->next;
249 else
250 Arp_tab[hash_ip(ap->ip_addr)] = ap->next;
251 free_q(&ap->pending);
252 free(ap->hw_addr);
253 free(ap);
254 }
255
256 /* Look up the given IP address in the ARP table */
257 struct arp_tab *
258 arp_lookup(hardware,ipaddr)
259 enum arp_hwtype hardware;
260 int32 ipaddr;
261 {
262 register struct arp_tab *ap;
263
264 for(ap = Arp_tab[hash_ip(ipaddr)]; ap != NULL; ap = ap->next){
265 if(ap->ip_addr == ipaddr && ap->hardware == hardware)
266 break;
267 }
268 return ap;
269 }
270 /* Send an ARP request to resolve IP address target_ip */
271 static void
272 arp_output(iface,hardware,target)
273 struct iface *iface;
274 enum arp_hwtype hardware;
275 int32 target;
276 {
277 struct arp arp;
278 struct mbuf *bp;
279 struct arp_type *at;
280
281 at = &Arp_type[hardware];
282 if(iface->output == NULL)
283 return;
284
285 arp.hardware = hardware;
286 arp.protocol = at->iptype;
287 arp.hwalen = at->hwalen;
288 arp.pralen = sizeof(int32);
289 arp.opcode = ARP_REQUEST;
290 memcpy(arp.shwaddr,iface->hwaddr,at->hwalen);
291 arp.sprotaddr = iface->addr;
292 memset(arp.thwaddr,0,at->hwalen);
293 arp.tprotaddr = target;
294 if((bp = htonarp(&arp)) == NULL)
295 return;
C51 COMPILER V6.12 ARP 05/31/2006 19:17:24 PAGE 6
296 (*iface->output)(iface,at->bdcst,
297 iface->hwaddr,at->arptype,&bp);
298 Arp_stat.outreq++;
299 }
300
C51 COMPILATION COMPLETE. 1 WARNING(S), 7 ERROR(S)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -