Stefan Schuermans commited on 2012-03-24 23:11:26
Showing 3 changed files, with 65 additions and 24 deletions.
... | ... |
@@ -18,11 +18,11 @@ |
18 | 18 |
#define ARP_TAB_FLAG_MAC_OK (2) |
19 | 19 |
struct arp_table |
20 | 20 |
{ |
21 |
- unsigned char flags; /// flags - see constants |
|
22 |
- unsigned char ticks; /// age of entry in 200ms steps |
|
21 |
+ unsigned int flags; /// flags - see constants |
|
22 |
+ unsigned int ticks; /// age of entry in 200ms steps |
|
23 | 23 |
unsigned char mac[6]; |
24 | 24 |
unsigned char ip[4]; |
25 |
-} arp_tab[12]; |
|
25 |
+} arp_tab[16]; |
|
26 | 26 |
|
27 | 27 |
/** |
28 | 28 |
* @brief send an ARP request |
... | ... |
@@ -144,28 +144,16 @@ void arp_recv(void *ptr, unsigned int sz) |
144 | 144 |
if (arp_pack->arp_hdr.op == htons(0x0002) && // ARP reply |
145 | 145 |
mac_eq(arp_pack->arp_hdr.dest_mac, config_mac.mac) && // own MAC address |
146 | 146 |
ip_eq(arp_pack->arp_hdr.dest_ip, config_ip.ip)) { // own IP address |
147 |
- unsigned int i; |
|
148 | 147 |
|
149 |
- // search IP in ARP tabale |
|
150 |
- for (i = 0; i < count(arp_tab); ++i) |
|
151 |
- if ((arp_tab[i].flags & ARP_TAB_FLAG_IN_USE) && |
|
152 |
- ip_eq(arp_pack->arp_hdr.src_ip, arp_tab[i].ip)) |
|
153 |
- break; |
|
154 |
- // if found in ARP table |
|
155 |
- // (we do not want to put an entry in the ARP table |
|
156 |
- // if we have not asked for the MAC of this IP) |
|
157 |
- if (i < count(arp_tab)) { |
|
158 |
- // update ARP table entry |
|
159 |
- arp_tab[i].flags = ARP_TAB_FLAG_IN_USE | ARP_TAB_FLAG_MAC_OK; |
|
160 |
- arp_tab[i].ticks = 0; |
|
161 |
- mac_cpy(arp_tab[i].mac, arp_pack->arp_hdr.src_mac); |
|
148 |
+ // store MAC for IP |
|
149 |
+ arp_store(arp_pack->arp_hdr.src_ip, arp_pack->arp_hdr.src_mac); |
|
150 |
+ |
|
162 | 151 |
// notify IP |
163 | 152 |
// - IP might be waiting for the MAC to transmit a packet |
164 |
- ip_got_mac(arp_tab[i].ip, arp_tab[i].mac); |
|
165 |
- } |
|
153 |
+ ip_got_mac(arp_pack->arp_hdr.src_ip, arp_pack->arp_hdr.src_mac); |
|
154 |
+ |
|
166 | 155 |
return; |
167 | 156 |
} |
168 |
- |
|
169 | 157 |
} |
170 | 158 |
|
171 | 159 |
/** |
... | ... |
@@ -225,3 +213,47 @@ int arp_lookup(unsigned char ip[4], unsigned char mac[6]) |
225 | 213 |
return 1; |
226 | 214 |
} |
227 | 215 |
|
216 |
+/** |
|
217 |
+ * @brief store the MAC for an IP address |
|
218 |
+ * @param[in] ip IP address to store MAC for |
|
219 |
+ * @param[out] mac MAC address for this IP address |
|
220 |
+ */ |
|
221 |
+void arp_store(unsigned char ip[4], unsigned char mac[6]) |
|
222 |
+{ |
|
223 |
+ unsigned int i, j; |
|
224 |
+ |
|
225 |
+ // search IP in ARP table |
|
226 |
+ for (i = 0; i < count(arp_tab); ++i) { |
|
227 |
+ if ((arp_tab[i].flags & ARP_TAB_FLAG_IN_USE) && |
|
228 |
+ ip_eq(ip, arp_tab[i].ip)) |
|
229 |
+ break; |
|
230 |
+ } |
|
231 |
+ |
|
232 |
+ // not found |
|
233 |
+ if (i >= count(arp_tab)) { |
|
234 |
+ // find a free entry |
|
235 |
+ for (i = 0; i < count(arp_tab); ++i) |
|
236 |
+ if (!(arp_tab[i].flags & ARP_TAB_FLAG_IN_USE)) |
|
237 |
+ break; |
|
238 |
+ |
|
239 |
+ // no free entry |
|
240 |
+ if (i >= count(arp_tab)) { |
|
241 |
+ // find oldest entry |
|
242 |
+ i = 0; |
|
243 |
+ for (j = 1; j < count(arp_tab); ++j) |
|
244 |
+ if (arp_tab[j].ticks > arp_tab[i].ticks ) |
|
245 |
+ i = j; |
|
246 |
+ } |
|
247 |
+ |
|
248 |
+ // set up this entry |
|
249 |
+ arp_tab[i].flags = ARP_TAB_FLAG_IN_USE; |
|
250 |
+ arp_tab[i].ticks = 0; |
|
251 |
+ ip_cpy(arp_tab[i].ip, ip); |
|
252 |
+ } |
|
253 |
+ |
|
254 |
+ // update ARP table entry |
|
255 |
+ arp_tab[i].flags = ARP_TAB_FLAG_IN_USE | ARP_TAB_FLAG_MAC_OK; |
|
256 |
+ arp_tab[i].ticks = 0; |
|
257 |
+ mac_cpy(arp_tab[i].mac, mac); |
|
258 |
+} |
|
259 |
+ |
... | ... |
@@ -45,5 +45,12 @@ void arp_recv(void *ptr, unsigned int sz); |
45 | 45 |
*/ |
46 | 46 |
int arp_lookup(unsigned char ip[4], unsigned char mac[6]); |
47 | 47 |
|
48 |
+/** |
|
49 |
+ * @brief store the MAC for an IP address |
|
50 |
+ * @param[in] ip IP address to store MAC for |
|
51 |
+ * @param[out] mac MAC address for this IP address |
|
52 |
+ */ |
|
53 |
+void arp_store(unsigned char ip[4], unsigned char mac[6]); |
|
54 |
+ |
|
48 | 55 |
#endif // #ifdef ARP_H |
49 | 56 |
|
... | ... |
@@ -30,7 +30,7 @@ struct ip_buffer_table |
30 | 30 |
void *ptr; ///< pointer to buffer for packet |
31 | 31 |
unsigned int buf_sz; ///< size of buffer |
32 | 32 |
unsigned int pkg_sz; ///< size of packet in buffer, 0 for packet |
33 |
- unsigned int ticks; //< age of entry (in 200ms) |
|
33 |
+ unsigned int ticks; ///< age of entry (in 200ms) |
|
34 | 34 |
} ip_buffer_tab[] = |
35 | 35 |
{ // put smaller buffers in front of larger buffers |
36 | 36 |
// - then short packets will use smaller buffers more often |
... | ... |
@@ -130,8 +130,7 @@ void ip_recv(void *ptr, unsigned int sz) |
130 | 130 |
(ip_pack->ip_hdr.src[2] & config_ip.mask[2]) == |
131 | 131 |
(config_ip.ip[2] & config_ip.mask[2]) && |
132 | 132 |
(ip_pack->ip_hdr.src[3] & config_ip.mask[3]) == |
133 |
- (config_ip.ip[3] & config_ip.mask[3])) |
|
134 |
- { |
|
133 |
+ (config_ip.ip[3] & config_ip.mask[3])) { |
|
135 | 134 |
// local network address |
136 | 135 |
if ((ip_pack->ip_hdr.src[0] & ~config_ip.mask[0]) == 0x00 && |
137 | 136 |
(ip_pack->ip_hdr.src[1] & ~config_ip.mask[1]) == 0x00 && |
... | ... |
@@ -166,6 +165,9 @@ void ip_recv(void *ptr, unsigned int sz) |
166 | 165 |
if (checksum(&ip_pack->ip_hdr, sizeof(struct ip_header), 0x0000, 0x0000)) |
167 | 166 |
return; |
168 | 167 |
|
168 |
+ // save MAC/IP information in ARP table |
|
169 |
+ arp_store(ip_pack->ip_hdr.src, ip_pack->eth_hdr.src); |
|
170 |
+ |
|
169 | 171 |
// branch according to protocol |
170 | 172 |
switch (ip_pack->ip_hdr.proto) { |
171 | 173 |
// ICMP |
... | ... |
@@ -240,7 +242,7 @@ void ip_send(void *ptr, unsigned int sz) |
240 | 242 |
// find a buffer to store the packet in |
241 | 243 |
for (i = 0; i < count(ip_buffer_tab); i++) { |
242 | 244 |
if (ip_buffer_tab[i].pkg_sz == 0 && // buffer not in use |
243 |
- sz < ip_buffer_tab[i].buf_sz) { // buffer long enough |
|
245 |
+ sz <= ip_buffer_tab[i].buf_sz) { // buffer long enough |
|
244 | 246 |
// put packet into buffer |
245 | 247 |
memcpy(ip_buffer_tab[i].ptr, ptr, sz); |
246 | 248 |
ip_buffer_tab[i].pkg_sz = sz; |
247 | 249 |