diff --git a/AirportItlwm/AirportItlwmV2.cpp b/AirportItlwm/AirportItlwmV2.cpp index db2e26e9a..3c75c386d 100644 --- a/AirportItlwm/AirportItlwmV2.cpp +++ b/AirportItlwm/AirportItlwmV2.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include "AirportItlwmSkywalkInterface.hpp" #include "IOPCIEDeviceWrapper.hpp" @@ -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; diff --git a/itl80211/openbsd/sys/_mbuf.cpp b/itl80211/openbsd/sys/_mbuf.cpp index 31e5ed05a..307a96293 100644 --- a/itl80211/openbsd/sys/_mbuf.cpp +++ b/itl80211/openbsd/sys/_mbuf.cpp @@ -20,17 +20,25 @@ */ #include - +extern "C" { +#include +} +#include #include 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) { @@ -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++; diff --git a/itl80211/openbsd/sys/arp.c b/itl80211/openbsd/sys/arp.c new file mode 100644 index 000000000..5cb3dc772 --- /dev/null +++ b/itl80211/openbsd/sys/arp.c @@ -0,0 +1,301 @@ +// +// arp.c +// itlwm +// +// Created by zxystd on 2023/7/1. +// Copyright © 2023 钟先耀. All rights reserved. +// + +#include "arp.h" + +#include +#include +#include + +#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); + } +} diff --git a/itl80211/openbsd/sys/arp.h b/itl80211/openbsd/sys/arp.h new file mode 100644 index 000000000..7caf46698 --- /dev/null +++ b/itl80211/openbsd/sys/arp.h @@ -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 + +void debug_print_arp(const char *tag, mbuf_t m); + +#endif /* arp_h */ diff --git a/itlwm.xcodeproj/project.pbxproj b/itlwm.xcodeproj/project.pbxproj index e907c52e9..43e6ebc2a 100644 --- a/itlwm.xcodeproj/project.pbxproj +++ b/itlwm.xcodeproj/project.pbxproj @@ -317,6 +317,14 @@ 5088ECBF252884AF0068A63D /* libkmod.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5088ECBC252884870068A63D /* libkmod.a */; }; 5088ECC0252884C10068A63D /* libkmod.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5088ECBC252884870068A63D /* libkmod.a */; }; 5088ECC1252884D70068A63D /* libkmod.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5088ECBC252884870068A63D /* libkmod.a */; }; + A5A0C5242A501E6800EF9328 /* arp.c in Sources */ = {isa = PBXBuildFile; fileRef = A5A0C5232A501E6800EF9328 /* arp.c */; }; + A5A0C5252A501E6800EF9328 /* arp.c in Sources */ = {isa = PBXBuildFile; fileRef = A5A0C5232A501E6800EF9328 /* arp.c */; }; + A5A0C5262A501E6800EF9328 /* arp.c in Sources */ = {isa = PBXBuildFile; fileRef = A5A0C5232A501E6800EF9328 /* arp.c */; }; + A5A0C5272A501E6800EF9328 /* arp.c in Sources */ = {isa = PBXBuildFile; fileRef = A5A0C5232A501E6800EF9328 /* arp.c */; }; + A5A0C5282A501E6800EF9328 /* arp.c in Sources */ = {isa = PBXBuildFile; fileRef = A5A0C5232A501E6800EF9328 /* arp.c */; }; + A5A0C5292A501E6800EF9328 /* arp.c in Sources */ = {isa = PBXBuildFile; fileRef = A5A0C5232A501E6800EF9328 /* arp.c */; }; + A5A0C52A2A501E6800EF9328 /* arp.c in Sources */ = {isa = PBXBuildFile; fileRef = A5A0C5232A501E6800EF9328 /* arp.c */; }; + A5A0C52B2A501E6800EF9328 /* arp.c in Sources */ = {isa = PBXBuildFile; fileRef = A5A0C5232A501E6800EF9328 /* arp.c */; }; A5FA2AE428A797B200847103 /* _ifq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FA2AE328A797B200847103 /* _ifq.cpp */; }; A5FA2AE528A797B200847103 /* _ifq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FA2AE328A797B200847103 /* _ifq.cpp */; }; A5FA2AE628A797B200847103 /* _ifq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5FA2AE328A797B200847103 /* _ifq.cpp */; }; @@ -1018,6 +1026,8 @@ A5213EBC27A0C3ED00D7EAB1 /* iwm-8000C-36 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "iwm-8000C-36"; sourceTree = ""; }; A5213EBD27A0C3ED00D7EAB1 /* iwm-9260-46 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "iwm-9260-46"; sourceTree = ""; }; A5213EBE27A0C3ED00D7EAB1 /* iwm-8265-36 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "iwm-8265-36"; sourceTree = ""; }; + A5A0C5222A501E2900EF9328 /* arp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = arp.h; sourceTree = ""; }; + A5A0C5232A501E6800EF9328 /* arp.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = arp.c; sourceTree = ""; }; A5FA2AE328A797B200847103 /* _ifq.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = _ifq.cpp; sourceTree = ""; }; F800DD9A24FBEBF000789320 /* ItlDriverController.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ItlDriverController.hpp; sourceTree = ""; }; F837C91C2724577F00B2C499 /* coex.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = coex.cpp; sourceTree = ""; }; @@ -1584,6 +1594,8 @@ F8BEFA9124CA93E900F6D938 /* _malloc.h */, F8C7EF7B263125DE00BA87B6 /* _netstat.h */, F8BB56172647FDF500F180EC /* _clock.h */, + A5A0C5222A501E2900EF9328 /* arp.h */, + A5A0C5232A501E6800EF9328 /* arp.c */, ); path = sys; sourceTree = ""; @@ -2315,6 +2327,7 @@ 024A085723FCBC6C009FBA6C /* gmac.c in Sources */, F8C2EC592408031A007A9422 /* ieee80211_mira.c in Sources */, 024A083223FCBC6C009FBA6C /* ecb3_enc.c in Sources */, + A5A0C5242A501E6800EF9328 /* arp.c in Sources */, 024A08D023FCEE88009FBA6C /* ctxt.cpp in Sources */, F8D76362244F21BB00DEA040 /* pm.cpp in Sources */, 024A08C023FCD4E2009FBA6C /* utils.cpp in Sources */, @@ -2365,6 +2378,7 @@ 35CBE68E251CB89700435CBC /* rijndael.c in Sources */, 35CBE68F251CB89700435CBC /* ecb3_enc.c in Sources */, 35CBE690251CB89700435CBC /* set_key.c in Sources */, + A5A0C5282A501E6800EF9328 /* arp.c in Sources */, 35CBE691251CB89700435CBC /* cast.c in Sources */, 35CBE692251CB89700435CBC /* michael.c in Sources */, 35CBE693251CB89700435CBC /* sha1.c in Sources */, @@ -2443,6 +2457,7 @@ 35CBE6F8251CB8BF00435CBC /* rijndael.c in Sources */, 35CBE6F9251CB8BF00435CBC /* ecb3_enc.c in Sources */, 35CBE6FA251CB8BF00435CBC /* set_key.c in Sources */, + A5A0C5262A501E6800EF9328 /* arp.c in Sources */, 35CBE6FB251CB8BF00435CBC /* cast.c in Sources */, 35CBE6FC251CB8BF00435CBC /* michael.c in Sources */, 35CBE6FD251CB8BF00435CBC /* sha1.c in Sources */, @@ -2521,6 +2536,7 @@ 35CBE763251CB8CA00435CBC /* rijndael.c in Sources */, 35CBE764251CB8CA00435CBC /* ecb3_enc.c in Sources */, 35CBE765251CB8CA00435CBC /* set_key.c in Sources */, + A5A0C5252A501E6800EF9328 /* arp.c in Sources */, 35CBE766251CB8CA00435CBC /* cast.c in Sources */, 35CBE767251CB8CA00435CBC /* michael.c in Sources */, 35CBE768251CB8CA00435CBC /* sha1.c in Sources */, @@ -2633,6 +2649,7 @@ F897ED0A266EFF93005EE8F7 /* led.cpp in Sources */, F897ED0B266EFF93005EE8F7 /* power.cpp in Sources */, F897ED0C266EFF93005EE8F7 /* scan.cpp in Sources */, + A5A0C5292A501E6800EF9328 /* arp.c in Sources */, F897ED0D266EFF93005EE8F7 /* ItlIwm.cpp in Sources */, F897ED0E266EFF93005EE8F7 /* AirportSTAIOCTL.cpp in Sources */, F897ED0F266EFF93005EE8F7 /* AirportItlwm.cpp in Sources */, @@ -2678,6 +2695,7 @@ F89B6C0D250231E4000F77FF /* rijndael.c in Sources */, F89B6C0E250231E4000F77FF /* ecb3_enc.c in Sources */, F89B6C0F250231E4000F77FF /* set_key.c in Sources */, + A5A0C5272A501E6800EF9328 /* arp.c in Sources */, F89B6C10250231E4000F77FF /* cast.c in Sources */, F89B6C11250231E4000F77FF /* michael.c in Sources */, F89B6C12250231E4000F77FF /* sha1.c in Sources */, @@ -2790,6 +2808,7 @@ F8AE654A285471560085B4CF /* led.cpp in Sources */, F8AE654B285471560085B4CF /* power.cpp in Sources */, F8AE654C285471560085B4CF /* scan.cpp in Sources */, + A5A0C52A2A501E6800EF9328 /* arp.c in Sources */, F8AE654D285471560085B4CF /* ItlIwm.cpp in Sources */, F8AE654E285471560085B4CF /* AirportSTAIOCTL.cpp in Sources */, F8AE654F285471560085B4CF /* AirportItlwm.cpp in Sources */, @@ -2835,6 +2854,7 @@ F8B210DB2A2EC2680043ECBD /* set_key.c in Sources */, F8B210DC2A2EC2680043ECBD /* cast.c in Sources */, F8B210DD2A2EC2680043ECBD /* michael.c in Sources */, + A5A0C52B2A501E6800EF9328 /* arp.c in Sources */, F8B210DE2A2EC2680043ECBD /* sha1.c in Sources */, F8B210DF2A2EC2680043ECBD /* cmac.c in Sources */, F8B210E02A2EC2680043ECBD /* ecb_enc.c in Sources */,