mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-27 12:48:22 +00:00
69 lines
1.9 KiB
C
69 lines
1.9 KiB
C
#include <kernel/virtio.h>
|
|
#include <logging.h>
|
|
#include <kernel/page.h>
|
|
#include <kernel/eth.h>
|
|
#include <kernel/net.h>
|
|
#include <hashtable.h>
|
|
#include <arch/cpu.h>
|
|
#include <kernel/init.h>
|
|
#include <kernel/interrupt.h>
|
|
|
|
static netdev_t loopbacknetdev;
|
|
|
|
// requested size doesn't account for ethernet header or the virtio header
|
|
static int loopback_allocdesc(netdev_t *netdev, size_t requestedsize, netdesc_t *desc) {
|
|
__assert(requestedsize <= netdev->mtu);
|
|
desc->address = alloc(requestedsize + sizeof(ethframe_t));
|
|
if (desc->address == NULL)
|
|
return ENOMEM;
|
|
|
|
desc->size = requestedsize + sizeof(ethframe_t);
|
|
desc->curroffset = sizeof(ethframe_t);
|
|
return 0;
|
|
}
|
|
|
|
static int loopback_freedesc(netdev_t *netdev, netdesc_t *desc) {
|
|
free(desc->address);
|
|
return 0;
|
|
}
|
|
|
|
static int loopback_sendpacket(netdev_t *netdev, netdesc_t desc, mac_t targetmac, int proto) {
|
|
desc.curroffset = 0;
|
|
ethframe_t ethframe = {
|
|
.type = cpu_to_be_w(proto)
|
|
};
|
|
|
|
mac_t broadcast = NET_BROADCAST_MAC;
|
|
|
|
memcpy(ðframe.source, &netdev->mac, sizeof(mac_t));
|
|
memcpy(ðframe.destination, &broadcast, sizeof(mac_t));
|
|
memcpy(desc.address, ðframe, sizeof(ethframe_t));
|
|
|
|
long ipl = interrupt_raiseipl(IPL_DPC);
|
|
eth_process(netdev, desc.address);
|
|
interrupt_loweripl(ipl);
|
|
|
|
return netdev->freedesc(netdev, &desc);
|
|
}
|
|
|
|
netdev_t *loopback_device() {
|
|
return &loopbacknetdev;
|
|
}
|
|
|
|
void loopback_init() {
|
|
loopbacknetdev.mtu = 30000;
|
|
loopbacknetdev.sendpacket = loopback_sendpacket;
|
|
loopbacknetdev.allocdesc = loopback_allocdesc;
|
|
loopbacknetdev.freedesc = loopback_freedesc;
|
|
loopbacknetdev.ip = 0x7f000001;
|
|
loopbacknetdev.flags = NETDEV_FLAGS_UP | NETDEV_FLAGS_LOOPBACK | NETDEV_FLAGS_RUNNING;
|
|
__assert(hashtable_init(&loopbacknetdev.arpcache, 30) == 0);
|
|
|
|
for (int i = 0; i < 6; ++i)
|
|
loopbacknetdev.mac.address[i] = 0;
|
|
|
|
__assert(netdev_register(&loopbacknetdev, "lo") == 0);
|
|
}
|
|
|
|
INIT_ROUTINE_DEFINE(loopback, INIT_ROUTINE_FLAGS_NONE, loopback_init, devfs);
|