Created
August 28, 2016 15:53
-
-
Save bitdust/039dafe5a3cb7f15101c7884b98509a5 to your computer and use it in GitHub Desktop.
Revisions
-
bitdust revised this gist
Aug 28, 2016 . No changes.There are no files selected for viewing
-
bitdust created this gist
Aug 28, 2016 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,56 @@ # # Copyright (C) 2006-2008 OpenWrt.org # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. # include $(TOPDIR)/rules.mk PKG_NAME:=8021xbridge PKG_RELEASE:=alpha PKG_VERSION:=0.1 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)-$(PKG_RELEASE) #its not cool in xd. #PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz #PKG_MD5SUM:=1b19ac98ba90e18aff7aeefa431753e2 include $(INCLUDE_DIR)/package.mk define Package/8021xbridge SECTION:=net CATEGORY:=Network TITLE:=802.1X bridge # URL:=http://liuqun.github.com/njit8021xclient # WARMING! the code in liuqun's github can't work in xd. DEPENDS:=+libpcap PKG_BUILD_DEPENDS:=+libopenssl endef define Package/8021xbridge/description 802.1X authentication bridge Support H3C/iNode's private authentication protocol ALL version. endef CONFIGURE_ARGS += \ --program-prefix="8021xbridge-" \ $(NULL) define Build/Prepare mkdir -p $(PKG_BUILD_DIR) $(CP) ./patch/* $(PKG_BUILD_DIR)/ endef define Build/Configure $(call Build/Configure/Default) endef define Package/8021xbridge/install $(MAKE) -C $(PKG_BUILD_DIR) install-exec DESTDIR=$(1) endef define Package/8021xbridge/conffiles /etc/config/8021xbridge.conf endef $(eval $(call BuildPackage,8021xbridge)) This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,188 @@ /* File: auth.c * ------------ * 注:核心函数为Authentication(),由该函数执行801.1X认证 */ int Authentication(const char *DeviceName_1, const char *DeviceName_2); #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <string.h> #include <assert.h> #include <time.h> #include <stdbool.h> #include <pcap.h> #include <unistd.h> #include <sys/wait.h> #include <sys/ioctl.h> #include <sys/socket.h> #include <net/if.h> #include <arpa/inet.h> #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; } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,52 @@ /* File: main.c * ------------ * 802.1X 转发器 */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> /* 子函数声明 */ int Authentication(const char *DeviceName_1, const char *DeviceName_2); /** * 函数:main() * * 检查程序的执行权限,检查命令行参数格式。 * 允许的调用格式包括: * njit-client username password * njit-client username password eth0 * njit-client username password eth1 * 若没有从命令行指定网卡,则默认将使用eth0 */ int main(int argc, char *argv[]) { char *DeviceName_1; char *DeviceName_2; /* 检查当前是否具有root权限 */ if (getuid() != 0) { fprintf(stderr, "抱歉,运行本客户端程序需要root权限\n"); fprintf(stderr, "(RedHat/Fedora下使用su命令切换为root)\n"); fprintf(stderr, "(Ubuntu/Debian下在命令前添加sudo)\n"); exit(-1); } /* 检查命令行参数格式 */ if (argc<2 || argc>3) { fprintf(stderr, "命令行参数错误!\n"); fprintf(stderr, "正确的调用格式例子如下:\n"); fprintf(stderr, " %s eth0[LAN] eth1[WAN]\n", argv[0]); exit(-1); } DeviceName_1 = argv[1]; DeviceName_2 = argv[2]; Authentication(DeviceName_1,DeviceName_2); return (0); }