diff options
author | Marvin Borner | 2020-11-03 21:09:34 +0100 |
---|---|---|
committer | Marvin Borner | 2020-11-03 21:09:34 +0100 |
commit | 5951024ab35e6cdd1ed6b97d76e28f1a253f6593 (patch) | |
tree | 52670f12af4a1274f9ce6e8a642ad055658255ed /kernel | |
parent | 36bd8f09d359d176a2a1ca59864838269e887c4b (diff) |
Started TCP implementation
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/features/net.c | 64 | ||||
-rw-r--r-- | kernel/inc/net.h | 31 |
2 files changed, 91 insertions, 4 deletions
diff --git a/kernel/features/net.c b/kernel/features/net.c index 01cbb47..2b4fbb5 100644 --- a/kernel/features/net.c +++ b/kernel/features/net.c @@ -19,7 +19,7 @@ static u8 gateway_mac[6] = { 0 }; u16 ip_calculate_checksum(struct ip_packet *packet) { - int array_size = sizeof(struct ip_packet) / 2; + int array_size = sizeof(*packet) / 2; u16 *array = (u16 *)packet; u32 sum = 0; for (int i = 0; i < array_size; i++) { @@ -32,6 +32,55 @@ u16 ip_calculate_checksum(struct ip_packet *packet) return ret; } +u16 tcp_calculate_checksum(struct tcp_packet *packet, struct tcp_pseudo_header *header, void *data, + u32 len) +{ + u32 sum = 0; + u16 *s = (u16 *)header; + + // TODO: Checksums for options? + for (int i = 0; i < 6; ++i) { + sum += ntohs(s[i]); + if (sum > 0xffff) { + sum = (sum >> 16) + (sum & 0xffff); + } + } + + s = (u16 *)packet; + for (int i = 0; i < 10; ++i) { + sum += ntohs(s[i]); + if (sum > 0xffff) { + sum = (sum >> 16) + (sum & 0xffff); + } + } + + u16 d_words = len / 2; + + s = (u16 *)data; + for (unsigned int i = 0; i < d_words; ++i) { + sum += ntohs(s[i]); + if (sum > 0xffff) { + sum = (sum >> 16) + (sum & 0xffff); + } + } + + if (d_words * 2 != len) { + u8 *t = (u8 *)data; + u8 tmp[2]; + tmp[0] = t[d_words * sizeof(u16)]; + tmp[1] = 0; + + u16 *f = (u16 *)tmp; + + sum += ntohs(f[0]); + if (sum > 0xffff) { + sum = (sum >> 16) + (sum & 0xffff); + } + } + + return ~(sum & 0xffff) & 0xffff; +} + u16 icmp_calculate_checksum(struct icmp_packet *packet) { u32 sum = 0; @@ -40,8 +89,8 @@ u16 icmp_calculate_checksum(struct icmp_packet *packet) for (int i = 0; i < 5; i++) sum += s[i]; - if (sum > 0xFFFF) - sum = (sum >> 16) + (sum & 0xFFFF); + if (sum > 0xffff) + sum = (sum >> 16) + (sum & 0xffff); return ~sum; } @@ -197,6 +246,13 @@ void dhcp_handle_packet(struct dhcp_packet *packet) } } +void tcp_handle_packet(struct tcp_packet *packet) +{ + printf("TCP Port: %d\n", ntohs(packet->dst_port)); + u16 flags = ntohs(packet->flags); + printf("%b\n", flags); +} + void udp_handle_packet(struct udp_packet *packet) { printf("UDP Port: %d\n", ntohs(packet->dst_port)); @@ -204,7 +260,6 @@ void udp_handle_packet(struct udp_packet *packet) if (ntohs(packet->dst_port) == 68) dhcp_handle_packet(data_ptr); - return; } void ip_handle_packet(struct ip_packet *packet, int len) @@ -217,6 +272,7 @@ void ip_handle_packet(struct ip_packet *packet, int len) break; case IP_PROT_TCP: print("TCP Packet!\n"); + tcp_handle_packet((struct tcp_packet *)packet->data); break; case IP_PROT_UDP: print("UDP Packet!\n"); diff --git a/kernel/inc/net.h b/kernel/inc/net.h index 78aed51..f2fbb20 100644 --- a/kernel/inc/net.h +++ b/kernel/inc/net.h @@ -20,6 +20,16 @@ #define IP_PROT_TCP 0x06 #define IP_PROT_UDP 0x11 +#define TCP_FLAG_FIN (1 << 0) +#define TCP_FLAG_SYN (1 << 1) +#define TCP_FLAG_RES (1 << 2) +#define TCP_FLAG_PSH (1 << 3) +#define TCP_FLAG_ACK (1 << 4) +#define TCP_FLAG_URG (1 << 5) +#define TCP_FLAG_ECE (1 << 6) +#define TCP_FLAG_CWR (1 << 7) +#define TCP_FLAG_NS (1 << 8) + #define ARP_REQUEST 1 #define ARP_REPLY 2 @@ -91,6 +101,27 @@ struct udp_packet { u8 data[]; } __attribute__((packed)); +struct tcp_packet { + u16 src_port; + u16 dst_port; + u32 seq_number; + u32 ack_number; + u16 flags; + u16 window_size; + u16 checksum; + u16 urgent; + u8 data[]; +} __attribute__((packed)); + +struct tcp_pseudo_header { + u32 source; + u32 destination; + u8 zeros; + u8 protocol; + u16 tcp_len; + u8 tcp_header[]; +}; + struct icmp_packet { u8 type; u8 version; |