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

📄 rt61apd.c

📁 Ralink RT61 SoftAP Driver source code. RT61:MiniPCI
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 *
 * 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 + -