mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-01 06:58:22 +00:00
arp: handle replies
This commit is contained in:
+42
-7
@@ -11,6 +11,8 @@
|
|||||||
#define CACHE_TIMEOUT_SEC 300
|
#define CACHE_TIMEOUT_SEC 300
|
||||||
#define CACHE_TIMEOUT_MS (CACHE_TIMEOUT_SEC * 1000)
|
#define CACHE_TIMEOUT_MS (CACHE_TIMEOUT_SEC * 1000)
|
||||||
#define LOOKUP_TIMEOUT_SEC 5
|
#define LOOKUP_TIMEOUT_SEC 5
|
||||||
|
#define OPCODE_REQUEST 1
|
||||||
|
#define OPCODE_REPLY 2
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
mac_t mac;
|
mac_t mac;
|
||||||
@@ -115,11 +117,36 @@ static semaphore_t psem;
|
|||||||
static spinlock_t ringlock;
|
static spinlock_t ringlock;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
int opcode;
|
||||||
netdev_t *netdev;
|
netdev_t *netdev;
|
||||||
uint32_t ip;
|
uint32_t ip;
|
||||||
mac_t mac;
|
mac_t mac;
|
||||||
} bufferentry_t;
|
} bufferentry_t;
|
||||||
|
|
||||||
|
static void send_reply(netdev_t *netdev, uint32_t ip, mac_t mac) {
|
||||||
|
arpframe_t frame = {
|
||||||
|
.hwtype = cpu_to_be_w(1),
|
||||||
|
.protocoltype = cpu_to_be_w(0x800),
|
||||||
|
.hwlen = 6,
|
||||||
|
.ptlen = 4,
|
||||||
|
.opcode = cpu_to_be_w(OPCODE_REPLY),
|
||||||
|
.srcpt = cpu_to_be_d(netdev->ip),
|
||||||
|
.dstpt = cpu_to_be_d(ip)
|
||||||
|
};
|
||||||
|
|
||||||
|
memcpy(&frame.srchw, &netdev->mac, sizeof(mac_t));
|
||||||
|
memcpy(&frame.dsthw, &mac, sizeof(mac_t));
|
||||||
|
netdesc_t desc;
|
||||||
|
int e = netdev->allocdesc(sizeof(arpframe_t), &desc);
|
||||||
|
if (e)
|
||||||
|
return;
|
||||||
|
|
||||||
|
memcpy((void *)((uintptr_t)desc.address + desc.curroffset), &frame, sizeof(frame));
|
||||||
|
|
||||||
|
e = netdev->sendpacket(netdev, desc, mac, ETH_PROTO_ARP);
|
||||||
|
// TODO free netdesc
|
||||||
|
}
|
||||||
|
|
||||||
static void handlerthreadfn() {
|
static void handlerthreadfn() {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
semaphore_wait(&psem, false);
|
semaphore_wait(&psem, false);
|
||||||
@@ -132,14 +159,22 @@ static void handlerthreadfn() {
|
|||||||
spinlock_release(&ringlock);
|
spinlock_release(&ringlock);
|
||||||
interrupt_loweripl(old);
|
interrupt_loweripl(old);
|
||||||
|
|
||||||
MUTEX_ACQUIRE(&cachelock, false);
|
switch (entry.opcode) {
|
||||||
timespec_t time = timekeeper_time();
|
case OPCODE_REPLY:
|
||||||
set(entry.netdev, entry.ip, entry.mac, time);
|
// add to cache
|
||||||
MUTEX_RELEASE(&cachelock);
|
MUTEX_ACQUIRE(&cachelock, false);
|
||||||
|
timespec_t time = timekeeper_time();
|
||||||
|
set(entry.netdev, entry.ip, entry.mac, time);
|
||||||
|
MUTEX_RELEASE(&cachelock);
|
||||||
|
break;
|
||||||
|
case OPCODE_REQUEST:
|
||||||
|
// reply
|
||||||
|
send_reply(entry.netdev, entry.ip, entry.mac);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// executed in dpc context
|
// executed in dpc context
|
||||||
void arp_process(netdev_t *netdev, void *buffer) {
|
void arp_process(netdev_t *netdev, void *buffer) {
|
||||||
arpframe_t *frame = buffer;
|
arpframe_t *frame = buffer;
|
||||||
@@ -147,10 +182,10 @@ void arp_process(netdev_t *netdev, void *buffer) {
|
|||||||
__assert(frame->protocoltype == cpu_to_be_w(0x800)); // ip
|
__assert(frame->protocoltype == cpu_to_be_w(0x800)); // ip
|
||||||
__assert(frame->hwlen == 6);
|
__assert(frame->hwlen == 6);
|
||||||
__assert(frame->ptlen == 4);
|
__assert(frame->ptlen == 4);
|
||||||
__assert(frame->opcode == cpu_to_be_w(2));
|
|
||||||
__assert(MAC_EQUAL(&frame->dsthw, &netdev->mac));
|
__assert(MAC_EQUAL(&frame->dsthw, &netdev->mac));
|
||||||
|
|
||||||
bufferentry_t entry = {
|
bufferentry_t entry = {
|
||||||
|
.opcode = cpu_to_be_w(frame->opcode),
|
||||||
.netdev = netdev,
|
.netdev = netdev,
|
||||||
.ip = be_to_cpu_d(frame->srcpt),
|
.ip = be_to_cpu_d(frame->srcpt),
|
||||||
.mac = frame->srchw
|
.mac = frame->srchw
|
||||||
@@ -168,7 +203,7 @@ static int sendrequest(netdev_t *netdev, uint32_t ip) {
|
|||||||
.protocoltype = cpu_to_be_w(0x800),
|
.protocoltype = cpu_to_be_w(0x800),
|
||||||
.hwlen = 6,
|
.hwlen = 6,
|
||||||
.ptlen = 4,
|
.ptlen = 4,
|
||||||
.opcode = cpu_to_be_w(1),
|
.opcode = cpu_to_be_w(OPCODE_REQUEST),
|
||||||
.srcpt = 0,
|
.srcpt = 0,
|
||||||
.dsthw = (mac_t){{0,0,0,0,0,0}},
|
.dsthw = (mac_t){{0,0,0,0,0,0}},
|
||||||
.dstpt = cpu_to_be_d(ip)
|
.dstpt = cpu_to_be_d(ip)
|
||||||
|
|||||||
Reference in New Issue
Block a user