/* File: auth.c * ------------ * 注:核心函数为Authentication(),由该函数执行801.1X认证 */ int Authentication(const char *DeviceName_1, const char *DeviceName_2); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "debug.h" const uint8_t BroadcastAddr[6] = {0xff,0xff,0xff,0xff,0xff,0xff}; // 广播MAC地址 const uint8_t MultcastAddr[6] = {0x01,0x80,0xc2,0x00,0x00,0x03}; // 多播MAC地址 static void GetMacFromDevice(uint8_t mac[6], const char *devicename); // From fillmd5.c extern void FillMD5Area(uint8_t digest[], uint8_t id, const char passwd[], const uint8_t srcMD5[]); // From ip.c extern void GetIpFromDevice(uint8_t ip[4], const char DeviceName[]); /** * 函数:Authentication() * * 使用以太网进行802.1X认证(802.1X Authentication) * 该函数将不断循环,转发802.1X认证数据包 */ int Authentication(const char *DeviceName_1, const char *DeviceName_2) { char errbuf_1[PCAP_ERRBUF_SIZE]; pcap_t *adhandle_1; // adapter handle uint8_t MAC_1[6]; char FilterStr_1[100]; struct bpf_program fcode_1; char errbuf_2[PCAP_ERRBUF_SIZE]; pcap_t *adhandle_2; // adapter handle uint8_t MAC_2[6]; char FilterStr_2[100]; struct bpf_program fcode_2; uint8_t MAC_client[6] = {0x00,0x00,0x00,0x00,0x00,0x00}; uint8_t MAC_switch[6] = {0x00,0x00,0x00,0x00,0x00,0x00}; const int DefaultTimeout=500;//设置接收超时参数,单位ms // NOTE: 这里没有检查网线是否已插好,网线插口可能接触不良 /* 打开适配器(网卡) */ adhandle_1 = pcap_open_live(DeviceName_1,65536,1,DefaultTimeout,errbuf_1); if (adhandle_1==NULL) { fprintf(stderr, "%s\n", errbuf_1); exit(-1); } adhandle_2 = pcap_open_live(DeviceName_2,65536,1,DefaultTimeout,errbuf_2); if (adhandle_2==NULL) { fprintf(stderr, "%s\n", errbuf_2); exit(-1); } /* 查询本机MAC地址 */ GetMacFromDevice(MAC_1, DeviceName_1); GetMacFromDevice(MAC_2, DeviceName_2); /* * 设置过滤器: * 初始情况下只捕获发往本机的802.1X认证会话,不接收多播信息(避免误捕获其他客户端发出的多播信息) * 进入循环体前可以重设过滤器,那时再开始接收多播信息 */ sprintf(FilterStr_1, "(ether proto 0x888e)"); pcap_compile(adhandle_1, &fcode_1, FilterStr_1, 1, 0xff); pcap_setfilter(adhandle_1, &fcode_1); sprintf(FilterStr_2, "(ether proto 0x888e)"); pcap_compile(adhandle_2, &fcode_2, FilterStr_2, 1, 0xff); pcap_setfilter(adhandle_2, &fcode_2); int retcode_1; int retcode_2; struct pcap_pkthdr *header_1 = NULL; const uint8_t *captured_1 = NULL; struct pcap_pkthdr *header_2 = NULL; const uint8_t *captured_2 = NULL; uint8_t sendbuffer_1[500]; uint8_t sendbuffer_2[500]; while(1) { retcode_1 = pcap_next_ex(adhandle_1, &header_1, &captured_1); if (retcode_1==1) { memcpy(sendbuffer_1, captured_1, header_1->len); memcpy(sendbuffer_1+6, MAC_2, 6); // replace source addr if(captured_1[15] == 0x01) { // start. memcpy(MAC_client, captured_1+6, 6); printf("set MAC_client. [%2x:%2x:%2x:%2x:%2x:%2x]\n",MAC_client[0],MAC_client[1],MAC_client[2],MAC_client[3],MAC_client[4],MAC_client[5]); } else { if (MAC_switch[0] == 0x00 && MAC_switch[1] == 0x00 && MAC_switch[2] == 0x00 && MAC_switch[3] == 0x00 && MAC_switch[4] == 0x00 && MAC_switch[5] == 0x00) { printf("send Multcast to WAN.\n"); memcpy(sendbuffer_1, MultcastAddr, 6); } else { memcpy(sendbuffer_1, MAC_switch, 6); } } pcap_sendpacket(adhandle_2, sendbuffer_1, header_1->len); } retcode_2 = pcap_next_ex(adhandle_2, &header_2, &captured_2); if (retcode_2==1) { memcpy(sendbuffer_2, captured_2, header_2->len); memcpy(sendbuffer_2+6, MAC_1, 6); if(captured_2[0] == MAC_2[0] && captured_2[1] == MAC_2[1] && captured_2[2] == MAC_2[2] && captured_2[3] == MAC_2[3] && captured_2[4] == MAC_2[4] && captured_2[5] == MAC_2[5]) { memcpy(MAC_switch,captured_2+6,6); printf("set MAC_switch [%2x:%2x:%2x:%2x:%2x:%2x]\n",MAC_switch[0],MAC_switch[1],MAC_switch[2],MAC_switch[3],MAC_switch[4],MAC_switch[5]); } if (MAC_client[0] == 0x00 && MAC_client[1] == 0x00 && MAC_client[2] == 0x00 && MAC_client[3] == 0x00 && MAC_client[4] == 0x00 && MAC_client[5] == 0x00) { printf("send Multcast to LAN.\n"); memcpy(sendbuffer_2, MultcastAddr, 6); } else { memcpy(sendbuffer_2, MAC_client, 6); } pcap_sendpacket(adhandle_1, sendbuffer_2, header_2->len); } } } static void GetMacFromDevice(uint8_t mac[6], const char *devicename) { int fd; int err; struct ifreq ifr; fd = socket(PF_PACKET, SOCK_RAW, htons(0x0806)); assert(fd != -1); assert(strlen(devicename) < IFNAMSIZ); strncpy(ifr.ifr_name, devicename, IFNAMSIZ); ifr.ifr_addr.sa_family = AF_INET; err = ioctl(fd, SIOCGIFHWADDR, &ifr); assert(err != -1); memcpy(mac, ifr.ifr_hwaddr.sa_data, 6); err = close(fd); assert(err != -1); return; }