⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 my802.c

📁 开发了一款模拟802.1x协议的网络编程.是在vc6.0下运行的.
💻 C
字号:
/*本程序参考了mystar的客户端代码,所用到的开发包为libnet-1.1.2和libpcap-1.0.2*/#include "my802.h"#include "global.h"#include "sendpacket.h"#include "myerr.h"/* my802.conf中需要用户填写的信息 */char   *m_name=NULL;         //用户名char   *m_password=NULL;     //密码char   *m_nic=NULL;          //网卡char   *m_fakeAddress=NULL;  //手动设置的IPint     m_uploadIP=-1;       //是否上传IPu_char  m_localMAC[6];       //本机的MAC地址u_char  m_destMAC[6] = {0x01,0x80,0xc2,0x00,0x00,0x03}; //多播MAC地址. u_char  m_localIP[4];        //当前选择的网卡的IP地址/* 当前认证状态----------------------------------------   0:未找到服务器                         1:已找到服务器,未通过用户名认证   2:已通过用户名认证,未通过MD5认证      3:已通过MD5认证,通网成功         -------------------------------------------------------*/static volatile sig_atomic_t m_state=0;//当前认证状态static void sig_intr(int signo);     //do some cleanup work on exit with Ctrl+Cstatic void checkAndSetConfig(void); //configure related parametersint main(int argc, char* argv[]){    libnet_t                 *l=NULL;    u_int32_t                 l_ip;    char                      l_errbuf[LIBNET_ERRBUF_SIZE];    struct libnet_ether_addr *l_ether_addr;    pcap_t             *p=NULL;    int                 p_fd;    fd_set              read_set;    char                filter_buf[256];    struct bpf_program  filter_code;    u_int32_t           p_netaddr,p_netmask;    struct pcap_pkthdr *pkt_hdr;    const u_char       *pkt_data;    char                p_errbuf[PCAP_ERRBUF_SIZE];    sigset_t        sigset_full,sigset_zero;    struct timespec timeout;    int packetCount_SentFindServer=0;    int packetCount_SentName=0;    int packetCount_SentPassword=0;    int packetCount_Success=0;    checkAndSetConfig();//从my802.conf文件中读取用户配置信息        //对libnet函数库进行初始化,发送数据报接口类型为LIBNET_LINE,    //设备指定为m_nic代表的网卡,l返回的是设备描述符    if((l=libnet_init(LIBNET_LINK, m_nic,l_errbuf))==NULL)		err_quit("libnet_init: %s\n", l_errbuf);    if((p=pcap_open_live(m_nic,65536,0, 500, p_errbuf))==NULL)    { //获得用于捕获网络数据包的数据包捕获描述字,m_nic是打开的网卡,      //捕获最大字节数是65536,超时时间为500毫秒		err_msg("pcap_open_live: %s\n",p_errbuf);		goto err1; 	}    //p_fd保存被打开文件的文件描述字号码    p_fd=pcap_fileno(p); //we can pselect() it in the following code.    if((l_ether_addr=libnet_get_hwaddr(l))==NULL)    { //根据设备描述符得到MAC地址存入l_ether_addr		err_msg("unable to get local mac address :%s\n",libnet_geterror(l));		goto err2;	}    memcpy(m_localMAC,l_ether_addr,sizeof(m_localMAC));    if(m_fakeAddress==NULL)    {		if((l_ip=libnet_get_ipaddr4(l))==-1)		{ //根据设备描述符得到IP地址存入l_ip			err_msg("unable to get ip address--ingored... :%s\n",libnet_geterror(l));			l_ip=0; 		}		memcpy(m_localIP,&l_ip,sizeof(m_localIP));    }    else {	} //或者已经在前面的checkandSetConfig()中被初始化	if(pcap_lookupnet(m_nic,&p_netaddr,&p_netmask,p_errbuf)==-1)    { //获得m_nic指定的网卡的网络号和掩码		err_msg("unable to get netmask--igored... %s\n",p_errbuf);		p_netmask=0;	}    //将m_localMAC[n]中的内容填入filter_buf    snprintf(filter_buf,sizeof(filter_buf),FILTER_STR, m_localMAC[0],m_localMAC[1],	     m_localMAC[2],m_localMAC[3],m_localMAC[4],m_localMAC[5]);    //将filter_buf中的字符串编译到过虑程序中    if(pcap_compile(p, &filter_code,filter_buf, 0, p_netmask)==-1)    {		err_msg("pcap_compile(): %s", pcap_geterr(p));		goto err2;	}    //指定一个过虑程序    if(pcap_setfilter(p, &filter_code)==-1)    {		err_msg("pcap_setfilter(): %s", pcap_geterr(p));		goto err2; 	}    pcap_freecode(&filter_code); // avoid  memory-leak    (void)signal(SIGINT,sig_intr);  //We can exit with Ctrl+C    (void)sigfillset(&sigset_full);    (void)sigprocmask(SIG_BLOCK,&sigset_full,NULL); //block all signals.    //search for the serverbeginAuthentication:    m_state=0;    (void)SendLoginPacket(l); //发送登录包到服务器    packetCount_SentFindServer=1;    packetCount_SentName=0;    packetCount_SentPassword=0;    packetCount_Success=0;    while(1)          {		(void)sigfillset(&sigset_full);		(void)sigdelset(&sigset_full,SIGINT);		FD_ZERO(&read_set);//将read_set描述符集清空		FD_SET(p_fd, &read_set);//增加一个新的描述符		timeout.tv_sec =1;		timeout.tv_nsec =0; // 1 second		//wait with all signals(except SIGINT) blocked.		switch ( pselect(p_fd+1,&read_set,NULL,NULL,&timeout,&sigset_full) )		{		case -1: //Normally, this case should not happen since sig_intr() never returns!			goto err2;		case 0:  //timed out			switch(m_state)			{			case 0:				if(++packetCount_SentFindServer>3)				{ 					puts("Restarting authenticaton!");					goto beginAuthentication;				}				(void)SendLoginPacket(l);				continue; //jump to next loop of while(1) to receive next packet			case 1:				if(++packetCount_SentName>3)				{					puts("Restarting authenticaton!");					goto beginAuthentication;				}				(void)SendNamePacket(l, pkt_data);				continue;			case 2:				if(++packetCount_SentPassword>3)				{					puts("Restarting authenticaton!");					goto beginAuthentication;				}				(void)SendPasswordPacket(l, pkt_data);				continue;			default:                if(++packetCount_Success >= 45)				{					puts("Restarting authenticaton!");					goto beginAuthentication;				}				continue;			}		}		//Here return value of pselect must be 1		if((pcap_next_ex(p,&pkt_hdr,&pkt_data))!=1)			continue;		PPKTHDR pbuf = (PPKTHDR)pkt_data;		//received a packet successfully. for convenience, 		//SUPPOSE it's the RIGHT packet!! but maybe WRONG!!		//for example, we have NEVER vefified the length of packet, 		//fancying the packet's length is 0x11 ?!		switch( pbuf->Code )  //分析EAP包类型		{		case EAP_REQUEST:       //表示请求 			switch( pbuf->EapType )			{			case EAP_IDENTIFY:    //请求用户名等				if(m_state==0)                 {					m_state=1;				    fputs("@@ Server found, requesting user name...\n",stdout);				    (void)SendNamePacket(l, pkt_data);                }                else if(m_state==3)                {					packetCount_Success = 0;				    (void)SendKeeponlinePacket(l,pkt_data);                }			    break;			case EAP_MD5:   //请求密码				if(m_state!=1)					continue;				m_state=2;				fputs("@@ User name valid, requesting password...\n",stdout);				(void)SendPasswordPacket(l, pkt_data);				break;			}			break;		case EAP_SUCCESS:         //认证成功			if(m_state!=2)				continue;			m_state=3;			fputs("@@ Password valid, authentication SUCCESS!!! :)\n",stdout);			//unblock SIGINT, so we can exit with Ctrl+C			(void)sigemptyset(&sigset_zero);			(void)sigaddset(&sigset_zero,SIGINT);			(void)sigprocmask(SIG_UNBLOCK,&sigset_zero,NULL);			break;		case EAP_FAILURE:        //认证失败(用户名或密码错误/不在上网时段内/重复上网等)			m_state=0;			if(pbuf->EapType == EAP_LOGOUT)				fputs("@@ Logout SUCCESS!!! :)\n",stdout);			else				fprintf(stdout,"@@ Authenticaton failed!!! :(%s\n",pkt_data+0x18);			goto beginAuthentication;			break; //should never come here		case EAP_OTHER:			fputs("@@ Received some extra information!!! :)\n",stdout);			break;		}// end switch    }// end whiledone:    pcap_close(p); libnet_destroy(l);    return 0;err2:    pcap_close(p);err1:    libnet_destroy(l);    return 1;}static void checkAndSetConfig(void){//从my802.conf文件中读用户配置信息    FILE *fp;    char  buf[4096];    char *p;    int   i,len;	int   uploadIP;    static char name[32];    static char password[32];    static char nic[32];    static char fakeAddress[32];     //the check and anylysis against my802.conf  *don't*  work perfectly.    //this may be improved in the later version.    if( (fp=fopen("my802.conf","r"))==NULL )		err_quit("cannot open file my802.conf ! check it.\n");	    while(fgets(buf,sizeof(buf),fp)!=NULL)    {     	if( (buf[0]=='#') || (buf[0]=='\n') )			continue;     	len=strlen(buf); 		if(buf[len-1]=='\n')			buf[len-1]='\0';     	if( ( (p=strchr(buf,'=')) == NULL) || (p==buf) )			continue;     	//the code above doesn't detect ALL the errors!! it should be improved in future.     	*p++='\0';     	for(i=0; i<strlen(buf); i++) 			buf[i]=tolower(buf[i]);     	if(strcmp(buf,"name")==0) //得到用户名		{ 			strncpy(name,p,sizeof(name)-1); name[sizeof(name)-1]=0;  m_name=name; 		}     	else if(strcmp(buf,"password")==0) //得到口令		{			strncpy(password,p,sizeof(password)-1); password[sizeof(password)-1]=0;			m_password=password;		}     	else if(strcmp(buf,"uploadip")==0) //得到上传IP地址		{			uploadIP=atoi(p);			m_uploadIP=uploadIP; 		}     	else if(strcmp(buf,"nic")==0) //得到网卡		{			for(i=0; i<strlen(p); i++)				p[i]=tolower(p[i]);			strncpy(nic,p,sizeof(nic)-1); 			nic[sizeof(nic)-1]=0; 			m_nic=nic;		}       	else if(strcmp(buf,"fakeaddress")==0) //得到手动IP地址		{			strncpy(fakeAddress,p,sizeof(fakeAddress)-1);			fakeAddress[sizeof(fakeAddress)-1]=0;			if( inet_pton(AF_INET,fakeAddress,m_localIP)<=0 )				err_msg("invalid fakeAddress found in my802.conf, ignored...\n");			else m_fakeAddress=fakeAddress;		}     	else continue;    }    if(ferror(fp))		err_quit("cannot read my802.conf ! check it.\n");    fclose(fp);    if((m_name==NULL)||(m_name[0]==0))		err_quit("invalid name found in my802.conf!\n");    if((m_password==NULL)||(m_password[0]==0)) 		err_quit("invalid password found in my802.conf!\n");    if((m_uploadIP<0)||(m_uploadIP>1))		err_quit("invalid uploadIP found in my802.conf!\n");    if( (m_nic==NULL) || (strcmp(m_nic,"")==0) ||  (strcmp(m_nic,"any")==0) )		err_quit("invalid nic found in my802.conf!\n");//  printf("m_name=%s\n",m_name);//  printf("m_password=%s\n",m_password);//  printf("m_nic=%s\n",m_nic);//  printf("m_uploadIP=%d\n",m_uploadIP);//  printf("m_fakeAddress=%s\n",m_fakeAddress);}static void sig_intr(int signo) {//临关闭前的清理工作    libnet_t *l=NULL;    char      l_errbuf[LIBNET_ERRBUF_SIZE];    if(m_state==3)    {		if((l=libnet_init(LIBNET_LINK, m_nic,l_errbuf))==NULL)			_exit(0);		(void)SendLogoutPacket(l);		libnet_destroy(l);    }    _exit(0);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -