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

📄 rt61apd.c

📁 802.1x 源码,基于linux平台开发
💻 C
📖 第 1 页 / 共 2 页
字号:
/*创建发送socket*/    
/*   if (rtapd->ioctl_sock < 0)
    {
        rtapd->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
        if (rtapd->ioctl_sock < 0)
        {
            perror("socket[PF_INET,SOCK_DGRAM]");
            return -1;
        } 
    }

    sprintf(ifr.ifr_name, "%s",rtapd->conf->ethifname);
    DBGPRINT(RT_DEBUG_TRACE,"Register eth interface as (%s)\n", ifr.ifr_name);

    if (ioctl(rtapd->ioctl_sock, SIOCGIFHWADDR, &ifr) != 0)
    {
        perror("ioctl(SIOCGIFHWADDR)2");
        return -1;
    }

    DBGPRINT(RT_DEBUG_INFO," Device %s has ifr.ifr_hwaddr.sa_family %d\n",ifr.ifr_name, ifr.ifr_hwaddr.sa_family);
    if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER)
    {
        DBGPRINT(RT_DEBUG_ERROR,"Invalid HW-addr family 0x%04x\n", ifr.ifr_hwaddr.sa_family);
        return -1;
    }

    memcpy(rtapd->own_addr[0], ifr.ifr_hwaddr.sa_data, ETH_ALEN);
    DBGPRINT(RT_DEBUG_TRACE,"IF-%s MAC Address = %x:%x:%x:%x:%x:%x\n",ifr.ifr_name, rtapd->own_addr[0][0], 
        rtapd->own_addr[0][1],rtapd->own_addr[0][2],rtapd->own_addr[0][3], rtapd->own_addr[0][4],rtapd->own_addr[0][5]);
*/
    /*创建接收报文socket*/
    rtapd->eth_sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
    if (rtapd->eth_sock < 0)
    {
        perror("socket[PF_PACKET,SOCK_RAW](eth_sock)");
        return -1;
    }
    if (eloop_register_read_sock(rtapd->eth_sock, Handle_read, rtapd, NULL))
    {
        DBGPRINT(RT_DEBUG_ERROR,"Could not register read socket(eth_sock)\n");
        return -1;
    }
    memset(&ifr, 0, sizeof(ifr));
	
    //if your interface name is not 'eth0', then you need to modify 'Ethifname' in RT61AP.dat as what you want
	memset(&addr, 0, sizeof(addr));
    addr.sll_family = AF_PACKET;
	
    memcpy(ifr.ifr_name, rtapd->conf->ethifname, strlen(rtapd->conf->ethifname));
	

    DBGPRINT(RT_DEBUG_TRACE,"Register eth interface as (%s)\n", ifr.ifr_name);

   	if (ioctl(rtapd->eth_sock, SIOCGIFINDEX, &ifr) != 0)
    	{
	        perror("error:ioctl(SIOCGIFHWADDR)(eth_sock)\n");
	        return -1;
	  }    
    addr.sll_ifindex = 0;//ifr.ifr_ifindex;
	//
	if (ioctl(rtapd->eth_sock, SIOCGIFHWADDR, &ifr) != 0)
    {
       perror("error :ioctl(SIOCGIFHWADDR)2\n");
        return -1;
    }
	memcpy(rtapd->own_addr[0], ifr.ifr_hwaddr.sa_data, ETH_ALEN);
	
    DBGPRINT(RT_DEBUG_TRACE,"IF-%s MAC Address = %x:%x:%x:%x:%x:%x\n",ifr.ifr_name, rtapd->own_addr[0][0], 
       rtapd->own_addr[0][1],rtapd->own_addr[0][2],rtapd->own_addr[0][3], rtapd->own_addr[0][4],rtapd->own_addr[0][5]);

	//
	
    if (bind(rtapd->eth_sock, (struct sockaddr *) &addr, sizeof(addr)) < 0)
    {
        perror("bind");
        return -1;
    }
    DBGPRINT(RT_DEBUG_TRACE,"Opening ethernet raw packet socket for %s(socknum=%d,ifindex=%d)\n", ifr.ifr_name, rtapd->eth_sock, addr.sll_ifindex);


    return 0;
}

static void Apd_cleanup(rtapd *rtapd)
{
    int i;

    for (i = 0; i < rtapd->conf->SsidNum; i++)
    {
    	if (rtapd->sock[i] >= 0)
    		close(rtapd->sock[i]);
    }
	if (rtapd->ioctl_sock >= 0)
		close(rtapd->ioctl_sock);
	if (rtapd->eth_sock >= 0)
		close(rtapd->eth_sock);
    
	Radius_client_deinit(rtapd);

	Config_free(rtapd->conf);
	rtapd->conf = NULL;

	free(rtapd->config_fname);
}

static int Apd_setup_interface(rtapd *rtapd)
{   

	if (Apd_init_sockets(rtapd))
		return -1;    
    
	if (Radius_client_init(rtapd))
    {
		DBGPRINT(RT_DEBUG_ERROR,"RADIUS client initialization failed.\n");
		return -1;
	}

	if (ieee802_1x_init(rtapd))
    {
		DBGPRINT(RT_DEBUG_ERROR,"IEEE 802.1X initialization failed.\n");
		return -1;
	}
    DBGPRINT(RT_DEBUG_TRACE,"rtapd->radius->auth_serv_sock = %d\n",rtapd->radius->auth_serv_sock);

	return 0;
}

static void usage(void)
{
#if MULTIPLE_RADIUS    
	DBGPRINT(RT_DEBUG_TRACE, "USAGE :  rt61apd <wireless_if_name> \n");
	exit(1);
#else	
    DBGPRINT(RT_DEBUG_TRACE, "USAGE :  rt61apd \n");
#endif	
}

static rtapd * Apd_init(const char *config_file, int pid)
{
	rtapd *rtapd;
	int i;

	rtapd = malloc(sizeof(*rtapd));
	if (rtapd == NULL)
    {
		DBGPRINT(RT_DEBUG_ERROR,"Could not allocate memory for hostapd data\n");
		exit(1);
	}
	memset(rtapd, 0, sizeof(*rtapd));

	rtapd->config_fname = strdup(config_file);
	if (rtapd->config_fname == NULL)
    {
		DBGPRINT(RT_DEBUG_ERROR,"Could not allocate memory for config_fname\n");
		exit(1);
	}

	rtapd->conf = Config_read(rtapd->config_fname, pid);
	if (rtapd->conf == NULL)
    {
		DBGPRINT(RT_DEBUG_ERROR,"Could not allocate memory for rtapd->conf \n");
		free(rtapd->config_fname);
		exit(1);
	}

	for (i = 0; i < rtapd->conf->SsidNum; i++)
	    rtapd->sock[i] = -1;
	rtapd->ioctl_sock = -1;

    
    
	return rtapd;
}

static void Handle_usr1(int sig, void *eloop_ctx, void *signal_ctx)
{
	struct hapd_interfaces *rtapds = (struct hapd_interfaces *) eloop_ctx;
	struct rtapd_config *newconf;
	int i;

	DBGPRINT(RT_DEBUG_TRACE,"Reloading configuration\n");
	for (i = 0; i < rtapds->count; i++)
    {
		rtapd *rtapd = rtapds->rtapd[i];
		newconf = Config_read(rtapd->config_fname,0);
		if (newconf == NULL)
        {
			DBGPRINT(RT_DEBUG_ERROR,"Failed to read new configuration file - continuing with old.\n");
			continue;
		}

		/* TODO: update dynamic data based on changed configuration
		 * items (e.g., open/close sockets, remove stations added to
		 * deny list, etc.) */
		Radius_client_flush(rtapd);
		Config_free(rtapd->conf);
		rtapd->conf = newconf;
        Apd_free_stas(rtapd);

/* when reStartAP, no need to reallocate sock
        for (i = 0; i < rtapd->conf->SsidNum; i++)
        {
            if (rtapd->sock[i] >= 0)
                close(rtapd->sock[i]);
                
    	    rtapd->sock[i] = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
    	    if (rtapd->sock[i] < 0)
            {
    		    perror("socket[PF_PACKET,SOCK_RAW]");
    		    return;
    	    }
        }*/

	    if (Radius_client_init(rtapd))
        {
		    DBGPRINT(RT_DEBUG_ERROR,"RADIUS client initialization failed.\n");
		    return;
	    }

        DBGPRINT(RT_DEBUG_TRACE,"rtapd->radius->auth_serv_sock = %d\n",rtapd->radius->auth_serv_sock);
	}
}

void Handle_term(int sig, void *eloop_ctx, void *signal_ctx)
{
	FILE    *f;
	char    buf[256], *pos;
	int     line = 0, i;
    int     filesize,cur = 0;
    char    *ini_buffer;             /* storage area for .INI file */
#if MULTIPLE_RADIUS   
	FILE 	*pidfile; 
    char 	file_path[1024];
#endif
	
	DBGPRINT(RT_DEBUG_ERROR,"Signal %d received - terminating\n", sig);
	f = fopen(RT61AP_SYSTEM_PATH, "r+");
	if (f == NULL)
    {
		DBGPRINT(RT_DEBUG_ERROR,"Could not open configuration file '%s' for reading.\n", RT61AP_SYSTEM_PATH);
		return;
	}

    if ((fseek(f, 0, SEEK_END))!=0)
        return;
    filesize=ftell(f);
	DBGPRINT(RT_DEBUG_ERROR,"filesize %d   - terminating\n", filesize);

    if ((ini_buffer=(char *)malloc(filesize + 1 ))==NULL)
        return;   //out of memory
    fseek(f,0,SEEK_SET);
    fread(ini_buffer, filesize, 1, f);
    fseek(f,0,SEEK_SET);
    ini_buffer[filesize]='\0';

	while ((fgets(buf, sizeof(buf), f)))
    {
		line++;
		if (buf[0] == '#')
			continue;
		pos = buf;
		while (*pos != '\0')
        {
			if (*pos == '\n')
            {
				*pos = '\0';
				break;
			}
			pos++;
		}
		if (buf[0] == '\0')
			continue;

		pos = strchr(buf, '=');
		if (pos == NULL)
        {
		    pos = strchr(buf, '[');                
			continue;
		}
		*pos = '\0';
		pos++;

        if ((strcmp(buf, "pid") == 0) )
        {
            cur = 0;
            while(cur < (int)filesize)
            {  
                if ((ini_buffer[cur]=='p') && (ini_buffer[cur+1]=='i') && (ini_buffer[cur+2]=='d'))
                {
                    cur += 4;
                    for( i=4; i>=0; i--)
                    {
                        if (ini_buffer[cur] !='\n' )
                        {
                            ini_buffer[cur] =0x30;
                        }
                        else
                        {
                            break;
                        }
                        cur++;
                    }   
                    break;
                }
                cur++;
            }
		} 
    }
    fseek(f,0,SEEK_SET);
    fprintf(f, "%s", ini_buffer);    
    fclose(f);

#if MULTIPLE_RADIUS 
	DBGPRINT(RT_DEBUG_TRACE,"terminating 802.1x for (%s)\n",wireless_ifname);
	sprintf(file_path,"/var/run/auth_%s.pid",wireless_ifname);

    if ((pidfile = fopen(file_path, "w")) != NULL) {
		fprintf(pidfile, "%d\n", 0);
		(void) fclose(pidfile);
    } else {
		DBGPRINT(RT_DEBUG_ERROR, "Failed to create pid file %s\n", file_path);
    }
#endif

	eloop_terminate();
}

int main(int argc, char *argv[])
{
	struct hapd_interfaces interfaces;
    pid_t child_pid;
	int ret = 1, i;
	int c;
#if MULTIPLE_RADIUS    
    pid_t auth_pid;
#endif

    Mac2Port_Init();
	
#if MULTIPLE_RADIUS     
	if(argc != 2)
		usage();
	
	for (;;)
    {
		c = getopt(argc, argv, "h");
		if (c < 0)
			break;

		switch (c)
        {
		    case 'h':
		        usage();
			    break;

		    default:
		    	usage();
			    break;
		}
	} 

	strcpy(wireless_ifname,argv[1]);
	//if prefix is not "ra", please modify here.
	if(strncmp(wireless_ifname,"ra",2)!=0)
	{
		DBGPRINT(RT_DEBUG_ERROR, "Invalid Interface Name.\n");	
		usage();
	}
	DBGPRINT(RT_DEBUG_TRACE, "Wireless Ifname = %s\n",wireless_ifname);
#else
    
	for (;;)
    {
		c = getopt(argc, argv, "h");
		if (c < 0)
			break;

		switch (c)
        {
		    case 'h':
		        usage();
			    break;

		    default:
			    break;
		}
	} 

#endif	
	
    child_pid = fork();
    if (child_pid == 0)
    {           
#if MULTIPLE_RADIUS
		auth_pid = getpid();
		DBGPRINT(RT_DEBUG_TRACE, "Porcess ID = %d\n",auth_pid);
#endif        
        
        openlog("rt61apd",0,LOG_DAEMON);
        // set number of configuration file 1
        interfaces.count = 1;
        interfaces.rtapd = malloc(sizeof(rtapd *));
        if (interfaces.rtapd == NULL)
        {
            DBGPRINT(RT_DEBUG_ERROR,"malloc failed\n");
            exit(1);    
        }
        eloop_init(&interfaces);
		/*
		
		SIGHUP 终端线已经挂起
		SIGINT 终端线已经接收到中断字符
		SIGQUIT 终端线已经接收到退出字符
		SIGUSR1 用户自定义信号1
		SIGUSR2 用户自定义信号2
		SIGTERM 正被终止的进程
		SIGCHLD 一个子进程已终止
		SIGPIPE 半关闭管道的写操作已经发生
		SIGALRM Alarm函数的计时器已经到期
		信号处理函数取值:
		SIG_DEL 默认的信号操作(DEFault)
		SIG_IGN 忽略信号(IGNore)
		*/
		
        eloop_register_signal(SIGINT, Handle_term, NULL);
        eloop_register_signal(SIGTERM, Handle_term, NULL);
        eloop_register_signal(SIGUSR1, Handle_usr1, NULL);
        eloop_register_signal(SIGHUP, Handle_usr1, NULL);
		
        DBGPRINT(RT_DEBUG_ERROR,"\n Configuration file: %s\n", RT61AP_SYSTEM_PATH);
        interfaces.rtapd[0] = Apd_init(strdup(RT61AP_SYSTEM_PATH),(int)getpid());
		
        if (!interfaces.rtapd[0])
            goto out;
        if (Apd_setup_interface(interfaces.rtapd[0]))
            goto out;
		
#if MULTIPLE_RADIUS        
        create_pidfile(wireless_ifname);
#endif        
        AuthPort_init();
        eloop_run(interfaces.rtapd[0]);

        Apd_free_stas(interfaces.rtapd[0]);
	    ret = 0;

out:
	    for (i = 0; i < interfaces.count; i++)
        {
		    if (!interfaces.rtapd[i])
			    continue;

		    Apd_cleanup(interfaces.rtapd[i]);
		    free(interfaces.rtapd[i]);
	    }

	    free(interfaces.rtapd);
	    eloop_destroy();
        closelog();
	    return ret;
    }
    else        
        return 0;
}

#if MULTIPLE_RADIUS      
static void create_pidfile(const char* ifname)
{
    FILE *pidfile;
	char file_path[1024];

	sprintf(file_path,"/var/run/auth_%s.pid",ifname);

    if ((pidfile = fopen(file_path, "w")) != NULL) {
		fprintf(pidfile, "%d\n", getpid());
		(void) fclose(pidfile);
    } else {
		DBGPRINT(RT_DEBUG_ERROR, "Failed to create pid file %s\n", file_path);
    }
}
#endif

⌨️ 快捷键说明

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