H3C 802.1x兼容客户端编程简述

来源:互联网 发布:数据漫游打开会怎么样 编辑:程序博客网 时间:2024/04/27 16:44

bool UserSended = false; //用于标记是否发送过密码

bool FirstPacket = true;        //用于标记第一个包是否已发送

bool online = false;        // 是否在线的标记

HWND hOwner = 0;            // 界面的窗体句柄

pcap_t *fp = NULL;      // 网卡设备

 

初始化各种待发送的包,略(包结构参考有关资料)

unsigned char ConnectBuf[60] 请求连接包

unsigned char DisconnectBuf[60] 请求断开包

unsigned char UnknowBufA[67] 我不知道的包

unsigned char PasswordBuf[60] 包含密码、用户名的包

unsigned char KeepBuf[60] 保持连接的包,包含IP、用户名

unsigned char SendUsernameBuf[60] 发送IP、用户名的包

 

//打开网卡,用pcap_findalldevs()获得*device

bool OpenDevice(char* device)

{

    char errbuf[PCAP_ERRBUF_SIZE];

    //抓取的最大包的字节为60 20ms抓取一次

    if ((fp = pcap_open_live(device, 60, 1, 20, errbuf)) == NULL)    

        return false;

    

    return true;

}

 

void CloseDevice()// 关闭网卡

{         

       if (fp != NULL)

       {

              pcap_close(fp);

       }

}

 

void DeviceLoop()// 启动包处理循环

 

{

    if (fp == NULL)

        return;

    pcap_loop(fp, 0, packet_handler, NULL);

}

 

// 分析包并产生相应动作

void packet_handler(unsigned char *param,

const struct pcap_pkthdr *header,

const unsigned char *pkt_data)

{

    // 判断包的类型的标志

    static unsigned char Type[4] = {0x88, 0x8e, 0x01, 0x00}; //协议类型

    static unsigned char SessionFlagA[3] = {0x00, 0x05, 0x01}; //保持连接包

    static unsigned char SessionFlagB[3] = {0x00, 0x05, 0x01};

    static unsigned char Unknow[3] = {0x00, 0x05, 0x02};

    static unsigned char RequestPwdA[3] = {0x00, 0x16, 0x01}; //请求密码包

    static unsigned char RequestPwdB[3] = {0x00, 0x16, 0x04};

    static unsigned char SuccessA[3] = {0x00, 0x04, 0x03}; //成功认证包

    static unsigned char SuccessB[3] = {0x00, 0x04, 0x00};

       static unsigned char ByeA[3] = {0x00, 0x06, 0x04}; //成功断线包

    static unsigned char ByeB[3] = {0x00, 0x07, 0x08};

 

    // 找包的大小为60个字节, 协议为EAPoL的包

    if (header->len == 60 && !memcmp(pkt_data + 0x0c, Type, 4))

    {

        //获得以后我们所要回复的MAC地址,并放入包

        if (FirstPacket)

        {

            FirstPacket = false;

            ChangeDestMac(pkt_data + 0x06);

        }

        

        // 判断是否为对话维持包或需要发送用户名的包(这两种包的特征是相同的)

        if (!memcmp(pkt_data + 0x10, SessionFlagA, 3) && 

            !memcmp(pkt_data + 0x14, SessionFlagB, 3))

        {

                     if (online)//已上线,发送对话维持包

            {

                SetSessionID(pkt_data + 0x13); //配置标识位

                pcap_sendpacket(fp, KeepBuf, 60);

                if (online == false)

                {

                    online = true;

                    ShowOnline(); //上线处理

                }

            }

            else    // 否则就发送用户名

            {

                SetUsernameID(pkt_data + 0x13); //配置标识位

                pcap_sendpacket(fp, SendUsernameBuf, 60); //包含IP、用户名

                UserSended = true;

            }

            return;

        }

 

        // 判断是否为未知类型的包

        if (!memcmp(pkt_data + 0x10, SessionFlagA, 3) &&

            !memcmp(pkt_data + 0x14, Unknow, 3))

        {

            pcap_sendpacket(fp, UnknowBufA, 67); //固定的包

            return;

        }

 

        // 判断是否为需要发送密码的包

        if (!memcmp(pkt_data + 0x10, RequestPwdA, 3) &&

            !memcmp(pkt_data + 0x14, RequestPwdB, 3))

        {

            SetPasswordID(pkt_data + 0x13); //配置标识位

            SetMd5Buf(pkt_data + 0x13, pkt_data + 0x18);//MD5加密

            pcap_sendpacket(fp, PasswordBuf, 60); //发送包含密码和用户名的包

            return;

        }

             

        // 判断是否为认证成功的包 code=3

        if (!memcmp(pkt_data + 0x10, SuccessA, 3) && 

            !memcmp(pkt_data + 0x14, SuccessB, 3))

        {

            if (online == false)

            {

                online = true;

                ShowOnline(); //上线处理

            }

            return;

        }

 

              // failure code=4

              if (!memcmp(pkt_data + 0x10, ByeA, 3))

              {

                     // 判断是否为断线成功的包

                     if(!memcmp(pkt_data + 0x14, ByeB, 3))

                     {

                            if (online == true)

                            {

                                   online = false;

                                   ShowOffline(); //离线处理

 

                                   UserSended = false;    // 重置UserSended

                            }

                            return;

                     }

                     else// 其他离线包

                     {

                            ShowOffline();

                            {//提示出错原因

                                   strMsg.Format("%s", (pkt_data+0x18));

                                   MessageBox(hOwner, strMsg, "连接失败",MB_ICONWARNING);

                            }

                            return;

                     }

              }

       }

}

原创粉丝点击