0
点赞
收藏
分享

微信扫一扫

Packet32 打开网卡设备/写帧/读帧【帧:以太网格式】

_鱼与渔_ 2022-04-29 阅读 123

网卡设备ID格式为:

\Device\NPF_{网卡名称},网卡名称可以通过 WINAPI “GetAdaptersInfo” 函数来获取,当然人们仍旧可以使用 Packet32 提供的 “PacketGetAdapterNames” 函数来获取,每个网卡之间使用 “/x0” 来做分隔符,结束标志位为某端两个“\x0”,用法简单就不再本文过多描述了。

PacketOpenAdapter 打开网卡设备

    inline static LPADAPTER ethernet_open_device(const std::string& id) {
        if (id.empty()) {
            return NULL;
        }

        LPADAPTER p = PacketOpenAdapter(id.data());
        if (!p) {
            PacketCloseAdapter(p);
            return NULL;
        }

        if (!PacketSetHwFilter(p, NDIS_PACKET_TYPE_PROMISCUOUS)) {
            PacketCloseAdapter(p);
            return NULL;
        }

        if (!PacketSetBuff(p, 16 * 1024 * 1024)) {
            PacketCloseAdapter(p);
            return NULL;
        }

        if (!PacketSetReadTimeout(p, INFINITE)) {
            PacketCloseAdapter(p);
            return NULL;
        }
        return p;
    }
    

 PacketReceivePacket 读入网卡数据(一次读入多个以太网帧)

    inline static bool ethernet_loopback(const std::string& device, const std::string& id) {
        ETHERNET_NIC = ethernet_open_device(id);
        if (!ETHERNET_NIC) {
            return false;
        }
        else {
            ethernet_init();
        }

        LPPACKET PACKET = PacketAllocatePacket();
        while (!ETHERNET_FIN) {
            LPADAPTER NIC = ETHERNET_NIC;
            if (!NIC) {
                break;
            }

            static CHAR BUFF[65536];
            PacketInitPacket(PACKET, BUFF, sizeof(BUFF));
            if (!PacketReceivePacket(NIC, PACKET, TRUE)) {
                break;
            }

            CHAR* PKG = BUFF;
            while (PACKET->ulBytesReceived > 0) {
                struct bpf_hdr* HDR = (struct bpf_hdr*)PKG;
                int LEN = HDR->bh_datalen;
                do {
                    struct eth_hdr* ETH = (struct eth_hdr*)(PKG + HDR->bh_hdrlen);
                    int PROTO = ntohs(ETH->proto);
                    if (PROTO == ETHTYPE_IP) {
                        if (MAC2I64(ETH->dst) != MAC2I64(ETHERNET_MAC)) {
                            break;
                        }
                    }

                    std::shared_ptr<char> FRM = std::shared_ptr<char>((char*)malloc(LEN), free);
                    memcpy(FRM.get(), ETH, LEN);
                    ETHERNET_CONTEXT_.post(std::bind(ethernet_input, ETH, PROTO, FRM, LEN));
                } while (0);
                LEN = Packet_WORDALIGN(HDR->bh_hdrlen + HDR->bh_datalen);
                PKG += LEN;
                PACKET->ulBytesReceived -= LEN;
            }
        }
        PacketFreePacket(PACKET);
        ethernet_release();
        return true;
    }

PacketSendPacket  写入网卡数据,MAX: 1514 BYTE

    int ethernet_output(struct eth_hdr* eth, int len) {
        static const INT32 MTU = 1514;

        if (!eth || len < sizeof(*eth)) {
            return -1;
        }

        LPADAPTER NIC = ETHERNET_NIC;
        if (!NIC) {
            return -1;
        }

        int ERR = -1;
        LPPACKET PACKET = PacketAllocatePacket();
        if (PACKET) {
            CHAR* DATA = (CHAR*)eth;
            INT32 SIZE = (INT32)len;
            while (SIZE > 0) {
                INT32 BT = min(SIZE, MTU);
                PacketInitPacket(PACKET, DATA, BT);
                if (!PacketSendPacket(NIC, PACKET, TRUE)) {
                    break;
                }
                SIZE -= BT;
                DATA += BT;
            }
            ERR = 0;
        }
        PacketFreePacket(PACKET);
        return ERR;
    }

 

 

举报

相关推荐

0 条评论