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 |