Skip to content

Commit

Permalink
Add arp.c for arp packet debugging.
Browse files Browse the repository at this point in the history
  • Loading branch information
zxystd committed Jul 2, 2023
1 parent ea7e802 commit a84edc8
Show file tree
Hide file tree
Showing 5 changed files with 350 additions and 1 deletion.
2 changes: 2 additions & 0 deletions AirportItlwm/AirportItlwmV2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <crypto/sha1.h>
#include <net80211/ieee80211_priv.h>
#include <net80211/ieee80211_var.h>
#include <sys/arp.h>

#include "AirportItlwmSkywalkInterface.hpp"
#include "IOPCIEDeviceWrapper.hpp"
Expand Down Expand Up @@ -548,6 +549,7 @@ UInt32 AirportItlwm::outputPacket(mbuf_t m, void *param)
ifp->netStat->outputErrors++;
ret = kIOReturnOutputDropped;
}
debug_print_arp(__func__, m);
if (!ifp->if_snd.queue->lockEnqueue(m)) {
freePacket(m);
ret = kIOReturnOutputDropped;
Expand Down
12 changes: 11 additions & 1 deletion itl80211/openbsd/sys/_mbuf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,25 @@
*/

#include <sys/_mbuf.h>

extern "C" {
#include <net/bpf.h>
}
#include <sys/arp.h>
#include <IOKit/IOCommandGate.h>

extern IOCommandGate *_fCommandGate;

struct network_header {
char pad[0x48];
};

static IOReturn _if_input(OSObject *target, void *arg0, void *arg1, void *arg2, void *arg3)
{
mbuf_t m;
bool isEmpty = true;
struct _ifnet *ifq = (struct _ifnet *)arg0;
struct mbuf_list *ml = (struct mbuf_list *)arg1;
struct network_header header = { 0 };

MBUF_LIST_FOREACH(ml, m) {
if (ifq->iface == NULL) {
Expand All @@ -43,6 +51,8 @@ static IOReturn _if_input(OSObject *target, void *arg0, void *arg1, void *arg2,
}
// XYLog("%s %d 啊啊啊啊 ifq->iface->inputPacket(m) hdr_len=%d len=%d\n", __FUNCTION__, __LINE__, mbuf_pkthdr_len(m), mbuf_len(m));
isEmpty = false;
debug_print_arp(__func__, m);
bpf_tap_in(ifq->iface->getIfnet(), DLT_RAW, m, &header, 0x48);
ifq->iface->inputPacket(m, 0, IONetworkInterface::kInputOptionQueuePacket);
if (ifq->netStat != NULL) {
ifq->netStat->inputPackets++;
Expand Down
301 changes: 301 additions & 0 deletions itl80211/openbsd/sys/arp.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,301 @@
//
// arp.c
// itlwm
//
// Created by zxystd on 2023/7/1.
// Copyright © 2023 钟先耀. All rights reserved.
//

#include "arp.h"

#include <netinet/if_ether.h>
#include <linux/types.h>
#include <sys/_malloc.h>

#define EXTRACT_16BITS(p) \
((u_int16_t)*((const u_int8_t *)(p) + 0) << 8 | \
(u_int16_t)*((const u_int8_t *)(p) + 1))
#define EXTRACT_32BITS(p) \
((u_int32_t)*((const u_int8_t *)(p) + 0) << 24 | \
(u_int32_t)*((const u_int8_t *)(p) + 1) << 16 | \
(u_int32_t)*((const u_int8_t *)(p) + 2) << 8 | \
(u_int32_t)*((const u_int8_t *)(p) + 3))
#define EXTRACT_24BITS(p) \
((u_int32_t)*((const u_int8_t *)(p) + 0) << 16 | \
(u_int32_t)*((const u_int8_t *)(p) + 1) << 8 | \
(u_int32_t)*((const u_int8_t *)(p) + 2))
#define EXTRACT_LE_8BITS(p) (*(p))
#define EXTRACT_LE_16BITS(p) \
((u_int16_t)*((const u_int8_t *)(p) + 1) << 8 | \
(u_int16_t)*((const u_int8_t *)(p) + 0))
#define EXTRACT_LE_32BITS(p) \
((u_int32_t)*((const u_int8_t *)(p) + 3) << 24 | \
(u_int32_t)*((const u_int8_t *)(p) + 2) << 16 | \
(u_int32_t)*((const u_int8_t *)(p) + 1) << 8 | \
(u_int32_t)*((const u_int8_t *)(p) + 0))
#define EXTRACT_LE_64BITS(p) \
((u_int64_t)*((const u_int8_t *)(p) + 7) << 56 | \
(u_int64_t)*((const u_int8_t *)(p) + 6) << 48 | \
(u_int64_t)*((const u_int8_t *)(p) + 5) << 40 | \
(u_int64_t)*((const u_int8_t *)(p) + 4) << 32 | \
(u_int64_t)*((const u_int8_t *)(p) + 3) << 24 | \
(u_int64_t)*((const u_int8_t *)(p) + 2) << 16 | \
(u_int64_t)*((const u_int8_t *)(p) + 1) << 8 | \
(u_int64_t)*((const u_int8_t *)(p) + 0))

#define ESRC(ep) ((ep)->ether_shost)
#define EDST(ep) ((ep)->ether_dhost)
#define SHA(ap) ((ap)->arp_sha)
#define THA(ap) ((ap)->arp_tha)
#define SPA(ap) ((ap)->arp_spa)
#define TPA(ap) ((ap)->arp_tpa)

#define HASHNAMESIZE 4096

struct hnamemem {
u_int32_t addr;
char *name;
struct hnamemem *nxt;
};

struct enamemem {
u_short e_addr0;
u_short e_addr1;
u_short e_addr2;
char *e_name;
u_char *e_nsap; /* used only for nsaptable[] */
#define e_bs e_nsap /* for bytestringtable */
struct enamemem *e_nxt;
};

struct hnamemem hnametable[HASHNAMESIZE];
struct enamemem enametable[HASHNAMESIZE];

struct hnamemem *
newhnamemem(void)
{
struct hnamemem *p;
static struct hnamemem *ptr = NULL;
static u_int num = 0;

if (num <= 0) {
num = 64;
ptr = (struct hnamemem *)malloc(num * sizeof (*ptr), 0, 0);
}
--num;
p = ptr++;
return (p);
}

char *
intoa(u_int32_t addr)
{
char *cp;
u_int byte;
int n;
static char buf[sizeof(".xxx.xxx.xxx.xxx")];

NTOHL(addr);
cp = &buf[sizeof buf];
*--cp = '\0';

n = 4;
do {
byte = addr & 0xff;
*--cp = byte % 10 + '0';
byte /= 10;
if (byte > 0) {
*--cp = byte % 10 + '0';
byte /= 10;
if (byte > 0)
*--cp = byte + '0';
}
*--cp = '.';
addr >>= 8;
} while (--n > 0);

return cp + 1;
}

char *
savestr(const char *str)
{
size_t size;
char *p;
static char *strptr = NULL;
static size_t strsize = 0;

size = strlen(str) + 1;
if (size > strsize) {
strsize = 1024;
if (strsize < size)
strsize = size;
strptr = (char *)malloc(strsize, 0, 0);
}
(void)strlcpy(strptr, str, size);
p = strptr;
strptr += size;
strsize -= size;
return (p);
}

#define HOST_NAME_MAX 255

char *
getname(const u_char *ap)
{
char host[HOST_NAME_MAX+1];
u_int32_t addr;
struct hnamemem *p;

/*
* Extract 32 bits in network order, dealing with alignment.
*/
switch ((intptr_t)ap & (sizeof(u_int32_t)-1)) {

case 0:
addr = *(u_int32_t *)ap;
break;

case 2:
#if BYTE_ORDER == BIG_ENDIAN
addr = ((u_int32_t)*(u_short *)ap << 16) |
(u_int32_t)*(u_short *)(ap + 2);
#else
addr = ((u_int32_t)*(u_short *)(ap + 2) << 16) |
(u_int32_t)*(u_short *)ap;
#endif
break;

default:
#if BYTE_ORDER == BIG_ENDIAN
addr = ((u_int32_t)ap[0] << 24) |
((u_int32_t)ap[1] << 16) |
((u_int32_t)ap[2] << 8) |
(u_int32_t)ap[3];
#else
addr = ((u_int32_t)ap[3] << 24) |
((u_int32_t)ap[2] << 16) |
((u_int32_t)ap[1] << 8) |
(u_int32_t)ap[0];
#endif
break;
}

p = &hnametable[addr & (HASHNAMESIZE-1)];
for (; p->nxt; p = p->nxt) {
if (p->addr == addr)
return (p->name);
}
p->addr = addr;
p->nxt = newhnamemem();

p->name = savestr(intoa(addr));
return (p->name);
}

char *
ether_ntoa(struct ether_addr *e)
{
static char a[] = "xx:xx:xx:xx:xx:xx";

(void)snprintf(a, sizeof a, "%02x:%02x:%02x:%02x:%02x:%02x",
e->ether_addr_octet[0], e->ether_addr_octet[1],
e->ether_addr_octet[2], e->ether_addr_octet[3],
e->ether_addr_octet[4], e->ether_addr_octet[5]);

return (a);
}

static inline struct enamemem *
lookup_emem(const u_char *ep)
{
u_int i, j, k;
struct enamemem *tp;

k = (ep[0] << 8) | ep[1];
j = (ep[2] << 8) | ep[3];
i = (ep[4] << 8) | ep[5];

tp = &enametable[(i ^ j) & (HASHNAMESIZE-1)];
while (tp->e_nxt)
if (tp->e_addr0 == i &&
tp->e_addr1 == j &&
tp->e_addr2 == k)
return tp;
else
tp = tp->e_nxt;
tp->e_addr0 = i;
tp->e_addr1 = j;
tp->e_addr2 = k;
tp->e_nxt = (struct enamemem *)malloc(1 * sizeof(*tp), 0, 0);

return tp;
}

char *
etheraddr_string(const u_char *ep)
{
struct enamemem *tp;
struct ether_addr e;

tp = lookup_emem(ep);
if (tp->e_name)
return (tp->e_name);
memcpy(e.ether_addr_octet, ep, sizeof(e.ether_addr_octet));
tp->e_name = savestr(ether_ntoa(&e));
return (tp->e_name);
}

#define ipaddr_string(p) getname((const u_char *)(p))

void
debug_print_arp(const char *tag, mbuf_t m)
{
size_t len = mbuf_len(m);
ether_header_t *eh = (ether_header_t *)mbuf_data(m);
if (len >= sizeof(ether_header_t) &&
(eh->ether_type == htons(ETHERTYPE_ARP) || eh->ether_type == htons(ETHERTYPE_REVARP))) {
u_char *p = (u_char *)eh + sizeof(ether_header);
len -= sizeof(ether_header);
const struct ether_arp *ap = (const struct ether_arp *)p;
u_short pro, hrd, op;
pro = EXTRACT_16BITS(&ap->arp_pro);
hrd = EXTRACT_16BITS(&ap->arp_hrd);
op = EXTRACT_16BITS(&ap->arp_op);
if ((pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL)
|| ap->arp_hln != sizeof(SHA(ap))
|| ap->arp_pln != sizeof(SPA(ap))) {
XYLog("%s arp-#%d for proto #%d (%d) hardware #%d (%d)\n",
tag, op, pro, ap->arp_pln, hrd, ap->arp_hln);
}
if (pro == ETHERTYPE_TRAIL)
XYLog("%s trailer-\n", tag);
switch (op) {

case ARPOP_REQUEST:
XYLog("%s arp who-has %s tell %s\n", tag, ipaddr_string(TPA(ap)), ipaddr_string(SPA(ap)));
break;

case ARPOP_REPLY:
XYLog("%s arp reply %s is-at %s\n", tag, ipaddr_string(SPA(ap)), etheraddr_string(SHA(ap)));
break;

case ARPOP_REVREQUEST:
XYLog("%s rarp who-is %s tell %s\n", tag, etheraddr_string(THA(ap)),
etheraddr_string(SHA(ap)));
break;

case ARPOP_REVREPLY:
XYLog("%s rarp reply %s at %s\n", tag, etheraddr_string(THA(ap)),
ipaddr_string(TPA(ap)));
break;

default:
XYLog("%s arp-#%d\n", tag, op);
break;
}
if (hrd != ARPHRD_ETHER)
XYLog("%s hardware #%d\n", tag, hrd);
}
}
16 changes: 16 additions & 0 deletions itl80211/openbsd/sys/arp.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//
// arp.h
// itlwm
//
// Created by zxystd on 2023/7/1.
// Copyright © 2023 钟先耀. All rights reserved.
//

#ifndef arp_h
#define arp_h

#include <sys/kpi_mbuf.h>

void debug_print_arp(const char *tag, mbuf_t m);

#endif /* arp_h */
Loading

0 comments on commit a84edc8

Please sign in to comment.