mirror of
https://github.com/OpenIntelWireless/itlwm.git
synced 2024-11-25 13:56:13 +00:00
111 lines
4.0 KiB
C++
111 lines
4.0 KiB
C++
//
|
|
// AirportItlwmEthernetInterface.cpp
|
|
// AirportItlwm-Sonoma
|
|
//
|
|
// Created by qcwap on 2023/6/27.
|
|
// Copyright © 2023 钟先耀. All rights reserved.
|
|
//
|
|
|
|
#include "AirportItlwmEthernetInterface.hpp"
|
|
|
|
#include <sys/_if_ether.h>
|
|
#include <net80211/ieee80211_var.h>
|
|
|
|
#define super IOEthernetInterface
|
|
OSDefineMetaClassAndStructors(AirportItlwmEthernetInterface, IOEthernetInterface);
|
|
|
|
bool AirportItlwmEthernetInterface::
|
|
initWithSkywalkInterfaceAndProvider(IONetworkController *controller, IO80211SkywalkInterface *interface)
|
|
{
|
|
bool ret = super::init(controller);
|
|
if (ret)
|
|
this->interface = interface;
|
|
this->isAttach = false;
|
|
return ret;
|
|
}
|
|
|
|
IOReturn AirportItlwmEthernetInterface::
|
|
attachToDataLinkLayer( IOOptionBits options, void *parameter )
|
|
{
|
|
XYLog("%s\n", __FUNCTION__);
|
|
char infName[IFNAMSIZ];
|
|
IOReturn ret = super::attachToDataLinkLayer(options, parameter);
|
|
if (ret == kIOReturnSuccess && interface) {
|
|
UInt8 builtIn = 0;
|
|
IOEthernetAddress addr;
|
|
interface->setProperty("built-in", OSData::withBytes(&builtIn, sizeof(builtIn)));
|
|
snprintf(infName, sizeof(infName), "%s%u", ifnet_name(getIfnet()), ifnet_unit(getIfnet()));
|
|
interface->setProperty("IOInterfaceName", OSString::withCString(infName));
|
|
interface->setProperty(kIOInterfaceUnit, OSNumber::withNumber(ifnet_unit(getIfnet()), 8));
|
|
interface->setProperty(kIOInterfaceNamePrefix, OSString::withCString(ifnet_name(getIfnet())));
|
|
if (OSDynamicCast(IOEthernetController, getController())->getHardwareAddress(&addr) == kIOReturnSuccess)
|
|
setProperty(kIOMACAddress, (void *) &addr,
|
|
kIOEthernetAddressSize);
|
|
interface->registerService();
|
|
interface->prepareBSDInterface(getIfnet(), 0);
|
|
// ret = bpf_attach(getIfnet(), DLT_RAW, 0x48, &AirportItlwmEthernetInterface::bpfOutputPacket, &AirportItlwmEthernetInterface::bpfTap);
|
|
}
|
|
isAttach = true;
|
|
return ret;
|
|
}
|
|
|
|
void AirportItlwmEthernetInterface::
|
|
detachFromDataLinkLayer(IOOptionBits options, void *parameter)
|
|
{
|
|
super::detachFromDataLinkLayer(options, parameter);
|
|
isAttach = false;
|
|
}
|
|
|
|
/**
|
|
Add another hack to fake that the provider is IOSkywalkNetworkInterface, to avoid skywalkfamily instance cast panic.
|
|
*/
|
|
IOService *AirportItlwmEthernetInterface::
|
|
getProvider() const
|
|
{
|
|
return isAttach ? this->interface : super::getProvider();
|
|
}
|
|
|
|
errno_t AirportItlwmEthernetInterface::
|
|
bpfOutputPacket(ifnet_t interface, u_int32_t data_link_type, mbuf_t packet)
|
|
{
|
|
XYLog("%s data_link_type: %d\n", __FUNCTION__, data_link_type);
|
|
AirportItlwmEthernetInterface *networkInterface = (AirportItlwmEthernetInterface *)ifnet_softc(interface);
|
|
return networkInterface->enqueueOutputPacket(packet);
|
|
}
|
|
|
|
errno_t AirportItlwmEthernetInterface::
|
|
bpfTap(ifnet_t interface, u_int32_t data_link_type, bpf_tap_mode direction)
|
|
{
|
|
XYLog("%s data_link_type: %d direction: %d\n", __FUNCTION__, data_link_type, direction);
|
|
return 0;
|
|
}
|
|
|
|
bool AirportItlwmEthernetInterface::
|
|
setLinkState(IO80211LinkState state)
|
|
{
|
|
if (state == kIO80211NetworkLinkUp) {
|
|
ifnet_set_flags(getIfnet(), ifnet_flags(getIfnet()) | (IFF_UP | IFF_RUNNING), (IFF_UP | IFF_RUNNING));
|
|
} else {
|
|
ifnet_set_flags(getIfnet(), ifnet_flags(getIfnet()) & ~(IFF_UP | IFF_RUNNING), 0);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
extern const char* hexdump(uint8_t *buf, size_t len);
|
|
|
|
UInt32 AirportItlwmEthernetInterface::
|
|
inputPacket(mbuf_t packet, UInt32 length, IOOptionBits options, void *param)
|
|
{
|
|
ether_header_t *eh;
|
|
size_t len = mbuf_len(packet);
|
|
|
|
eh = (ether_header_t *)mbuf_data(packet);
|
|
if (len >= sizeof(ether_header_t) && eh->ether_type == htons(ETHERTYPE_PAE)) { // EAPOL packet
|
|
const char* dump = hexdump((uint8_t*)mbuf_data(packet), len);
|
|
XYLog("input EAPOL packet, len: %zu, data: %s\n", len, dump ? dump : "Failed to allocate memory");
|
|
if (dump)
|
|
IOFree((void*)dump, 3 * len + 1);
|
|
}
|
|
return IOEthernetInterface::inputPacket(packet, length, options, param);
|
|
}
|