前天,802.1x的上网认证过程改变了,前两个版本已经不能使用。下面是版本1.2的代码。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include"md5.c"
#define Eap_Pack_Len 67
#define EAP_REQUEST_LEN 60
#define NAMESIZE 40
#define EAP_PWD_ERR_LEN 146
#define EAP_NAME_ERR_LEN 63
//#define EAP_MAC_ERR_LEN
const char
*lock_file="/tmp/802.1x_EAP_Client_lock-file_DW";//锁文件
u_char
mac_client[6],base[32],EAP_Pack[Eap_Pack_Len],user_name[NAMESIZE];//EAP_Pack为要发送给服务噐的数据,user_name为以后禁止回显准备
u_char mac_server[6]={0x01,0x80,0xc2,0x00,0x00,0x03};
struct pcap_pkthdr *header;
u_char *pkt_data;
unsigned int ID;
const char *version="Version:1.2_20090805";
const char VERSION_802_1X[16]="CH V2.40-F0316";
const char KEY[]="HuaWei3COM1X";
struct ifreq req;
char network_name[30];
pcap_t *fp;
struct sigaction act;
int sockfd;
int file_desc,flag_sig_pro=1;
int get_mac_client()
{
//int sockfd;
//struct ifreq req;
sockfd=socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ALL));
if(sockfd<0)
return 1;
if(-1==ioctl(sockfd,SIOCGIFHWADDR,&req))
{
close(sockfd);
return 1;
}
memcpy(mac_client,req.ifr_hwaddr.sa_data,6);
//close(sockfd);
return 0;
}
//md5
int get_md5_digest(u_char EAP_Pack[],const char *str,unsigned int
len)//对字符串进行16位md5加密
{
md5_state_t state;
md5_byte_t digest[16];
md5_init(&state);
md5_append(&state,(const md5_byte_t
*)str,len);
md5_finish(&state,digest);
memcpy(EAP_Pack,digest,16);
return 0;
}
int Fill_Eapol_Start(u_char EAP_Pack[])
{
EAP_Pack[15]=0x01;
return 0;
}
int Fill_EAP_Name(u_char EAP_Pack[],char user_name[])
{
EAP_Pack[15]=0x00;EAP_Pack[16]=0x00;EAP_Pack[17]=0x15;EAP_Pack[18]=0x02;
EAP_Pack[19]=ID;EAP_Pack[20]=0x00;EAP_Pack[21]=0x15;EAP_Pack[22]=0x01;
EAP_Pack[23]=0x15;EAP_Pack[24]=0x04;
memset(EAP_Pack+25,0x00,Eap_Pack_Len-25);
memcpy(EAP_Pack+29,user_name,strlen(user_name));
return 0;
}
int Fill_Eap_PWD(u_char EAP_Pack[],u_char pkt_data[],char
user_name[],char user_pwd[])
{
int
pwdlen=strlen(user_pwd);
u_char *pwdstring=(u_char
*)malloc(1+pwdlen+16); pwdstring[0]=*(pkt_data+0x13);
memcpy(pwdstring+1,user_pwd,pwdlen);
memcpy(pwdstring+1+pwdlen,pkt_data+0x18,16);
get_md5_digest(EAP_Pack+24,pwdstring,1+pwdlen+16);
EAP_Pack[15]=0x00;EAP_Pack[16]=0x00;EAP_Pack[17]=0x20;EAP_Pack[18]=0x02;
EAP_Pack[19]=ID;EAP_Pack[20]=0x00;EAP_Pack[21]=0x20;EAP_Pack[22]=0x04;
EAP_Pack[23]=0x10;
memcpy(EAP_Pack+40,user_name,strlen(user_name));
free(pwdstring);
return 0;
}
void XOR(uint8_t data[], unsigned dlen, const char key[], unsigned
klen)
{
unsigned
int i,j;
//先按正序处理一遍
for (i=0;
i
data[i] ^= key[i%klen];
//
再按倒序处理第二遍
for
(i=dlen-1,j=0; j
data[i] ^= key[j%klen];
}
int Fill_Client_Version(int i)
{
uint32_t
random;
char
RandomKey[8+1];
random =
(uint32_t)
time(NULL); // 注:可以选任意32位整数
sprintf(RandomKey, "%08x", random);// 生成RandomKey[]字符串
//
第一轮异或运算,以RandomKey为密钥加密16字节
memcpy(EAP_Pack+i, VERSION_802_1X, sizeof(VERSION_802_1X));
XOR(EAP_Pack+i, 16, RandomKey, strlen(RandomKey));
//
此16字节加上4字节的random,组成总计20字节
random =
htonl(random); // (需调整为网络字节序)
memcpy(EAP_Pack+i+16, &random, 4);
//
第二轮异或运算,以KEY为密钥加密前面生成的20字节
XOR(EAP_Pack+i, 20, KEY, strlen(KEY));
return
0;
}
int Fill_EAP_Notification()
{
EAP_Pack[15]=0x00;EAP_Pack[16]=0x00;EAP_Pack[17]=0x31;EAP_Pack[18]=0x02;
EAP_Pack[19]=ID;EAP_Pack[20]=0x00;EAP_Pack[21]=0x31;EAP_Pack[22]=0x02;
EAP_Pack[23]=0x01;EAP_Pack[24]=0x16;
Fill_Client_Version(25);
EAP_Pack[45]=0x02;EAP_Pack[46]=0x16;EAP_Pack[47]=0x3a;EAP_Pack[48]=0x71;
EAP_Pack[49]=0x38;EAP_Pack[50]=0x01;EAP_Pack[51]=0x0b;EAP_Pack[52]=0x3b;
EAP_Pack[53]=0x7e;EAP_Pack[54]=0x3d;EAP_Pack[55]=0x26;EAP_Pack[56]=0x7c;
EAP_Pack[57]=0x7c;EAP_Pack[58]=0x17;EAP_Pack[59]=0x0b;EAP_Pack[60]=0x46;
EAP_Pack[61]=0x08;EAP_Pack[62]=0x32;EAP_Pack[63]=0x32;EAP_Pack[64]=0x08;
EAP_Pack[65]=0x46;EAP_Pack[66]=0x0b;
return 0;
}
int Fill_EAP_After_Suc()
{
char
ip[20];
int
swap=0,k=0,j=0,len;
EAP_Pack[19]=ID;
ioctl(sockfd,SIOCGIFADDR,&req);
sprintf(ip,"%s",inet_ntoa(((struct sockaddr_in
*)&req.ifr_ifru.ifru_addr)->sin_addr));
len=strlen(ip);
for(j=0;j
{
if('.'==ip[j])
{
EAP_Pack[25+k]=swap;
swap=0;