📄 rt61apd.c
字号:
/*创建发送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 + -