quinn-os/ether.c
2017-10-07 23:37:30 +10:00

93 lines
2.0 KiB
C

#include "ether.h"
#include "i825xx.h"
#include "memory.h"
#include "arp.h"
struct ether_t **etherdevs;
unsigned int etherdev_count;
static int add_ether(struct ether_t *card) {
if (!etherdev_count) {
etherdevs = (struct ether_t **)malloc(sizeof(struct ether_t *));
} else {
etherdevs = (struct ether_t **)realloc(etherdevs, sizeof(struct ether_t *) * (etherdev_count + 1));
}
etherdevs[etherdev_count++] = card;
return 1;
}
int ether_send(struct ether_t *card, char *packet, int len) {
int sr;
if (card->type == 1) {
sr = i825xx_send((struct i825xx_device_t *)card->data, packet, len);
return sr;
}
}
int ether_receive(struct ether_t *ether, unsigned char *packet, int len) {
struct ether_packet_t *p = (struct ether_packet_t *)packet;
if (htons(p->ethertype) == 0x806) {
if (!(len - 14 < sizeof(struct arp_packet_t))) {
arp_process_packet(ether, (struct arp_packet_t *)(p->payload));
}
} else if (htons(p->ethertype) == 0x800) {
ipv4_process_packet(ether, (char *)(p->payload), len - sizeof(struct ether_packet_t));
}
}
int ether_enable(int ether, unsigned int ipv4, unsigned int mask) {
if (ether < 0 || ether >= etherdev_count) {
return -1;
}
etherdevs[ether]->ipv4 = ipv4;
etherdevs[ether]->mask = mask;
init_arp(etherdevs[ether]);
if (etherdevs[ether]->type == 1) {
i825xx_enable(etherdevs[ether]);
}
return etherdevs[ether]->state;
}
int ether_add_default_gw(int ether, unsigned int ipv4) {
if (ether < 0 || ether >= etherdev_count) {
return -1;
}
etherdevs[ether]->default_gw = ipv4;
return 0;
}
struct ether_t *ether_find_from_ipv4(unsigned int ipv4) {
int i;
for (i=0;i<etherdev_count;i++) {
if ((ipv4 & etherdevs[i]->mask) == (etherdevs[i]->ipv4 & etherdevs[i]->mask) || etherdevs[i]->default_gw != 0) {
return etherdevs[i];
}
}
return (void *)0;
}
void init_ether() {
struct ether_t *ether;
int count;
etherdev_count = 0;
count = 0;
ether = init_i825xx(count);
while (ether != (void *)0) {
add_ether(ether);
count++;
ether = init_i825xx(count);
}
}