📄 rt61apd.c
字号:
/*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. See README and COPYING for
* more details.
Module Name:
rt61apd.c
Revision History:
Who When What
-------- ---------- ----------------------------------------------
Jan, Lee Dec --2003 modified
*/
#include <net/if_arp.h>
#include <netpacket/packet.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <linux/wireless.h>
#include <arpa/inet.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/time.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <netinet/in.h>
#include <string.h>
#include <signal.h>
#include <time.h>
#include <syslog.h>
#include <stdarg.h>
#include <sys/types.h>
#include <sys/socket.h>
#include "rt61apd.h"
#include "eloop.h"
#include "ieee802_1x.h"
#include "eapol_sm.h"
#include "ap.h"
#include "sta_info.h"
#include "radius_client.h"
#include "config.h"
#define RT61AP_SYSTEM_PATH "/etc/Wireless/RT61AP/RT61AP.dat"
#if MULTIPLE_RADIUS
static void create_pidfile(const char* ifname);
unsigned char wireless_ifname[IFNAMSIZ+1];
#endif
struct hapd_interfaces {
int count;
rtapd **rtapd;
};
int msgid;
u8 bMsgReady;
/*
========================================================================
Routine Description:
Compare two memory block
Arguments:
Adapter Pointer to our adapter
Return Value:
0: memory is equal
1: pSrc1 memory is larger
2: pSrc2 memory is larger
Note:
========================================================================
*/
u16 RTMPCompareMemory(void *pSrc1,void *pSrc2, u16 Length)
{
char *pMem1;
char *pMem2;
u16 Index = 0;
pMem1 = (char*) pSrc1;
pMem2 = (char*) pSrc2;
for (Index = 0; Index < Length; Index++)
{
if (pMem1[Index] > pMem2[Index])
return (1);
else if (pMem1[Index] < pMem2[Index])
return (2);
}
// Equal
return (0);
}
int RT_ioctl(rtapd *rtapd, int param, char *data, int data_len, unsigned char apidx, int flags)
{
char name[12];
int ret = 1;
struct iwreq wrq;
#if MULTIPLE_RADIUS
strcpy(name,wireless_ifname);
#else
sprintf(name, "ra%d", apidx);
name[3] = '\0';
#endif
strcpy(wrq.ifr_name, name);
wrq.u.data.flags = flags;
wrq.u.data.length = data_len;
wrq.u.data.pointer = (caddr_t) data;
ret = ioctl(rtapd->ioctl_sock, param, &wrq);
return ret;
}
static void Handle_read(int sock, void *eloop_ctx, void *sock_ctx)
{
rtapd *rtapd = eloop_ctx;
int len;
unsigned char buf[3000];
u8 *sa, *pos, apidx=0;
u16 ethertype,i;
priv_rec *rec;
size_t left;
len = recv(sock, buf, sizeof(buf), 0);
if (len < 0)
{
perror("recv");
Handle_term(15,eloop_ctx,sock_ctx);
return;
}
rec = (priv_rec*)buf;
left = len -sizeof(*rec)+1;
if (left <= 0)
{
DBGPRINT(RT_DEBUG_ERROR," too short recv\n");
return;
}
sa = rec->saddr;
ethertype = rec->ethtype[0] << 8;
ethertype |= rec->ethtype[1];
if (ethertype == ETH_P_PRE_AUTH)
{
DBGPRINT(RT_DEBUG_TRACE,"WPA2 pre-auth packet\n");
}
else if (ethertype == ETH_P_PAE)
{
// search this packet is coming from which interface
for (i = 0; i < rtapd->conf->SsidNum; i++)
{
if(sock == rtapd->sock[i])
{
apidx = i;
break;
}
}
if(i >= rtapd->conf->SsidNum)
{
DBGPRINT(RT_DEBUG_ERROR,"sock not found (sock=%d)!!!\n", sock);
return;
}
}
else
return;
pos = rec->xframe;
if (len < 52 )
{
DBGPRINT(RT_DEBUG_INFO,"Handle_read :: handle_short_frame: (len=%d, left=%d)\n", len,left);
for(i = 0; i < left; i++)
DBGPRINT(RT_DEBUG_INFO," %x", *(pos+i));
DBGPRINT(RT_DEBUG_INFO,"\n");
}
ieee802_1x_receive(rtapd, sa, &apidx, pos, left, ethertype);
}
int Apd_init_sockets(rtapd *rtapd)
{
struct ifreq ifr;
struct sockaddr_ll addr;
int i;
// init ethernet interface 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
//sprintf(ifr.ifr_name, "eth%d", 0);
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("ioctl(SIOCGIFHWADDR)(eth_sock)");
return -1;
}
memset(&addr, 0, sizeof(addr));
addr.sll_family = AF_PACKET;
addr.sll_ifindex = ifr.ifr_ifindex;
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);
// init wireless interface socket
for(i = 0; i < rtapd->conf->SsidNum; i++)
{
#if MULTIPLE_RADIUS
strcpy(rtapd->conf->iface[i],wireless_ifname);
#else
sprintf(rtapd->conf->iface[i], "ra%d", i);
#endif
rtapd->sock[i] = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
if (rtapd->sock[i] < 0)
{
perror("socket[PF_PACKET,SOCK_RAW]");
return -1;
}
if (eloop_register_read_sock(rtapd->sock[i], Handle_read, rtapd, NULL))
{
DBGPRINT(RT_DEBUG_ERROR,"Could not register read socket\n");
return -1;
}
memset(&ifr, 0, sizeof(ifr));
#if MULTIPLE_RADIUS
strcpy(ifr.ifr_name,wireless_ifname);
#else
sprintf(ifr.ifr_name, "ra%d", i);
#endif
if (ioctl(rtapd->sock[i], SIOCGIFINDEX, &ifr) != 0)
{
perror("ioctl(SIOCGIFHWADDR)");
return -1;
}
memset(&addr, 0, sizeof(addr));
addr.sll_family = AF_PACKET;
addr.sll_ifindex = ifr.ifr_ifindex;
if (bind(rtapd->sock[i], (struct sockaddr *) &addr, sizeof(addr)) < 0)
{
perror("bind");
return -1;
}
#if MULTIPLE_RADIUS
DBGPRINT(RT_DEBUG_TRACE,"Opening raw packet socket for %s(sock=%d)\n", wireless_ifname, rtapd->sock[i]);
#else
DBGPRINT(RT_DEBUG_TRACE,"Opening raw packet socket for ra%d(socknum=%d,ifindex=%d)\n", i, rtapd->sock[i],addr.sll_ifindex);
#endif
}
for(i = 0; i < rtapd->conf->SsidNum; i++)
{
memset(&ifr, 0, sizeof(ifr));
#if MULTIPLE_RADIUS
strcpy(ifr.ifr_name,wireless_ifname);
#else
snprintf(ifr.ifr_name, 4, rtapd->conf->iface[i]);
#endif
if (ioctl(rtapd->sock[i], SIOCGIFHWADDR, &ifr) != 0)
{
perror("ioctl(SIOCGIFHWADDR)");
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[i], 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[i][0], rtapd->own_addr[i][1],rtapd->own_addr[i][2],rtapd->own_addr[i][3], rtapd->own_addr[i][4],rtapd->own_addr[i][5]);
}
return 0;
}
static void Apd_cleanup(rtapd *rtapd)
{
int i;
msgctl(msgid, IPC_RMID, NULL);
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 (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;
}
}
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;
}
int ApdSetupMsg(rtapd *rtapd)
{
int key = 0x55116604;
if((key = ftok(MSG_FILE, 0xf)) == -1)
{
DBGPRINT(RT_DEBUG_ERROR, "ApdSetupMsg: ftok Error:n");
return(-1);
}
if((msgid = msgget(key, 0x0600|IPC_CREAT)) == -1)
{
DBGPRINT(RT_DEBUG_ERROR, "ApdSetupMsg: msgget Error\n");
return (-1);
}
bMsgReady = FALSE;
DBGPRINT(RT_DEBUG_TRACE, "ApdSetupMsg: key=%d, msgid=%d\n", key, msgid);
return 0;
}
int ApdSendMsg(rtapd *rtapd, int msgsubtype, char* buf, int len)
{
struct msgbuf msg;
if (bMsgReady == FALSE)
{
DBGPRINT(RT_DEBUG_TRACE, "ApdSendMsg, IAPP is not ready\n");
return -1;
}
msg.msgtype = RADIUSMSGQUEID;
msg.msgsubtype = msgsubtype;
if (len > 0)
{
memcpy(msg.buf, buf, len);
}
DBGPRINT(RT_DEBUG_TRACE, "ApdSendMsg (msgsubtype=%d, len=%d)\n", msgsubtype, len);
return msgsnd(msgid, &msg, (len+4), 0);
}
int ApdProcessIPCMsg(rtapd *rtapd, struct msgbuf *msg, int len)
{
DBGPRINT(RT_DEBUG_TRACE,"ApdProcessIPCMsg (len=%d, msgtype=%d, msgsubtype=%d):%d:%d:%d:%d\n", len, (int)msg->msgtype, (int)msg->msgsubtype, msg->buf[0], msg->buf[1], msg->buf[2], msg->buf[3]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -