net: respond to pings?
This commit is contained in:
parent
394e4e3e0c
commit
f1efda9e2a
|
@ -294,7 +294,7 @@ static int configure_interface(const char * if_name) {
|
|||
|
||||
gettimeofday(&end, NULL);
|
||||
time_diff(&start,&end,&sec_diff,&usec_diff);
|
||||
if (sec_diff > 0 || usec_diff > 500000) {
|
||||
if (sec_diff > 2) {
|
||||
close(netdev);
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -8,11 +8,13 @@
|
|||
*/
|
||||
#include <errno.h>
|
||||
#include <kernel/types.h>
|
||||
#include <kernel/string.h>
|
||||
#include <kernel/printf.h>
|
||||
#include <kernel/syscall.h>
|
||||
#include <kernel/vfs.h>
|
||||
|
||||
#include <kernel/net/netif.h>
|
||||
#include <kernel/net/eth.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
|
||||
|
@ -30,6 +32,14 @@ struct ipv4_packet {
|
|||
uint8_t payload[];
|
||||
} __attribute__ ((packed)) __attribute__((aligned(2)));
|
||||
|
||||
struct icmp_header {
|
||||
uint8_t type;
|
||||
uint8_t code;
|
||||
uint16_t csum;
|
||||
uint16_t rest_of_header;
|
||||
uint8_t data[];
|
||||
} __attribute__((packed)) __attribute__((aligned(2)));
|
||||
|
||||
#define IPV4_PROT_UDP 17
|
||||
#define IPV4_PROT_TCP 6
|
||||
|
||||
|
@ -41,6 +51,67 @@ static void ip_ntoa(const uint32_t src_addr, char * out) {
|
|||
(src_addr & 0xFF));
|
||||
}
|
||||
|
||||
static uint16_t icmp_checksum(struct ipv4_packet * packet) {
|
||||
uint32_t sum = 0;
|
||||
uint16_t * s = (uint16_t *)packet->payload;
|
||||
for (int i = 0; i < (ntohs(packet->length) - 20) / 2; ++i) {
|
||||
sum += ntohs(s[i]);
|
||||
}
|
||||
if (sum > 0xFFFF) {
|
||||
sum = (sum >> 16) + (sum & 0xFFFF);
|
||||
}
|
||||
return ~(sum & 0xFFFF) & 0xFFFF;
|
||||
}
|
||||
|
||||
uint16_t calculate_ipv4_checksum(struct ipv4_packet * p) {
|
||||
uint32_t sum = 0;
|
||||
uint16_t * s = (uint16_t *)p;
|
||||
|
||||
/* TODO: Checksums for options? */
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
sum += ntohs(s[i]);
|
||||
}
|
||||
|
||||
if (sum > 0xFFFF) {
|
||||
sum = (sum >> 16) + (sum & 0xFFFF);
|
||||
}
|
||||
|
||||
return ~(sum & 0xFFFF) & 0xFFFF;
|
||||
}
|
||||
|
||||
static void icmp_handle(struct ipv4_packet * packet, const char * src, const char * dest, fs_node_t * nic) {
|
||||
struct icmp_header * header = (void*)&packet->payload;
|
||||
if (header->type == 8 && header->code == 0) {
|
||||
printf("net: ping with %d bytes of payload\n", ntohs(packet->length));
|
||||
if (ntohs(packet->length) & 1) packet->length++;
|
||||
|
||||
struct ipv4_packet * response = malloc(ntohs(packet->length));
|
||||
response->length = packet->length;
|
||||
response->destination = packet->source;
|
||||
response->source = ((struct EthernetDevice*)nic->device)->ipv4_addr;
|
||||
response->ttl = 64;
|
||||
response->protocol = 1;
|
||||
response->ident = packet->ident;
|
||||
response->flags_fragment = htons(0x4000);
|
||||
response->version_ihl = 0x45;
|
||||
response->dscp_ecn = 0;
|
||||
response->checksum = 0;
|
||||
response->checksum = htons(calculate_ipv4_checksum(response));
|
||||
memcpy(response->payload, packet->payload, ntohs(packet->length));
|
||||
|
||||
struct icmp_header * ping_reply = (void*)&response->payload;
|
||||
ping_reply->csum = 0;
|
||||
ping_reply->type = 0;
|
||||
ping_reply->csum = htons(icmp_checksum(response));
|
||||
|
||||
/* send ipv4... */
|
||||
net_eth_send((struct EthernetDevice*)nic->device, ntohs(response->length), response, ETHERNET_TYPE_IPV4, ETHERNET_BROADCAST_MAC);
|
||||
free(response);
|
||||
} else {
|
||||
printf("net: ipv4: %s: %s -> %s ICMP %d (code = %d)\n", nic->name, src, dest, header->type, header->code);
|
||||
}
|
||||
}
|
||||
|
||||
void net_ipv4_handle(struct ipv4_packet * packet, fs_node_t * nic) {
|
||||
|
||||
char dest[16];
|
||||
|
@ -51,7 +122,7 @@ void net_ipv4_handle(struct ipv4_packet * packet, fs_node_t * nic) {
|
|||
|
||||
switch (packet->protocol) {
|
||||
case 1:
|
||||
printf("net: ipv4: %s: %s -> %s ICMP\n", nic->name, src, dest);
|
||||
icmp_handle(packet, src, dest, nic);
|
||||
break;
|
||||
case IPV4_PROT_UDP:
|
||||
printf("net: ipv4: %s: %s -> %s udp %d to %d\n", nic->name, src, dest, ntohs(((uint16_t*)&packet->payload)[0]), ntohs(((uint16_t*)&packet->payload)[1]));
|
||||
|
|
Loading…
Reference in New Issue