Created
August 28, 2016 15:53
-
-
Save bitdust/039dafe5a3cb7f15101c7884b98509a5 to your computer and use it in GitHub Desktop.
8021xbridge core file.
This file contains 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 characters
/* 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 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 characters
/* 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); | |
} | |
This file contains 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 characters
# | |
# 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)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
modified from njit8021xclient.
works for ALL version of inode.