2021-06-09 02:23:34 +03:00
|
|
|
#include <kernel/types.h>
|
|
|
|
#include <kernel/string.h>
|
|
|
|
#include <kernel/printf.h>
|
|
|
|
#include <kernel/process.h>
|
|
|
|
#include <kernel/pipe.h>
|
|
|
|
#include <kernel/list.h>
|
|
|
|
#include <kernel/spinlock.h>
|
|
|
|
#include <kernel/vfs.h>
|
|
|
|
#include <kernel/mod/net.h>
|
|
|
|
#include <kernel/net/netif.h>
|
|
|
|
#include <kernel/net/eth.h>
|
2021-06-14 15:35:28 +03:00
|
|
|
#include <kernel/net/ipv4.h>
|
2021-06-09 02:23:34 +03:00
|
|
|
#include <errno.h>
|
|
|
|
|
|
|
|
#include <sys/socket.h>
|
|
|
|
|
2021-06-15 13:29:57 +03:00
|
|
|
#ifndef MISAKA_DEBUG_NET
|
|
|
|
#define printf(...)
|
|
|
|
#endif
|
|
|
|
|
2021-06-09 02:23:34 +03:00
|
|
|
struct ethernet_packet {
|
|
|
|
uint8_t destination[6];
|
|
|
|
uint8_t source[6];
|
|
|
|
uint16_t type;
|
|
|
|
uint8_t payload[];
|
|
|
|
} __attribute__((packed)) __attribute__((aligned(2)));
|
|
|
|
|
|
|
|
extern spin_lock_t net_raw_sockets_lock;
|
|
|
|
extern list_t * net_raw_sockets_list;
|
2021-10-25 12:27:08 +03:00
|
|
|
extern void net_ipv4_handle(void * packet, fs_node_t * nic, size_t);
|
2021-06-09 13:41:35 +03:00
|
|
|
extern void net_arp_handle(void * packet, fs_node_t * nic);
|
2021-06-09 02:23:34 +03:00
|
|
|
|
2021-10-25 12:27:08 +03:00
|
|
|
void net_eth_handle(struct ethernet_packet * frame, fs_node_t * nic, size_t size) {
|
|
|
|
struct EthernetDevice * nic_eth = nic->device;
|
|
|
|
|
|
|
|
if (size < sizeof(struct ethernet_packet)) {
|
|
|
|
dprintf("eth: %s: invalid ethernet frame (too small)\n",
|
|
|
|
nic_eth->if_name);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-06-09 02:23:34 +03:00
|
|
|
spin_lock(net_raw_sockets_lock);
|
|
|
|
foreach(node, net_raw_sockets_list) {
|
|
|
|
sock_t * sock = node->value;
|
|
|
|
if (!sock->_fnode.device || sock->_fnode.device == nic) {
|
2021-10-25 12:27:08 +03:00
|
|
|
net_sock_add(sock, frame, size);
|
2021-06-09 02:23:34 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
spin_unlock(net_raw_sockets_lock);
|
|
|
|
|
2021-06-10 03:09:52 +03:00
|
|
|
if (!memcmp(frame->destination, nic_eth->mac, 6) || !memcmp(frame->destination, ETHERNET_BROADCAST_MAC, 6)) {
|
2021-06-09 02:23:34 +03:00
|
|
|
/* Now pass the frame to the appropriate handler... */
|
|
|
|
switch (ntohs(frame->type)) {
|
|
|
|
case ETHERNET_TYPE_ARP:
|
2021-06-09 13:41:35 +03:00
|
|
|
net_arp_handle(&frame->payload, nic);
|
2021-06-09 02:23:34 +03:00
|
|
|
break;
|
2021-06-14 15:35:28 +03:00
|
|
|
case ETHERNET_TYPE_IPV4: {
|
|
|
|
struct ipv4_packet * packet = (struct ipv4_packet*)&frame->payload;
|
2021-06-15 13:29:57 +03:00
|
|
|
printf("net: eth: %s: rx ipv4 packet\n", nic->name);
|
2021-06-14 15:35:28 +03:00
|
|
|
if (packet->source != 0xFFFFFFFF) {
|
|
|
|
net_arp_cache_add(nic->device, packet->source, frame->source, 0);
|
|
|
|
}
|
2021-10-25 12:27:08 +03:00
|
|
|
net_ipv4_handle(packet, nic, size - sizeof(struct ethernet_packet));
|
2021-06-09 02:23:34 +03:00
|
|
|
break;
|
2021-06-14 15:35:28 +03:00
|
|
|
}
|
2021-06-09 02:23:34 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-06-10 03:09:52 +03:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|