More network subfunctions of sf75 and sf76.

This commit is contained in:
Ivan Baravy 2020-05-07 04:08:20 +03:00
parent 64ce1ee214
commit 728172f401
7 changed files with 442 additions and 5 deletions

View File

@ -239,7 +239,7 @@ typedef struct {
uint32_t eax;
} pushad_t;
#define NET_TYPE_ETH 1
#define NET_TYPE_ETH 1
#define NET_TYPE_SLIP 2
// Link state
@ -250,6 +250,33 @@ typedef struct {
#define ETH_LINK_100M 0x8 // 100 mbit
#define ETH_LINK_1G 0xc // gigabit
// Ethernet protocol numbers
#define ETHER_PROTO_ARP 0x0608
#define ETHER_PROTO_IPv4 0x0008
#define ETHER_PROTO_IPv6 0xDD86
#define ETHER_PROTO_PPP_DISCOVERY 0x6388
#define ETHER_PROTO_PPP_SESSION 0x6488
// Internet protocol numbers
#define IP_PROTO_IP 0
#define IP_PROTO_ICMP 1
#define IP_PROTO_TCP 6
#define IP_PROTO_UDP 17
#define IP_PROTO_RAW 255
// IP options
#define IP_TOS 1
#define IP_TTL 2
#define IP_HDRINCL 3
// PPP protocol numbers
#define PPP_PROTO_IPv4 0x2100
#define PPP_PROTO_IPV6 0x5780
#define PPP_PROTO_ETHERNET 666
// Protocol family
#define AF_INET4 AF_INET
typedef struct {
uint32_t device_type; // type field
uint32_t mtu; // Maximal Transmission Unit
@ -267,8 +294,19 @@ typedef struct {
uint32_t link_state; // link state (0 = no link)
uint32_t hwacc; // bitmask stating enabled HW accelerations (offload
// engines)
uint8_t mac[6];
} net_device_t; // NET_DEVICE
typedef struct {
void *next; // pointer to next frame in list
void *prev; // pointer to previous frame in list
net_device_t *device; // ptr to NET_DEVICE structure
uint32_t type; // encapsulation type: e.g. Ethernet
size_t length; // size of encapsulated data
size_t offset; // offset to actual data (24 bytes for default frame)
uint8_t data[0];
} net_buff_t;
void kos_init(void);
void i40(void);
uint32_t kos_time_to_epoch(uint32_t *time);
@ -294,6 +332,16 @@ static inline void kos_enable_acpi() {
: "memory", "cc");
}
typedef struct {
uint32_t value;
uint32_t errorcode;
} f75ret_t;
typedef struct {
uint32_t eax;
uint32_t ebx;
} f76ret_t;
static inline void kos_stack_init() {
__asm__ __inline__ __volatile__ (
"pushad;"

View File

@ -539,5 +539,157 @@ static inline uint32_t umka_sys_net_get_link_status(uint8_t dev_num) {
return status;
}
static inline f75ret_t umka_sys_net_open_socket(uint32_t domain, uint32_t type,
uint32_t protocol) {
f75ret_t r;
__asm__ __inline__ __volatile__ (
"call i40"
: "=a"(r.value),
"=b"(r.errorcode)
: "a"(75),
"b"(0),
"c"(domain),
"d"(type),
"S"(protocol)
: "memory");
return r;
}
static inline f75ret_t umka_sys_net_close_socket(uint32_t fd) {
f75ret_t r;
__asm__ __inline__ __volatile__ (
"call i40"
: "=a"(r.value),
"=b"(r.errorcode)
: "a"(75),
"b"(1),
"c"(fd)
: "memory");
return r;
}
static inline f75ret_t umka_sys_net_bind(uint32_t fd, void *sockaddr,
size_t sockaddr_len) {
f75ret_t r;
__asm__ __inline__ __volatile__ (
"call i40"
: "=a"(r.value),
"=b"(r.errorcode)
: "a"(75),
"b"(2),
"c"(fd),
"d"(sockaddr),
"S"(sockaddr_len)
: "memory");
return r;
}
static inline f75ret_t umka_sys_net_listen(uint32_t fd, uint32_t backlog) {
f75ret_t r;
__asm__ __inline__ __volatile__ (
"call i40"
: "=a"(r.value),
"=b"(r.errorcode)
: "a"(75),
"b"(3),
"c"(fd),
"d"(backlog)
: "memory");
return r;
}
static inline f75ret_t umka_sys_net_connect(uint32_t fd, void *sockaddr,
size_t sockaddr_len) {
f75ret_t r;
__asm__ __inline__ __volatile__ (
"call i40"
: "=a"(r.value),
"=b"(r.errorcode)
: "a"(75),
"b"(4),
"c"(fd),
"d"(sockaddr),
"S"(sockaddr_len)
: "memory");
return r;
}
static inline f75ret_t umka_sys_net_accept(uint32_t fd, void *sockaddr,
size_t sockaddr_len) {
f75ret_t r;
__asm__ __inline__ __volatile__ (
"call i40"
: "=a"(r.value),
"=b"(r.errorcode)
: "a"(75),
"b"(5),
"c"(fd),
"d"(sockaddr),
"S"(sockaddr_len)
: "memory");
return r;
}
static inline f76ret_t umka_sys_net_eth_read_mac(uint32_t dev_num) {
f76ret_t r;
__asm__ __inline__ __volatile__ (
"call i40"
: "=a"(r.eax),
"=b"(r.ebx)
: "a"(76),
"b"((0 << 16) + (dev_num << 8) + 0)
: "memory");
return r;
}
// Function 76, Protocol 1 - IPv4, Subfunction 0, Read # Packets sent =
// Function 76, Protocol 1 - IPv4, Subfunction 1, Read # Packets rcvd =
static inline f76ret_t umka_sys_net_ipv4_get_addr(uint32_t dev_num) {
f76ret_t r;
__asm__ __inline__ __volatile__ (
"call i40"
: "=a"(r.eax),
"=b"(r.ebx)
: "a"(76),
"b"((1 << 16) + (dev_num << 8) + 2)
: "memory");
return r;
}
static inline f76ret_t umka_sys_net_ipv4_set_addr(uint32_t dev_num,
uint32_t addr) {
f76ret_t r;
__asm__ __inline__ __volatile__ (
"call i40"
: "=a"(r.eax),
"=b"(r.ebx)
: "a"(76),
"b"((1 << 16) + (dev_num << 8) + 3),
"c"(addr)
: "memory");
return r;
}
// Function 76, Protocol 1 - IPv4, Subfunction 4, Read DNS address ===
// Function 76, Protocol 1 - IPv4, Subfunction 5, Set DNS address ===
// Function 76, Protocol 1 - IPv4, Subfunction 6, Read subnet mask ===
// Function 76, Protocol 1 - IPv4, Subfunction 7, Set subnet mask ===
// Function 76, Protocol 1 - IPv4, Subfunction 8, Read gateway ====
// Function 76, Protocol 1 - IPv4, Subfunction 9, Set gateway =====
// Function 76, Protocol 2 - ICMP, Subfunction 0, Read # Packets sent =
// Function 76, Protocol 2 - ICMP, Subfunction 1, Read # Packets rcvd =
// Function 76, Protocol 3 - UDP, Subfunction 0, Read # Packets sent ==
// Function 76, Protocol 3 - UDP, Subfunction 1, Read # Packets rcvd ==
// Function 76, Protocol 4 - TCP, Subfunction 0, Read # Packets sent ==
// Function 76, Protocol 4 - TCP, Subfunction 1, Read # Packets rcvd ==
// Function 76, Protocol 5 - ARP, Subfunction 0, Read # Packets sent ==
// Function 76, Protocol 5 - ARP, Subfunction 1, Read # Packets rcvd ==
// Function 76, Protocol 5 - ARP, Subfunction 2, Read # ARP entries ==
// Function 76, Protocol 5 - ARP, Subfunction 3, Read ARP entry ====
// Function 76, Protocol 5 - ARP, Subfunction 4, Add ARP entry ====
// Function 76, Protocol 5 - ARP, Subfunction 5, Remove ARP entry ====
// Function 76, Protocol 5 - ARP, Subfunction 6, Send ARP announce ==
// Function 76, Protocol 5 - ARP, Subfunction 7, Read # conflicts ===
#endif

19
test/023_#net_#f75_all.t Normal file
View File

@ -0,0 +1,19 @@
stack_init
net_add_device
net_get_dev_type 1
net_get_dev_name 1
net_dev_reset 1
net_get_dev 1
net_get_packet_tx_count 1
net_get_packet_rx_count 1
net_get_byte_tx_count 1
net_get_byte_rx_count 1
net_get_link_status 1
#net_open_socket 2 1 0
#net_bind 3 80 192.243.108.5
net_open_socket 2 1 0
net_connect 1 80 192.243.108.5
net_accept 1 80 192.243.108.5

9
test/024_#net_#f76_all.t Normal file
View File

@ -0,0 +1,9 @@
stack_init
net_add_device
net_get_dev_type 1
net_get_dev_name 1
net_dev_reset 1
net_eth_read_mac 1
net_ipv4_set_addr 1 192.168.1.27
net_ipv4_get_addr 1

View File

@ -30,6 +30,9 @@
#include <fcntl.h>
#include <assert.h>
#include <time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "vdisk.h"
#include "vnet.h"
#include "kolibri.h"
@ -72,8 +75,9 @@ net_device_t vnet = {
.packets_tx = 0,
.packets_rx = 0,
.link_state = 0, // link state (0 = no link)
.link_state = ETH_LINK_FD + ETH_LINK_10M,
.hwacc = 0,
.mac = {0x80, 0x2b, 0xf9, 0x3b, 0x6c, 0xca},
};
char cur_dir[PATH_MAX] = "/";
@ -1266,7 +1270,7 @@ void shell_net_get_link_status(int argc, char **argv) {
return;
}
uint8_t dev_num = strtoul(argv[1], NULL, 0);
uint32_t status = umka_sys_net_get_byte_rx_count(dev_num);
uint32_t status = umka_sys_net_get_link_status(dev_num);
printf("status: %s\n", status == UINT32_MAX ? "fail" : "ok");
if (status != UINT32_MAX) {
printf("link status of net dev #%" PRIu8 ": %" PRIu32 " ",
@ -1276,6 +1280,190 @@ void shell_net_get_link_status(int argc, char **argv) {
}
}
void shell_net_open_socket(int argc, char **argv) {
const char *usage = \
"usage: net_open_socket <domain> <type> <protocol>\n"
" domain domain\n"
" type type\n"
" protocol protocol";
if (argc != 4) {
puts(usage);
return;
}
uint32_t domain = strtoul(argv[1], NULL, 0);
uint32_t type = strtoul(argv[2], NULL, 0);
uint32_t protocol = strtoul(argv[3], NULL, 0);
f75ret_t r = umka_sys_net_open_socket(domain, type, protocol);
printf("value: 0x%" PRIx32 "\n", r.value);
printf("errorcode: 0x%" PRIx32 "\n", r.errorcode);
// UINT32_MAX
}
void shell_net_close_socket(int argc, char **argv) {
const char *usage = \
"usage: net_close_socket <socket number>\n"
" socket number socket number";
if (argc != 2) {
puts(usage);
return;
}
uint32_t fd = strtoul(argv[1], NULL, 0);
f75ret_t r = umka_sys_net_close_socket(fd);
printf("value: 0x%" PRIx32 "\n", r.value);
printf("errorcode: 0x%" PRIx32 "\n", r.errorcode);
}
void shell_net_bind(int argc, char **argv) {
const char *usage = \
"usage: net_bind <fd> <port> <ip>\n"
" fd socket number\n"
" port port\n"
" addr addr";
if (argc != 4) {
puts(usage);
return;
}
uint32_t fd = strtoul(argv[1], NULL, 0);
uint16_t port = strtoul(argv[2], NULL, 0);
char *addr_str = argv[3];
uint32_t addr = inet_addr(addr_str);
struct sockaddr_in sa;
memset(&sa, 0, sizeof(sa));
sa.sin_family = AF_INET4;
sa.sin_port = htons(port);
sa.sin_addr.s_addr = addr;
printf("sockaddr at %p\n", &sa);
f75ret_t r = umka_sys_net_bind(fd, &sa, sizeof(struct sockaddr_in));
printf("value: 0x%" PRIx32 "\n", r.value);
printf("errorcode: 0x%" PRIx32 "\n", r.errorcode);
}
void shell_net_listen(int argc, char **argv) {
const char *usage = \
"usage: net_listen <fd> <backlog>\n"
" fd socket number\n"
" backlog max queue length";
if (argc != 3) {
puts(usage);
return;
}
uint32_t fd = strtoul(argv[1], NULL, 0);
uint32_t backlog = strtoul(argv[2], NULL, 0);
f75ret_t r = umka_sys_net_listen(fd, backlog);
printf("value: 0x%" PRIx32 "\n", r.value);
printf("errorcode: 0x%" PRIx32 "\n", r.errorcode);
}
void shell_net_connect(int argc, char **argv) {
const char *usage = \
"usage: net_connect <fd> <port> <ip>\n"
" fd socket number\n"
" port port\n"
" addr addr";
if (argc != 4) {
puts(usage);
return;
}
uint32_t fd = strtoul(argv[1], NULL, 0);
uint16_t port = strtoul(argv[2], NULL, 0);
char *addr_str = argv[3];
uint32_t addr = inet_addr(addr_str);
struct sockaddr_in sa;
memset(&sa, 0, sizeof(sa));
sa.sin_family = AF_INET4;
sa.sin_port = htons(port);
sa.sin_addr.s_addr = addr;
printf("sockaddr at %p\n", &sa);
f75ret_t r = umka_sys_net_connect(fd, &sa, sizeof(struct sockaddr_in));
printf("value: 0x%" PRIx32 "\n", r.value);
printf("errorcode: 0x%" PRIx32 "\n", r.errorcode);
}
void shell_net_accept(int argc, char **argv) {
const char *usage = \
"usage: net_accept <fd> <port> <ip>\n"
" fd socket number\n"
" port port\n"
" addr addr";
if (argc != 4) {
puts(usage);
return;
}
uint32_t fd = strtoul(argv[1], NULL, 0);
uint16_t port = strtoul(argv[2], NULL, 0);
char *addr_str = argv[3];
uint32_t addr = inet_addr(addr_str);
struct sockaddr_in sa;
memset(&sa, 0, sizeof(sa));
sa.sin_family = AF_INET4;
sa.sin_port = htons(port);
sa.sin_addr.s_addr = addr;
printf("sockaddr at %p\n", &sa);
f75ret_t r = umka_sys_net_accept(fd, &sa, sizeof(struct sockaddr_in));
printf("value: 0x%" PRIx32 "\n", r.value);
printf("errorcode: 0x%" PRIx32 "\n", r.errorcode);
}
void shell_net_eth_read_mac(int argc, char **argv) {
const char *usage = \
"usage: net_eth_read_mac <dev_num>\n"
" dev_num device number as returned by net_add_device";
if (argc != 2) {
puts(usage);
return;
}
uint32_t dev_num = strtoul(argv[1], NULL, 0);
f76ret_t r = umka_sys_net_eth_read_mac(dev_num);
if (r.eax == UINT32_MAX) {
printf("status: fail\n");
} else {
printf("%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
(uint8_t)(r.ebx >> 0), (uint8_t)(r.ebx >> 8),
(uint8_t)(r.eax >> 0), (uint8_t)(r.eax >> 8),
(uint8_t)(r.eax >> 16), (uint8_t)(r.eax >> 24));
}
}
void shell_net_ipv4_get_addr(int argc, char **argv) {
const char *usage = \
"usage: net_ipv4_get_addr <dev_num>\n"
" dev_num device number as returned by net_add_device";
if (argc != 2) {
puts(usage);
return;
}
uint32_t dev_num = strtoul(argv[1], NULL, 0);
f76ret_t r = umka_sys_net_ipv4_get_addr(dev_num);
if (r.eax == UINT32_MAX) {
printf("status: fail\n");
} else {
printf("%d.%d.%d.%d\n",
(uint8_t)(r.eax >> 0), (uint8_t)(r.eax >> 8),
(uint8_t)(r.eax >> 16), (uint8_t)(r.eax >> 24));
}
}
void shell_net_ipv4_set_addr(int argc, char **argv) {
const char *usage = \
"usage: net_ipv4_set_addr <dev_num> <addr>\n"
" dev_num device number as returned by net_add_device\n"
" addr a.b.c.d";
if (argc != 3) {
puts(usage);
return;
}
uint32_t dev_num = strtoul(argv[1], NULL, 0);
char *addr_str = argv[2];
uint32_t addr = inet_addr(addr_str);
f76ret_t r = umka_sys_net_ipv4_set_addr(dev_num, addr);
if (r.eax == UINT32_MAX) {
printf("status: fail\n");
} else {
printf("status: ok\n");
}
}
typedef struct {
char *name;
@ -1340,6 +1528,15 @@ func_table_t funcs[] = {
{ "net_get_byte_tx_count", shell_net_get_byte_tx_count },
{ "net_get_byte_rx_count", shell_net_get_byte_rx_count },
{ "net_get_link_status", shell_net_get_link_status },
{ "net_open_socket", shell_net_open_socket },
{ "net_close_socket", shell_net_close_socket },
{ "net_bind", shell_net_bind },
{ "net_listen", shell_net_listen },
{ "net_connect", shell_net_connect },
{ "net_accept", shell_net_accept },
{ "net_eth_read_mac", shell_net_eth_read_mac },
{ "net_ipv4_get_addr", shell_net_ipv4_get_addr },
{ "net_ipv4_set_addr", shell_net_ipv4_set_addr },
{ NULL, NULL },
};

14
vnet.c
View File

@ -11,6 +11,7 @@ typedef struct {
} vnet_t;
void *vnet_init() {
printf("vnet_init\n");
vnet_t *vnet = (vnet_t*)malloc(sizeof(vnet_t));
*vnet = (vnet_t){.x = 0,};
return vnet;
@ -18,18 +19,29 @@ void *vnet_init() {
__attribute__((__stdcall__))
void vnet_unload() {
printf("vnet_unload\n");
COVERAGE_OFF();
COVERAGE_ON();
}
__attribute__((__stdcall__))
void vnet_reset() {
printf("vnet_reset\n");
COVERAGE_OFF();
COVERAGE_ON();
}
static void dump_net_buff(net_buff_t *buf) {
for (size_t i = 0; i < buf->length; i++) {
printf("%2.2x ", buf->data[i]);
}
putchar('\n');
}
__attribute__((__stdcall__))
void vnet_transmit() {
void vnet_transmit(net_buff_t *buf) {
printf("vnet_transmit: %d bytes\n", buf->length);
dump_net_buff(buf);
COVERAGE_OFF();
COVERAGE_ON();
}

2
vnet.h
View File

@ -14,6 +14,6 @@ __attribute__((__stdcall__))
void vnet_reset(void);
__attribute__((__stdcall__))
void vnet_transmit(void);
void vnet_transmit(net_buff_t *buf);
#endif // VNET_H_INCLUDED