arp: handle replies

This commit is contained in:
Matheus
2024-04-10 19:53:24 -03:00
parent 662e010925
commit 231eb98375
+42 -7
View File
@@ -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)