toaruos/modules/net.c

118 lines
2.3 KiB
C

/* vim: tabstop=4 shiftwidth=4 noexpandtab
* This file is part of ToaruOS and is released under the terms
* of the NCSA / University of Illinois License - see LICENSE.md
* Copyright (C) 2014 Kevin Lange
*/
#include <module.h>
#include <ipv4.h>
#include <printf.h>
uint32_t ip_aton(const char * in) {
char ip[16];
char * c = ip;
int out[4];
char * i;
memcpy(ip, in, strlen(in) < 15 ? strlen(in) + 1 : 15);
ip[15] = '\0';
i = (char *)lfind(c, '.');
*i = '\0';
out[0] = atoi(c);
c += strlen(c) + 1;
i = (char *)lfind(c, '.');
*i = '\0';
out[1] = atoi(c);
c += strlen(c) + 1;
i = (char *)lfind(c, '.');
*i = '\0';
out[2] = atoi(c);
c += strlen(c) + 1;
out[3] = atoi(c);
return ((out[0] << 24) | (out[1] << 16) | (out[2] << 8) | (out[3]));
}
void ip_ntoa(uint32_t src_addr, char * out) {
sprintf(out, "%d.%d.%d.%d",
(src_addr & 0xFF000000) >> 24,
(src_addr & 0xFF0000) >> 16,
(src_addr & 0xFF00) >> 8,
(src_addr & 0xFF));
}
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;
}
uint16_t calculate_tcp_checksum(struct tcp_check_header * p, struct tcp_header * h, void * d, size_t payload_size) {
uint32_t sum = 0;
uint16_t * s = (uint16_t *)p;
/* TODO: Checksums for options? */
for (int i = 0; i < 6; ++i) {
sum += ntohs(s[i]);
if (sum > 0xFFFF) {
sum = (sum >> 16) + (sum & 0xFFFF);
}
}
s = (uint16_t *)h;
for (int i = 0; i < 10; ++i) {
sum += ntohs(s[i]);
if (sum > 0xFFFF) {
sum = (sum >> 16) + (sum & 0xFFFF);
}
}
uint16_t d_words = payload_size / 2;
s = (uint16_t *)d;
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 != payload_size) {
uint8_t * t = (uint8_t *)d;
uint8_t tmp[2];
tmp[0] = t[d_words * sizeof(uint16_t)];
tmp[1] = 0;
uint16_t * f = (uint16_t *)tmp;
sum += ntohs(f[0]);
if (sum > 0xFFFF) {
sum = (sum >> 16) + (sum & 0xFFFF);
}
}
return ~(sum & 0xFFFF) & 0xFFFF;
}
static int init(void) {
return 0;
}
static int fini(void) {
return 0;
}
MODULE_DEF(net, init, fini);