net: actually try to figure out destination hardware addresses

This commit is contained in:
K. Lange 2021-06-18 18:54:34 +09:00
parent d8dc85e507
commit 71bd62d516
3 changed files with 56 additions and 7 deletions

View File

@ -62,6 +62,25 @@ struct ArpCacheEntry * net_arp_cache_get(uint32_t addr) {
return out;
}
void net_arp_ask(uint32_t addr, fs_node_t * fsnic) {
struct EthernetDevice * ethnic = fsnic->device;
struct arp_header arp_request = {0};
arp_request.arp_htype = htons(1); /* Ethernet */
arp_request.arp_ptype = htons(ETHERNET_TYPE_IPV4);
arp_request.arp_hlen = 6;
arp_request.arp_plen = 4;
arp_request.arp_oper = htons(1); /* Who is...? */
arp_request.arp_data.arp_eth_ipv4.arp_tpa = addr;
memcpy(arp_request.arp_data.arp_eth_ipv4.arp_sha, ethnic->mac, 6);
if (ethnic->ipv4_addr) {
arp_request.arp_data.arp_eth_ipv4.arp_spa = ethnic->ipv4_addr;
}
net_eth_send(ethnic, sizeof(struct arp_header), &arp_request, ETHERNET_TYPE_ARP, ETHERNET_BROADCAST_MAC);
}
void net_arp_handle(struct arp_header * packet, fs_node_t * nic) {
printf("net: arp: hardware %d protocol %d operation %d hlen %d plen %d\n",
ntohs(packet->arp_htype), ntohs(packet->arp_ptype), ntohs(packet->arp_oper),

View File

@ -283,6 +283,8 @@ static void init_tx(struct e1000_nic * device) {
read_command(device, E1000_REG_TCTRL));
}
extern void net_arp_ask(uint32_t addr, fs_node_t * fsnic);
static int ioctl_e1000(fs_node_t * node, unsigned long request, void * argp) {
struct e1000_nic * nic = node->device;
@ -312,6 +314,7 @@ static int ioctl_e1000(fs_node_t * node, unsigned long request, void * argp) {
return 0;
case SIOCSIFGATEWAY:
memcpy(&nic->eth.ipv4_gateway, argp, sizeof(nic->eth.ipv4_gateway));
net_arp_ask(nic->eth.ipv4_gateway, node);
return 0;
case SIOCGIFADDR6:

View File

@ -237,7 +237,13 @@ static int tcp_ack(fs_node_t * nic, sock_t * sock, struct ipv4_packet * packet,
tcp_header->checksum = htons(calculate_tcp_checksum(&check_hd, tcp_header, NULL, 0));
net_eth_send((struct EthernetDevice*)nic->device, ntohs(response->length), response, ETHERNET_TYPE_IPV4, ETHERNET_BROADCAST_MAC);
struct EthernetDevice * enic = nic->device;
uint32_t ipdest = response->destination;
if (ipdest & ~(enic->ipv4_subnet)) {
ipdest = enic->ipv4_gateway;
}
struct ArpCacheEntry * resp = net_arp_cache_get(ipdest);
net_eth_send((struct EthernetDevice*)nic->device, ntohs(response->length), response, ETHERNET_TYPE_IPV4, resp ? resp->hwaddr : ETHERNET_BROADCAST_MAC);
return retval;
}
@ -366,7 +372,13 @@ static long sock_udp_send(sock_t * sock, const struct msghdr *msg, int flags) {
memcpy(response->payload + sizeof(struct udp_packet), msg->msg_iov[0].iov_base, msg->msg_iov[0].iov_len);
net_eth_send((struct EthernetDevice*)nic->device, ntohs(response->length), response, ETHERNET_TYPE_IPV4, ETHERNET_BROADCAST_MAC);
struct EthernetDevice * enic = nic->device;
uint32_t ipdest = response->destination;
if (ipdest & ~(enic->ipv4_subnet)) {
ipdest = enic->ipv4_gateway;
}
struct ArpCacheEntry * resp = net_arp_cache_get(ipdest);
net_eth_send((struct EthernetDevice*)nic->device, ntohs(response->length), response, ETHERNET_TYPE_IPV4, resp ? resp->hwaddr : ETHERNET_BROADCAST_MAC);
free(response);
return 0;
@ -462,7 +474,12 @@ static void sock_tcp_close(sock_t * sock) {
tcp_header->checksum = htons(calculate_tcp_checksum(&check_hd, tcp_header, tcp_header->payload, 0));
struct ArpCacheEntry * resp = net_arp_cache_get(response->destination);
struct EthernetDevice * enic = nic->device;
uint32_t ipdest = response->destination;
if (ipdest & ~(enic->ipv4_subnet)) {
ipdest = enic->ipv4_gateway;
}
struct ArpCacheEntry * resp = net_arp_cache_get(ipdest);
net_eth_send((struct EthernetDevice*)nic->device, ntohs(response->length), response, ETHERNET_TYPE_IPV4, resp ? resp->hwaddr : ETHERNET_BROADCAST_MAC);
}
}
@ -596,8 +613,13 @@ static long sock_tcp_connect(sock_t * sock, const struct sockaddr *addr, socklen
tcp_header->checksum = htons(calculate_tcp_checksum(&check_hd, tcp_header, NULL, 0));
/* TODO: enqueue tcp packet for potential redelivery */
net_eth_send((struct EthernetDevice*)nic->device, ntohs(response->length), response, ETHERNET_TYPE_IPV4, ETHERNET_BROADCAST_MAC);
struct EthernetDevice * enic = nic->device;
uint32_t ipdest = response->destination;
if (ipdest & ~(enic->ipv4_subnet)) {
ipdest = enic->ipv4_gateway;
}
struct ArpCacheEntry * resp = net_arp_cache_get(ipdest);
net_eth_send((struct EthernetDevice*)nic->device, ntohs(response->length), response, ETHERNET_TYPE_IPV4, resp ? resp->hwaddr : ETHERNET_BROADCAST_MAC);
int _debug __attribute__((unused)) = 1;
@ -699,8 +721,13 @@ static long sock_tcp_send(sock_t * sock, const struct msghdr *msg, int flags) {
memcpy(tcp_header->payload, msg->msg_iov[0].iov_base, msg->msg_iov[0].iov_len);
tcp_header->checksum = htons(calculate_tcp_checksum(&check_hd, tcp_header, tcp_header->payload, msg->msg_iov[0].iov_len));
struct ArpCacheEntry * resp = net_arp_cache_get(response->destination);
net_eth_send((struct EthernetDevice*)nic->device, ntohs(response->length), response, ETHERNET_TYPE_IPV4, resp ? resp->hwaddr : ETHERNET_BROADCAST_MAC);
struct EthernetDevice * enic = nic->device;
uint32_t dest = response->destination;
if (dest & ~(enic->ipv4_subnet)) {
dest = enic->ipv4_gateway;
}
struct ArpCacheEntry * resp = net_arp_cache_get(dest);
net_eth_send(enic, ntohs(response->length), response, ETHERNET_TYPE_IPV4, resp ? resp->hwaddr : ETHERNET_BROADCAST_MAC);
return msg->msg_iov[0].iov_len;
}