36#include "ip64/ip64-eth.h"
37#include "ip64/ip64-arp.h"
84#define ARP_HWTYPE_ETH 1
93 {{0xff,0xff,0xff,0xff,0xff,0xff}};
97static uint8_t arptime;
103#define LOG_MODULE "IP64"
104#define LOG_LEVEL LOG_LEVEL_IP64
108const uip_ipaddr_t uip_all_zeroes_addr;
121 memset(&arp_table[i].
ipaddr, 0, 4);
137 struct arp_entry *tabptr;
142 tabptr = &arp_table[i];
145 memset(&tabptr->ipaddr, 0, 4);
155 register struct arp_entry *tabptr = arp_table;
162 tabptr = &arp_table[i];
172 memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
173 tabptr->time = arptime;
186 tabptr = &arp_table[i];
198 tabptr = &arp_table[i];
199 if(arptime - tabptr->time > tmpage) {
200 tmpage = arptime - tabptr->time;
205 tabptr = &arp_table[i];
210 uip_ip4addr_copy(&tabptr->ipaddr,
ipaddr);
211 memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
212 tabptr->time = arptime;
216ip64_arp_arp_input(
const uint8_t *packet, uint16_t packet_len)
218 struct arp_hdr *arphdr = (
struct arp_hdr *)packet;
220 if(packet_len <
sizeof(
struct arp_hdr)) {
221 LOG_WARN(
"ARP input: len too small %d\n", packet_len);
225 switch(arphdr->opcode) {
229 LOG_DBG(
"ARP input: request for %d.%d.%d.%d (we are %d.%d.%d.%d)\n",
230 arphdr->dipaddr.u8[0], arphdr->dipaddr.u8[1],
231 arphdr->dipaddr.u8[2], arphdr->dipaddr.u8[3],
232 ip64_get_hostaddr()->u8[0], ip64_get_hostaddr()->u8[1],
233 ip64_get_hostaddr()->u8[2], ip64_get_hostaddr()->u8[3]);
238 arp_update(&arphdr->sipaddr, &arphdr->shwaddr);
242 memcpy(arphdr->dhwaddr.addr, arphdr->shwaddr.addr, 6);
245 memcpy(arphdr->ethhdr.dest.addr, arphdr->dhwaddr.addr, 6);
247 uip_ip4addr_copy(&arphdr->dipaddr, &arphdr->sipaddr);
248 uip_ip4addr_copy(&arphdr->sipaddr, ip64_get_hostaddr());
250 arphdr->ethhdr.type =
UIP_HTONS(IP64_ETH_TYPE_ARP);
251 return sizeof(
struct arp_hdr);
258 arp_update(&arphdr->sipaddr, &arphdr->shwaddr);
267ip64_arp_check_cache(
const uint8_t *nlhdr)
269 struct ipv4_hdr *ipv4_hdr = (
struct ipv4_hdr *)nlhdr;
271 struct arp_entry *tabptr = arp_table;
273 LOG_DBG(
"ARP check cache %d.%d.%d.%d\n",
279 LOG_DBG(
"ARP check return 1\n");
281 }
else if(ipv4_hdr->destipaddr.u8[0] == 224) {
290 ip64_get_netmask())) {
294 uip_ip4addr_copy(&
ipaddr, ip64_get_draddr());
297 uip_ip4addr_copy(&
ipaddr, &ipv4_hdr->destipaddr);
315ip64_arp_create_ethhdr(uint8_t *llhdr,
const uint8_t *nlhdr)
317 struct arp_entry *tabptr = arp_table;
318 struct ipv4_hdr *ipv4_hdr = (
struct ipv4_hdr *)nlhdr;
332 memcpy(ðhdr->dest.addr, &broadcast_ethaddr.addr, 6);
333 }
else if(ipv4_hdr->destipaddr.u8[0] == 224) {
335 ethhdr->dest.addr[0] = 0x01;
336 ethhdr->dest.addr[1] = 0x00;
337 ethhdr->dest.addr[2] = 0x5e;
338 ethhdr->dest.addr[3] = ipv4_hdr->destipaddr.u8[1];
339 ethhdr->dest.addr[4] = ipv4_hdr->destipaddr.u8[2];
340 ethhdr->dest.addr[5] = ipv4_hdr->destipaddr.u8[3];
347 ip64_get_netmask())) {
351 uip_ip4addr_copy(&
ipaddr, ip64_get_draddr());
354 uip_ip4addr_copy(&
ipaddr, &ipv4_hdr->destipaddr);
367 memcpy(ethhdr->dest.addr, tabptr->ethaddr.addr, 6);
372 ethhdr->type =
UIP_HTONS(IP64_ETH_TYPE_IP);
377ip64_arp_create_arp_request(uint8_t *llhdr,
const uint8_t *nlhdr)
379 struct ipv4_hdr *ipv4_hdr = (
struct ipv4_hdr *)nlhdr;
380 struct arp_hdr *arp_hdr = (
struct arp_hdr *)llhdr;
385 ip64_get_netmask())) {
389 uip_ip4addr_copy(&
ipaddr, ip64_get_draddr());
392 uip_ip4addr_copy(&
ipaddr, &ipv4_hdr->destipaddr);
395 memset(arp_hdr->ethhdr.dest.addr, 0xff, 6);
396 memset(arp_hdr->dhwaddr.addr, 0x00, 6);
400 uip_ip4addr_copy(&arp_hdr->dipaddr, &
ipaddr);
401 uip_ip4addr_copy(&arp_hdr->sipaddr, ip64_get_hostaddr());
402 arp_hdr->opcode =
UIP_HTONS(ARP_REQUEST);
403 arp_hdr->hwtype =
UIP_HTONS(ARP_HWTYPE_ETH);
404 arp_hdr->protocol =
UIP_HTONS(IP64_ETH_TYPE_IP);
406 arp_hdr->protolen = 4;
407 arp_hdr->ethhdr.type =
UIP_HTONS(IP64_ETH_TYPE_ARP);
411 return sizeof(
struct arp_hdr);
void * uip_appdata
Pointer to the application data in the packet buffer.
#define uip_ip4addr_cmp(addr1, addr2)
Compare two IP addresses.
#define uip_ipaddr_maskcmp(addr1, addr2, mask)
Compare two IP addresses with netmasks.
#define UIP_HTONS(n)
Convert 16-bit quantity from host byte order to network byte order.
#define uip_ipaddr(addr, addr0, addr1, addr2, addr3)
Construct an IP address from four bytes.
#define uip_ipaddr_to_quad(a)
Convert an IP address to four bytes separated by commas.
#define uip_buf
Macro to access uip_aligned_buf as an array of bytes.
#define UIP_ARP_MAXAGE
The maximum age of ARP table entries measured in 10ths of seconds.
#define UIP_ARPTAB_SIZE
The size of the ARP table.
Header file for the logging system.
static uip_ipaddr_t ipaddr
Pointer to prefix information option in uip_buf.
Representation of an IP address.