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

📄 mystar.c

📁 用socket写的802.1x程序代码
💻 C
字号:

#include "globle.h"
#include "sendpacket.h"
#include "blog.h"
#include <sys/socket.h>

char   *m_name = NULL;
char   *m_password = NULL;
static int  m_echoInterval = -1;
static int  m_intelligentReconnect = -1;


unsigned char   m_localMAC[6];
unsigned char   m_destMAC[6];

/* 当前认证状态
   0:未找到服务器                      1:已找到服务器,未通过用户名认证
   2:已通过用户名认证,未通过MD5认证   3:已通过MD5认证,通网成功         */
static volatile sig_atomic_t  m_state=0;
ULONG_BYTEARRAY m_serialNo;    //序列号,收到第一个有效的Authentication-Success-packet时初始化
ULONG_BYTEARRAY m_key;          //密码加密键值,在main()函数开始时初始化

static void sig_intr(int signo);
int cardif_init(struct interface_data *thisint);



int cardif_init(struct interface_data *thisint)
{
	struct ifreq ifr;
	int sockopts,sockerr,retval;
	thisint->username=m_name;
	thisint->password=m_password;
	thisint->sockInt = socket(PF_PACKET,SOCK_RAW,htons(ETH_P_EAPOL));
	if(thisint->sockInt<0)
	{
		printf("couldn't initialize raw socket");
		return -1;
	}
	
	strcpy((char *)&ifr.ifr_name,"eth0");
	retval = ioctl(thisint->sockInt,SIOCGIFINDEX,&ifr);
	if(retval<0)
	{
		printf("error getting interface");
		return -2;
	}
	
	thisint->sll.sll_family = PF_PACKET;
	thisint->sll.sll_ifindex = ifr.ifr_ifindex;
	thisint->sll.sll_protocol = htons(ETH_P_EAPOL);
	
	retval = bind(thisint->sockInt,(const struct sockaddr *)&thisint->sll,
	         sizeof(struct sockaddr_ll));
	if(retval<0)
	{
		printf("error binding raw socket to interface");
		return -2;
	}
	
	retval = ioctl(thisint->sockInt,SIOCGIFHWADDR,&ifr);
	if(retval<0)
	{
		printf("error getting hardware address");
		return -3;
	}
	
	memcpy((char *)&thisint->source_mac[0],(char *)&ifr.ifr_hwaddr.sa_data[0],6);
	
	sockopts = fcntl(thisint->sockInt,F_GETFL,0);
	if(sockopts<0)
	{
		printf("eror getting socket options");
		return -3;
	}
	sockerr = fcntl(thisint->sockInt,F_SETFL,sockopts | O_NONBLOCK);
	if(sockerr<0)
	{
		printf("error setting options for interface");
		return -3;
	}
	
        return 0;
}
        
        
        
        
        
        

int main(int argc, char *argv[])
{       
       m_name=argv[1];
	m_password=argv[2];
	int retval;
	int p_fd;
	fd_set  read_set;
	u_int16_t  offset;
	struct interface_data *intcur = NULL;
	const u_char   *pkt_data;
	int      msglen;
	char     msgbuf[256];
	char     *pmsgbuf;
	ULONG_BYTEARRAY  uTemp;
	int      isFirstPacketFromServer = 1;
	sigset_t  sigset_full,sigset_zero;
	struct timespec timeout;
	int packetCount_SentFindServer=0;
	int packetCount_SentName=0;
	int packetCount_SentPassword=0;
	
	m_serialNo.ulValue = 0x1000002a;
	m_echoInterval = 30;
	if(cardif_init(intcur)<0)
	{
		retval = -3;
	}else{
	printf("interface is initalized!");
		}
	
	(void)signal(SIGINT,sig_intr);
	(void)sigfillset(&sigset_full);
	(void)sigprocmask(SIG_BLOCK,&sigset_full,NULL);
	
	//search for the server
	beginAuthentication:
	m_state = 0;
	(void)SendFindServerPacket(intcur);
	packetCount_SentFindServer = 1;
	packetCount_SentName = 0;
	packetCount_SentPassword = 0;
	
	while(1)
	{
	   (void)sigfillset(&sigset_full);
	   (void)sigdelset(&sigset_full,SIGINT);
	   FD_ZERO(&read_set); FD_SET(p_fd,&read_set);
	   timeout.tv_sec = 1;  
	   timeout.tv_nsec = 0;
	   
	   //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!
	     printf("it is bad");
	   case  0://time out
	     switch(m_state)
	     {
	     	case 0:
	     	  if(++packetCount_SentFindServer>3)
	     	  {
	     	  	printf("restarting authentication");
	     	  	goto beginAuthentication; 
	     	  }
	     	  (void)SendFindServerPacket(intcur);
	     	  continue;//jump to next loop of while(1) to receive next packet
	     	case 1:
	     	  if(++packetCount_SentName>3)
	     	  {
	     	  	printf("restarting authentication");
	     	  	goto beginAuthentication; 
	     	  }
	     	  (void)SendNamePacket(intcur,pkt_data);
	     	  continue;
	     	case 2:
	     	  if(++packetCount_SentPassword>3)
	     	  {
	     	  	printf("restarting authentication");
	     	  	goto beginAuthentication; 
	     	  }
	     	  (void)SendPasswordPacket(intcur,pkt_data);
	     	  continue;
	     	default:
	     	   printf("it is bad");
	     }
	   }
	   if(recvfrom(intcur->sockInt,pkt_data,sizeof(pkt_data),0,0,0)<0)
	   {
	   	printf("receive packet error");
	   	continue;
	   }
	   //收到的第二个及其以后的有效packet的源MAC必须等于头次收到的有效分组的源MAC
	   if((!isFirstPacketFromServer)&&(memcmp(intcur->dest_mac,pkt_data+6,6)!=0))
	   continue;
	   
	   
	
	   switch(pkt_data[0x12])   //分析EAP包类型
	   {
	   	case 0x01:  //表示请求
	   	  switch(pkt_data[0x16])
	   	  {
	   	  	case 0x01: //type 1,以用户名应答
	   	  	  if(m_state!=0)
	   	  	  continue;
	   	  	  m_state=1;
	   	  	  printf("server found,request user name");
	   	  	  if(isFirstPacketFromServer)//获得服务器的MAC地址
	   	  	  {
	   	  		memcpy(intcur->dest_mac,pkt_data+6,6);
	   	  		isFirstPacketFromServer=0;
	   	  	  }
	   	  	  ++packetCount_SentName;
	   	  	  (void)SendNamePacket(intcur,pkt_data);
	   	  	  break;
	   	  	case 0x04: //type 4,挑战,以MD5计算得到的值应答
	   	  	  if(m_state!=1)
	   	  	  continue;
	   	  	  m_state=2;
	   	  	  printf("user name valid,request password");
	   	  	  ++packetCount_SentPassword;
	   	  	  (void)SendPasswordPacket(intcur,pkt_data);
	   	  	  break;
	   	  }
	   	  break;
	   	case 0x03:   //认证成功
	   	  if(m_state!=2)
	   	  continue;
	   	  m_state=3;
	   	  printf("password valid,authenticationo success!!");
	   	  if(m_echoInterval<=0)
	   	  return 0;
	   	  
	   	  offset=ntohs( *((u_int16_t*)(pkt_data+0x10)) );
	          uTemp.ulValue = *((u_int32_t *)(pkt_data+(0x11+offset)-0x08));
	          m_key.btValue[0] = Alog(uTemp.btValue[3]);
	          m_key.btValue[1] = Alog(uTemp.btValue[2]);
	          m_key.btValue[2] = Alog(uTemp.btValue[1]);
	          m_key.btValue[3] = Alog(uTemp.btValue[0]);
	          
	          (void)sigemptyset(&sigset_zero);
	          (void)sigaddset(&sigset_zero,SIGINT);
	          (void)sigprocmask(SIG_UNBLOCK,&sigset_zero,NULL);
	          
	          printf("keeping sending echo...");
	          while(SendEchoPacket(intcur,pkt_data)==0)
	            sleep(m_echoInterval);
	          break;
	        case 0x04:  //认证失败(用户名或密码错误/不在上网时段内/重复上网等)
	          if((m_state==0)||(m_state==3)) continue;
	          m_state=0;
	          msglen=ntohs(*((u_int16_t*)(pkt_data+0x10)))-10;
	          if(msglen>0)
	          {
	          	if(msglen>=(sizeof(msgbuf)-1)) 
	          	msglen=sizeof(msgbuf)-1;
	          	memset(msgbuf,'\0',sizeof(msgbuf));
	          	pmsgbuf=msgbuf;
	          	if((msglen>2)&&(msgbuf[0]==0xd)&&(msgbuf[1]==0xa))
	          	pmsgbuf+=2;
	          }
	          else{
	          pmsgbuf="";
	          }
	          printf("authentication faild\ed!!!");
	          (void)SendEndCertPacket(intcur);
	          goto beginAuthentication;
	          break;
	     }
	}
}



static void sig_intr(int signo)
{
	struct interface_data *workint;
	if(m_state==3)
	{
		if(cardif_init(workint)<0);
		exit(0);
		(void)SendEndCertPacket(workint);
	}
	exit(0);
}
	   	  

⌨️ 快捷键说明

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