net: arp fixups
This commit is contained in:
parent
341c5ec7aa
commit
72968ed85c
@ -3,6 +3,13 @@
|
|||||||
#include <kernel/vfs.h>
|
#include <kernel/vfs.h>
|
||||||
#include <kernel/mod/net.h>
|
#include <kernel/mod/net.h>
|
||||||
|
|
||||||
|
#define ETHERNET_TYPE_IPV4 0x0800
|
||||||
|
#define ETHERNET_TYPE_ARP 0x0806
|
||||||
|
#define ETHERNET_BROADCAST_MAC (uint8_t[]){0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
|
||||||
|
|
||||||
|
#define MAC_FORMAT "%02x:%02x:%02x:%02x:%02x:%02x"
|
||||||
|
#define FORMAT_MAC(m) (m)[0], (m)[1], (m)[2], (m)[3], (m)[4], (m)[5]
|
||||||
|
|
||||||
void net_eth_handle(struct ethernet_packet * frame, fs_node_t * nic);
|
void net_eth_handle(struct ethernet_packet * frame, fs_node_t * nic);
|
||||||
|
|
||||||
struct EthernetDevice {
|
struct EthernetDevice {
|
||||||
@ -20,3 +27,5 @@ struct EthernetDevice {
|
|||||||
|
|
||||||
fs_node_t * device_node;
|
fs_node_t * device_node;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void net_eth_send(struct EthernetDevice *, size_t, void*, uint16_t, uint8_t*);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <kernel/types.h>
|
#include <kernel/types.h>
|
||||||
|
#include <kernel/string.h>
|
||||||
#include <kernel/printf.h>
|
#include <kernel/printf.h>
|
||||||
#include <kernel/syscall.h>
|
#include <kernel/syscall.h>
|
||||||
#include <kernel/vfs.h>
|
#include <kernel/vfs.h>
|
||||||
@ -19,7 +20,7 @@ struct arp_header {
|
|||||||
struct {
|
struct {
|
||||||
uint8_t arp_sha[6];
|
uint8_t arp_sha[6];
|
||||||
uint32_t arp_spa;
|
uint32_t arp_spa;
|
||||||
uint16_t arp_tha[6];
|
uint8_t arp_tha[6];
|
||||||
uint32_t arp_tpa;
|
uint32_t arp_tpa;
|
||||||
} __attribute__((packed)) arp_eth_ipv4;
|
} __attribute__((packed)) arp_eth_ipv4;
|
||||||
} arp_data;
|
} arp_data;
|
||||||
@ -33,14 +34,13 @@ static void ip_ntoa(const uint32_t src_addr, char * out) {
|
|||||||
(src_addr & 0xFF));
|
(src_addr & 0xFF));
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAC_FORMAT "%02x:%02x:%02x:%02x:%02x:%02x"
|
|
||||||
#define FORMAT_MAC(m) (m)[0], (m)[1], (m)[2], (m)[3], (m)[4], (m)[5]
|
|
||||||
|
|
||||||
void net_arp_handle(struct arp_header * packet, fs_node_t * nic) {
|
void net_arp_handle(struct arp_header * packet, fs_node_t * nic) {
|
||||||
printf("net: arp: hardware %d protocol %d operation %d\n",
|
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));
|
ntohs(packet->arp_htype), ntohs(packet->arp_ptype), ntohs(packet->arp_oper),
|
||||||
|
packet->arp_hlen, packet->arp_plen);
|
||||||
|
struct EthernetDevice * eth_dev = nic->device;
|
||||||
|
|
||||||
if (ntohs(packet->arp_htype) == 1 && ntohs(packet->arp_ptype) == 0x0800) {
|
if (ntohs(packet->arp_htype) == 1 && ntohs(packet->arp_ptype) == ETHERNET_TYPE_IPV4) {
|
||||||
/* Ethernet, IPv4 */
|
/* Ethernet, IPv4 */
|
||||||
if (ntohs(packet->arp_oper) == 1) {
|
if (ntohs(packet->arp_oper) == 1) {
|
||||||
char spa[17];
|
char spa[17];
|
||||||
@ -50,6 +50,21 @@ void net_arp_handle(struct arp_header * packet, fs_node_t * nic) {
|
|||||||
printf("net: arp: " MAC_FORMAT " (%s) wants to know who %s is\n",
|
printf("net: arp: " MAC_FORMAT " (%s) wants to know who %s is\n",
|
||||||
FORMAT_MAC(packet->arp_data.arp_eth_ipv4.arp_sha),
|
FORMAT_MAC(packet->arp_data.arp_eth_ipv4.arp_sha),
|
||||||
spa, tpa);
|
spa, tpa);
|
||||||
|
if (eth_dev->ipv4_addr && packet->arp_data.arp_eth_ipv4.arp_tpa == eth_dev->ipv4_addr) {
|
||||||
|
printf("net: arp: that's us, we should reply...\n");
|
||||||
|
|
||||||
|
struct arp_header response = {0};
|
||||||
|
response.arp_htype = htons(1);
|
||||||
|
response.arp_ptype = htons(ETHERNET_TYPE_IPV4);
|
||||||
|
response.arp_hlen = 6;
|
||||||
|
response.arp_plen = 4;
|
||||||
|
response.arp_oper = htons(2);
|
||||||
|
memcpy(response.arp_data.arp_eth_ipv4.arp_sha, eth_dev->mac, 6);
|
||||||
|
memcpy(response.arp_data.arp_eth_ipv4.arp_tha, packet->arp_data.arp_eth_ipv4.arp_sha, 6);
|
||||||
|
response.arp_data.arp_eth_ipv4.arp_spa = eth_dev->ipv4_addr;
|
||||||
|
response.arp_data.arp_eth_ipv4.arp_tpa = packet->arp_data.arp_eth_ipv4.arp_spa;
|
||||||
|
net_eth_send(eth_dev, sizeof(struct arp_header), &response, ETHERNET_TYPE_ARP, packet->arp_data.arp_eth_ipv4.arp_sha);
|
||||||
|
}
|
||||||
} else if (ntohs(packet->arp_oper) == 2) {
|
} else if (ntohs(packet->arp_oper) == 2) {
|
||||||
char spa[17];
|
char spa[17];
|
||||||
ip_ntoa(ntohl(packet->arp_data.arp_eth_ipv4.arp_spa), spa);
|
ip_ntoa(ntohl(packet->arp_data.arp_eth_ipv4.arp_spa), spa);
|
||||||
|
@ -20,10 +20,6 @@ struct ethernet_packet {
|
|||||||
uint8_t payload[];
|
uint8_t payload[];
|
||||||
} __attribute__((packed)) __attribute__((aligned(2)));
|
} __attribute__((packed)) __attribute__((aligned(2)));
|
||||||
|
|
||||||
#define ETHERNET_TYPE_IPV4 0x0800
|
|
||||||
#define ETHERNET_TYPE_ARP 0x0806
|
|
||||||
#define BROADCAST_MAC {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
|
|
||||||
|
|
||||||
extern spin_lock_t net_raw_sockets_lock;
|
extern spin_lock_t net_raw_sockets_lock;
|
||||||
extern list_t * net_raw_sockets_list;
|
extern list_t * net_raw_sockets_list;
|
||||||
extern void net_sock_add(sock_t * sock, void * frame);
|
extern void net_sock_add(sock_t * sock, void * frame);
|
||||||
@ -42,7 +38,7 @@ void net_eth_handle(struct ethernet_packet * frame, fs_node_t * nic) {
|
|||||||
|
|
||||||
struct EthernetDevice * nic_eth = nic->device;
|
struct EthernetDevice * nic_eth = nic->device;
|
||||||
|
|
||||||
if (!memcmp(frame->destination, nic_eth->mac, 6) || !memcmp(frame->destination, (uint8_t[])BROADCAST_MAC, 6)) {
|
if (!memcmp(frame->destination, nic_eth->mac, 6) || !memcmp(frame->destination, ETHERNET_BROADCAST_MAC, 6)) {
|
||||||
/* Now pass the frame to the appropriate handler... */
|
/* Now pass the frame to the appropriate handler... */
|
||||||
switch (ntohs(frame->type)) {
|
switch (ntohs(frame->type)) {
|
||||||
case ETHERNET_TYPE_ARP:
|
case ETHERNET_TYPE_ARP:
|
||||||
@ -57,3 +53,14 @@ void net_eth_handle(struct ethernet_packet * frame, fs_node_t * nic) {
|
|||||||
|
|
||||||
free(frame);
|
free(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void net_eth_send(struct EthernetDevice * nic, size_t len, void* data, uint16_t type, uint8_t * dest) {
|
||||||
|
size_t total_size = sizeof(struct ethernet_packet) + len;
|
||||||
|
struct ethernet_packet * packet = malloc(total_size);
|
||||||
|
memcpy(packet->payload, data, len);
|
||||||
|
memcpy(packet->destination, dest, 6);
|
||||||
|
memcpy(packet->source, nic->mac, 6);
|
||||||
|
packet->type = htons(type);
|
||||||
|
write_fs(nic->device_node, 0, total_size, (uint8_t*)packet);
|
||||||
|
free(packet);
|
||||||
|
}
|
||||||
|
@ -33,6 +33,9 @@ struct ipv4_packet {
|
|||||||
|
|
||||||
void net_ipv4_handle(struct ipv4_packet * packet, fs_node_t * nic) {
|
void net_ipv4_handle(struct ipv4_packet * packet, fs_node_t * nic) {
|
||||||
switch (packet->protocol) {
|
switch (packet->protocol) {
|
||||||
|
case 1:
|
||||||
|
printf("net: ipv4: %s: ICMP\n", nic->name);
|
||||||
|
break;
|
||||||
case IPV4_PROT_UDP:
|
case IPV4_PROT_UDP:
|
||||||
printf("net: ipv4: %s: udp packet\n", nic->name);
|
printf("net: ipv4: %s: udp packet\n", nic->name);
|
||||||
break;
|
break;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user