net: try to actually track received packet sizes...
This commit is contained in:
parent
073e43384c
commit
49342b7996
@ -10,7 +10,7 @@
|
|||||||
#define MAC_FORMAT "%02x:%02x:%02x:%02x:%02x:%02x"
|
#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]
|
#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, size_t size);
|
||||||
|
|
||||||
struct EthernetDevice {
|
struct EthernetDevice {
|
||||||
char if_name[32];
|
char if_name[32];
|
||||||
|
@ -27,21 +27,27 @@ struct ethernet_packet {
|
|||||||
|
|
||||||
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_ipv4_handle(void * packet, fs_node_t * nic);
|
extern void net_ipv4_handle(void * packet, fs_node_t * nic, size_t);
|
||||||
extern void net_arp_handle(void * packet, fs_node_t * nic);
|
extern void net_arp_handle(void * packet, fs_node_t * nic);
|
||||||
|
|
||||||
void net_eth_handle(struct ethernet_packet * frame, fs_node_t * nic) {
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
spin_lock(net_raw_sockets_lock);
|
spin_lock(net_raw_sockets_lock);
|
||||||
foreach(node, net_raw_sockets_list) {
|
foreach(node, net_raw_sockets_list) {
|
||||||
sock_t * sock = node->value;
|
sock_t * sock = node->value;
|
||||||
if (!sock->_fnode.device || sock->_fnode.device == nic) {
|
if (!sock->_fnode.device || sock->_fnode.device == nic) {
|
||||||
net_sock_add(sock, frame, 4096);
|
net_sock_add(sock, frame, size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
spin_unlock(net_raw_sockets_lock);
|
spin_unlock(net_raw_sockets_lock);
|
||||||
|
|
||||||
struct EthernetDevice * nic_eth = nic->device;
|
|
||||||
|
|
||||||
if (!memcmp(frame->destination, nic_eth->mac, 6) || !memcmp(frame->destination, ETHERNET_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)) {
|
||||||
@ -54,7 +60,7 @@ void net_eth_handle(struct ethernet_packet * frame, fs_node_t * nic) {
|
|||||||
if (packet->source != 0xFFFFFFFF) {
|
if (packet->source != 0xFFFFFFFF) {
|
||||||
net_arp_cache_add(nic->device, packet->source, frame->source, 0);
|
net_arp_cache_add(nic->device, packet->source, frame->source, 0);
|
||||||
}
|
}
|
||||||
net_ipv4_handle(packet, nic);
|
net_ipv4_handle(packet, nic, size - sizeof(struct ethernet_packet));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include <kernel/vfs.h>
|
#include <kernel/vfs.h>
|
||||||
#include <kernel/time.h>
|
#include <kernel/time.h>
|
||||||
#include <kernel/misc.h>
|
#include <kernel/misc.h>
|
||||||
|
#include <kernel/assert.h>
|
||||||
|
|
||||||
#include <kernel/net/netif.h>
|
#include <kernel/net/netif.h>
|
||||||
#include <kernel/net/eth.h>
|
#include <kernel/net/eth.h>
|
||||||
@ -158,7 +159,9 @@ static void icmp_handle(struct ipv4_packet * packet, const char * src, const cha
|
|||||||
/* Is this a PING request? */
|
/* Is this a PING request? */
|
||||||
if (header->type == 8 && header->code == 0) {
|
if (header->type == 8 && header->code == 0) {
|
||||||
printf("net: ping with %d bytes of payload\n", ntohs(packet->length));
|
printf("net: ping with %d bytes of payload\n", ntohs(packet->length));
|
||||||
if (ntohs(packet->length) & 1) packet->length++;
|
if (ntohs(packet->length) & 1) {
|
||||||
|
packet->length = htons(ntohs(packet->length) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
struct ipv4_packet * response = malloc(ntohs(packet->length));
|
struct ipv4_packet * response = malloc(ntohs(packet->length));
|
||||||
memcpy(response, packet, ntohs(packet->length));
|
memcpy(response, packet, ntohs(packet->length));
|
||||||
@ -203,15 +206,19 @@ static long sock_icmp_recv(sock_t * sock, struct msghdr * msg, int flags) {
|
|||||||
}
|
}
|
||||||
if (msg->msg_iovlen == 0) return 0;
|
if (msg->msg_iovlen == 0) return 0;
|
||||||
|
|
||||||
struct ipv4_packet * data = net_sock_get(sock);
|
char * packet = net_sock_get(sock);
|
||||||
if (!data) {
|
if (!packet) return -EINTR;
|
||||||
return -EINTR;
|
size_t packet_size = *(size_t*)packet;
|
||||||
|
struct ipv4_packet * data = (struct ipv4_packet*)(packet + sizeof(size_t));
|
||||||
|
|
||||||
|
if (packet_size > msg->msg_iov[0].iov_len) {
|
||||||
|
dprintf("ICMP recv too big for vector\n");
|
||||||
|
packet_size = msg->msg_iov[0].iov_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
long resp = ntohs(data->length);
|
memcpy(msg->msg_iov[0].iov_base, data, packet_size);
|
||||||
memcpy(msg->msg_iov[0].iov_base, data, resp);
|
free(packet);
|
||||||
free(data);
|
return packet_size;
|
||||||
return resp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static long sock_icmp_send(sock_t * sock, const struct msghdr *msg, int flags) {
|
static long sock_icmp_send(sock_t * sock, const struct msghdr *msg, int flags) {
|
||||||
@ -372,7 +379,11 @@ static int tcp_ack(fs_node_t * nic, sock_t * sock, struct ipv4_packet * packet,
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
void net_ipv4_handle(struct ipv4_packet * packet, fs_node_t * nic) {
|
void net_ipv4_handle(struct ipv4_packet * packet, fs_node_t * nic, size_t size) {
|
||||||
|
|
||||||
|
if (size < sizeof(struct ipv4_packet)) {
|
||||||
|
dprintf("ipv4: Incoming packet is too small.\n");
|
||||||
|
}
|
||||||
|
|
||||||
char dest[16];
|
char dest[16];
|
||||||
char src[16];
|
char src[16];
|
||||||
@ -514,12 +525,9 @@ static long sock_udp_recv(sock_t * sock, struct msghdr * msg, int flags) {
|
|||||||
}
|
}
|
||||||
if (msg->msg_iovlen == 0) return 0;
|
if (msg->msg_iovlen == 0) return 0;
|
||||||
|
|
||||||
struct ipv4_packet * data = net_sock_get(sock);
|
char * packet = net_sock_get(sock);
|
||||||
|
if (!packet) return -EINTR;
|
||||||
if (!data) {
|
struct ipv4_packet * data = (struct ipv4_packet*)(packet + sizeof(size_t));
|
||||||
/* We need to figure out why, but that's... complicated for now. */
|
|
||||||
return -EINTR;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("udp: got response, size is %u - sizeof(ipv4) - sizeof(udp) = %lu\n",
|
printf("udp: got response, size is %u - sizeof(ipv4) - sizeof(udp) = %lu\n",
|
||||||
ntohs(data->length), ntohs(data->length) - sizeof(struct ipv4_packet) - sizeof(struct udp_packet));
|
ntohs(data->length), ntohs(data->length) - sizeof(struct ipv4_packet) - sizeof(struct udp_packet));
|
||||||
@ -528,7 +536,7 @@ static long sock_udp_recv(sock_t * sock, struct msghdr * msg, int flags) {
|
|||||||
printf("udp: data copied to iov 0, return length?\n");
|
printf("udp: data copied to iov 0, return length?\n");
|
||||||
|
|
||||||
long resp = ntohs(data->length) - sizeof(struct ipv4_packet) - sizeof(struct udp_packet);
|
long resp = ntohs(data->length) - sizeof(struct ipv4_packet) - sizeof(struct udp_packet);
|
||||||
free(data);
|
free(packet);
|
||||||
return resp;
|
return resp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -674,11 +682,23 @@ static long sock_tcp_recv(sock_t * sock, struct msghdr * msg, int flags) {
|
|||||||
process_wait_nodes((process_t *)this_core->current_process, (fs_node_t*[]){(fs_node_t*)sock,NULL}, 200);
|
process_wait_nodes((process_t *)this_core->current_process, (fs_node_t*[]){(fs_node_t*)sock,NULL}, 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ipv4_packet * data = net_sock_get(sock);
|
char * packet = net_sock_get(sock);
|
||||||
if (!data) {
|
if (!packet) return -EINTR;
|
||||||
return -EINTR;
|
struct ipv4_packet * data = (struct ipv4_packet*)(packet + sizeof(size_t));
|
||||||
|
size_t packet_size = *(size_t*)packet;
|
||||||
|
unsigned long resp = ntohs(data->length);
|
||||||
|
|
||||||
|
if (resp != packet_size) {
|
||||||
|
dprintf("packet size does not match: %zu %zu\n", resp, packet_size);
|
||||||
|
resp = packet_size;
|
||||||
}
|
}
|
||||||
unsigned long resp = ntohs(data->length) - sizeof(struct ipv4_packet) - sizeof(struct tcp_header);
|
|
||||||
|
if (resp < sizeof(struct ipv4_packet) + sizeof(struct tcp_header)) {
|
||||||
|
dprintf("Invalid receive data?\n");
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
resp -= sizeof(struct ipv4_packet) + sizeof(struct tcp_header);
|
||||||
|
|
||||||
if (resp > (unsigned long)msg->msg_iov[0].iov_len) {
|
if (resp > (unsigned long)msg->msg_iov[0].iov_len) {
|
||||||
memcpy(msg->msg_iov[0].iov_base, data->payload + sizeof(struct tcp_header),msg->msg_iov[0].iov_len);
|
memcpy(msg->msg_iov[0].iov_base, data->payload + sizeof(struct tcp_header),msg->msg_iov[0].iov_len);
|
||||||
@ -687,12 +707,12 @@ static long sock_tcp_recv(sock_t * sock, struct msghdr * msg, int flags) {
|
|||||||
sock->unread = resp;
|
sock->unread = resp;
|
||||||
sock->buf = malloc(resp);
|
sock->buf = malloc(resp);
|
||||||
memcpy(sock->buf, data->payload + sizeof(struct tcp_header) + msg->msg_iov[0].iov_len, resp);
|
memcpy(sock->buf, data->payload + sizeof(struct tcp_header) + msg->msg_iov[0].iov_len, resp);
|
||||||
free(data);
|
free(packet);
|
||||||
return msg->msg_iov[0].iov_len;
|
return msg->msg_iov[0].iov_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(msg->msg_iov[0].iov_base, data->payload + sizeof(struct tcp_header), resp);
|
memcpy(msg->msg_iov[0].iov_base, data->payload + sizeof(struct tcp_header), resp);
|
||||||
free(data);
|
free(packet);
|
||||||
return resp;
|
return resp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -793,12 +813,11 @@ static long sock_tcp_connect(sock_t * sock, const struct sockaddr *addr, socklen
|
|||||||
printf("tcp: queue should have data now (len = %lu), trying to read\n", sock->rx_queue->length);
|
printf("tcp: queue should have data now (len = %lu), trying to read\n", sock->rx_queue->length);
|
||||||
|
|
||||||
/* wait for signal that we connected or timed out */
|
/* wait for signal that we connected or timed out */
|
||||||
struct ipv4_packet * data = net_sock_get(sock);
|
char * packet = net_sock_get(sock);
|
||||||
if (!data) {
|
if (!packet) return -EINTR;
|
||||||
return -EINTR;
|
//struct ipv4_packet * data = packet + sizeof(size_t);
|
||||||
}
|
|
||||||
printf("tcp: connect complete\n");
|
printf("tcp: connect complete\n");
|
||||||
free(data);
|
free(packet);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -92,7 +92,7 @@ static ssize_t write_loop(fs_node_t *node, off_t offset, size_t size, uint8_t *b
|
|||||||
nic->counts.rx_bytes += size;
|
nic->counts.rx_bytes += size;
|
||||||
nic->counts.tx_bytes += size;
|
nic->counts.tx_bytes += size;
|
||||||
|
|
||||||
net_eth_handle((void*)buffer, node);
|
net_eth_handle((void*)buffer, node, size);
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,8 +46,9 @@ void net_sock_alert(sock_t * sock) {
|
|||||||
|
|
||||||
void net_sock_add(sock_t * sock, void * frame, size_t size) {
|
void net_sock_add(sock_t * sock, void * frame, size_t size) {
|
||||||
spin_lock(sock->rx_lock);
|
spin_lock(sock->rx_lock);
|
||||||
char * bleh = malloc(size);
|
char * bleh = malloc(size + sizeof(size_t));
|
||||||
memcpy(bleh, frame, size);
|
*(size_t*)bleh = size;
|
||||||
|
memcpy(bleh + sizeof(size_t), frame, size);
|
||||||
list_insert(sock->rx_queue, bleh);
|
list_insert(sock->rx_queue, bleh);
|
||||||
wakeup_queue(sock->rx_wait);
|
wakeup_queue(sock->rx_wait);
|
||||||
net_sock_alert(sock);
|
net_sock_alert(sock);
|
||||||
@ -126,10 +127,11 @@ static long sock_raw_recv(sock_t * sock, struct msghdr * msg, int flags) {
|
|||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
}
|
}
|
||||||
if (msg->msg_iovlen == 0) return 0;
|
if (msg->msg_iovlen == 0) return 0;
|
||||||
if (msg->msg_iov[0].iov_len != 4096) return -EINVAL;
|
char * data = net_sock_get(sock);
|
||||||
void * data = net_sock_get(sock);
|
|
||||||
if (!data) return -EINTR;
|
if (!data) return -EINTR;
|
||||||
memcpy(msg->msg_iov[0].iov_base, data, 4096);
|
size_t packet_size = *(size_t*)data;
|
||||||
|
if (msg->msg_iov[0].iov_len < packet_size) return -EINVAL;
|
||||||
|
memcpy(msg->msg_iov[0].iov_base, data + sizeof(size_t), packet_size);
|
||||||
free(data);
|
free(data);
|
||||||
return 4096;
|
return 4096;
|
||||||
}
|
}
|
||||||
|
@ -175,7 +175,7 @@ static void e1000_queuer(void * data) {
|
|||||||
if (!(nic->rx[i].errors & (0x97))) {
|
if (!(nic->rx[i].errors & (0x97))) {
|
||||||
nic->counts.rx_count++;
|
nic->counts.rx_count++;
|
||||||
nic->counts.rx_bytes += nic->rx[i].length;
|
nic->counts.rx_bytes += nic->rx[i].length;
|
||||||
net_eth_handle((void*)nic->rx_virt[i], nic->eth.device_node);
|
net_eth_handle((void*)nic->rx_virt[i], nic->eth.device_node, nic->rx[i].length);
|
||||||
} else {
|
} else {
|
||||||
printf("error bits set in packet: %x\n", nic->rx[i].errors);
|
printf("error bits set in packet: %x\n", nic->rx[i].errors);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user