校园网802.1X的Linux联网客户端(1.3(2)

void shut_reb_signal_pro(int sig)//后台进程的重启、关机信号处理
{
   flag_sig_pro=0;
   close(sockfd);
   (void)unlink(lock_file);
   Send_Eapol_Logoff();
   (void)close(file_desc);
   pcap_close(fp);
   return;
}
void free_lock_file()
{
  (void)close(file_desc);
  (void)unlink(lock_file);
  if(tcsetattr(fileno(stdin),TCSANOW,&old_set))
      printf("restore terminal's mode failed!\n");
}
int main(int argc, char *argv[])
{
   int flag,flag_fail=1;
   pcap_if_t *alldevs,*d;
   char c,c1;
   int j=0,OvertimeCount=0,sendcount=1;
   char errbuf[PCAP_ERRBUF_SIZE];
   char shell[100]={"/sbin/ifconfig "};
   int rtrnval;
   pid_t pid;
   struct termios new_set;
   tcgetattr(fileno(stdin),&old_set);
   new_set=old_set;
   new_set.c_lflag&=~ISIG;
   //system("clear;history -c;exit 0");
   if(tcsetattr(fileno(stdin),TCSANOW,&new_set))
   {
       printf("set terminal's mode failed!\n");
       return 1;
   }
   new_set.c_lflag&=~ECHO;
   act.sa_handler=shut_reb_signal_pro;
   sigemptyset(&act.sa_mask);
   act.sa_flags=0;
   file_desc=open(lock_file,O_RDWR|O_CREAT|O_EXCL,0444);//建立锁文件
   if(file_desc==-1)
   {
      printf("%s_Lock already present\n",argv[0]);
      printf("If running %s is the first time after starting the PC,or you once ended it by closing the terminal,please remove %s!\nElse may you are running %s.\n",argv[0],lock_file,argv[0]);
      return 1;
   }
   printf("\nAttention:\n\nif the twisted-pair is pulled out of network_card,this programme may will hold on.If so, you will have to close this terminal to end it!\n\nPress ENTER to continue......\n");
   c1=getchar();
   while(c1!='\n')
     c1=getchar();
   memset(EAP_Pack,0X00,Eap_Pack_Len);
   j=0;
   if(pcap_findalldevs(&alldevs,errbuf)==0)
   {
     d=alldevs;
     if(!alldevs)
     {
       printf("try \"sudo %s \"\n",argv[0]);
       free_lock_file();
       return 1;
     }
     while(get_user_name());
     //noecho();
     if(tcsetattr(fileno(stdin),TCSAFLUSH,&new_set))
     {
         printf("set terminal's mode failed!\n");
         free_lock_file();
         return 1;
     }
     while(get_user_pwd());
     new_set.c_lflag|=ECHO;
     if(tcsetattr(fileno(stdin),TCSANOW,&new_set))
     {
         printf("set terminal's mode failed!\n");
         free_lock_file();
         return 1;
     }
     //echo();
     printf("\n\n");
     for(;d;d=d->next)
     {
        j++;
        printf("%d:network_card_%d's name:%s\n",j,j,d->name);
       //if(d->description)
       //     printf("device %d's description:%s\n",j,d->description);
       //   else
       //     printf("No description available for device %d.\n",j);
     }
     printf("Enter the interface number:\n");
     scanf("%c",&c);
     c1=c;
     while(c1!='\n')
       c1=getchar();
     c=c-'0';
     if(c>j||c<1)
     {
       printf("out of range!\n");
       pcap_freealldevs(alldevs);
       free_lock_file();
       return 1;
     }
     d=alldevs;
     for(j=1;j<c;j++,d=d->next);
   }
   else
   {
     printf("not found network_card!\n");
     free_lock_file();
     return 1;
   }
   strcpy(req.ifr_name,d->name);
   if(get_mac_client())
   {
     printf("got network_card's mac error!\n");
     pcap_freealldevs(alldevs);
     free_lock_file();
     return 1;
   }
   // Open the adapter
   if((fp=pcap_open_live(d->name,150,1,200,errbuf))==NULL)
   {
     printf("Unable to open the adapter. %s is not supported by WinPcap\n",d->name);
     pcap_freealldevs(alldevs);
     free_lock_file();
     return 1;
   }
   strcat(shell,d->name);
   strcat(shell," down;/sbin/ifconfig ");
   strcat(shell,d->name);
   strcat(shell," up;exit 0");
   pcap_freealldevs(alldevs);
   memcpy(EAP_Pack,mac_server,6);
   memcpy(EAP_Pack+6,mac_client,6);
   //strcpy(user_name,argv[1]);
   EAP_Pack[12]=0x88;EAP_Pack[13]=0x8e;EAP_Pack[14]=0x01;
   memcpy(base,mac_client,6);
   base[12]=0x88;base[13]=0x8e;base[14]=0x01;base[15]=0x00;base[16]=0x00;
   if(!Send_Eapol_Start(fp,EAP_Pack))
      printf("start logging on!\n");
   else
   {
      printf("start logging on error!\n");
      pcap_close(fp);
      free_lock_file();
      return 1;
   }
   j=1;
   while(j)
   {
     flag=0;
     if(OvertimeCount>10)//超时次数
     {
       printf("OvertimeCount>10!Please check PC's network_card!\n");
       break;
     }
     rtrnval=pcap_next_ex(fp,&header,(const u_char **)&pkt_data);
     if(rtrnval)
     {
       j++;
       if(EAP_REQUEST_LEN==header->len||EAP_PWD_ERR_LEN==header->len||EAP_NAME_ERR_LEN==header->len)
       {
         if(!EAP_CMP_Name_Error(pkt_data))
         {
           printf("name does'n exist or is wrong!\n");
           break;
         }
         if(!EAP_CMP_PWD_Error(pkt_data))
         {
           printf("password is wrong!check your password!\n");
           break;
         }
         if(!EAP_CMP_MAC_Error(pkt_data))
         {
            printf("MAC error!Did you change your network_card?\n");
            break;
         }
         if(!EAP_CMP_NOTI(pkt_data))
         {
            flag=1;
            j=1;
            if(Send_Eap_Noti(fp,EAP_Pack))
            {
                printf("sent Eap_Notification_Packet error!\n");
                break;
            }
            printf("sent eap_notification packet successfully!\n");
            continue;
         }
         if(!EAP_CMP_Name(pkt_data))
         {
            flag=1;
            j=1;
            if(Send_Eap_Name(fp,EAP_Pack))
            {
              printf("sent Eap_Name_Packet error!\n");
              break;
            }
            printf("sent eap_name_packet successfully!\n");
            continue;
         }
         if(!EAP_CMP_PWD(pkt_data))
         {
            flag=1;
            j=1;
            if(Send_Eap_PWD(fp,EAP_Pack,pkt_data))
            {
              printf("sent Eap_PWD_Packet error!\n");
              break;
            }
            printf("sent eap_pwd_packet successfully!\n");
            continue;
         }
         if(!EAP_CMP_Success(pkt_data))
         {
            flag_fail=0;
            printf("Logged on successfully!\n");
            system((const char *)shell);//执行shell获取IP
            printf("\nIF failed to automatically get IP,please manually operate to get IP.\n");
            printf("for example:\n");
            printf("  run the following commands in terminal:\n\tsudo ifdown <network_card's name> \n");
            printf("\tsudo ifup <network_card's name>\n");
            printf("\n\t\t--good luck!\n");
            printf("\t\t%s    by DW\n",version);
            break;
         }
     if(!EAP_CMP_ERR(pkt_data))
     {
         printf("receive log-off packet!Please check your name,password and network_card!\n");
         break;
     }
       }
     }
     else if(rtrnval==0)
     {
       OvertimeCount++;
       printf("received package over time!\n");
       if(OvertimeCount%2==0)
       {
          if(!Send_Eapol_Start(fp,EAP_Pack))
            printf("Restart logging on!\n");
          else
          {
            printf("restart logging on error!\n");
            break;
          }
       }
       continue;
     }
     else
     {
       printf("received package error!will exit!\n");
       break;
     }
     if(flag==0&&j%50==0)//如果连续50个数据包都不是认证所需的,重新发起认证
     {
       if(!Send_Eapol_Start(fp,EAP_Pack))
       {
          printf("Restart logging on!\n");
          sendcount++;
          continue;
       }
       else
       {
          printf("Restart logging on error!\n");
          break;
       }
     }
     if(sendcount>5)//重新发起认证次数
     {
        printf("logged on failed!\n");
        break;
     }
 }
 if(flag_fail)
 {
   close(sockfd);
   pcap_close(fp);
   free_lock_file();
   printf("exit......\n");
 }
 else//进入后台处理
 {
   free_lock_file();
   if((pid=fork())>0)
     exit(0);
   else if(pid<0)
   {
     pcap_close(fp);
     exit(1);
   }
   file_desc=open(lock_file,O_RDWR|O_CREAT|O_EXCL,0444);
   if(file_desc==-1)
      return 1;
   setsid();
   chdir("/");
   umask(0);
   sigaction(SIGTERM,&act,0);
   //处理认证成功后服务器持续发送确认包的情况
   sockfd=socket(AF_INET,SOCK_STREAM,0);//用来获取指定网卡IP
   Fill_EAP_Name(EAP_Pack);
   base[15]=0x00;base[16]=0x00;base[17]=0x05;base[18]=0x01;
   base[20]=0x00;base[21]=0x05;base[22]=0x01;
   while(flag_sig_pro)
   {
      rtrnval=pcap_next_ex(fp,&header,(const u_char **)&pkt_data);
      if(rtrnval&&EAP_REQUEST_LEN==header->len)
     {
        ID=base[19]=pkt_data[19];
        if(!strncmp(base,pkt_data,22))
        {
             Fill_EAP_After_Suc();
             if(pcap_sendpacket(fp,EAP_Pack,60))
                  shut_reb_signal_pro(-1);
        }
     }
  }
   //pause();
 }
 return 0;
}//end

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/28187.html