📄 my802.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 + -