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

📄 rt61apd.c

📁 802.1x 源码,基于linux平台开发
💻 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 <stdio.h>
#include <unistd.h>
#include <sched.h>
#include <sys/resource.h>
#include <sys/time.h>

#include <string.h>

#include <features.h>
#include <stdlib.h>
#include <stdarg.h> /* va_start... */
#include <sys/types.h>
#include <pthread.h>
#include <signal.h> /* kill */
#include <malloc.h>
#include <errno.h> /* errno */
#include <sys/stat.h> /* mkdir */
#include <fcntl.h> /* creat */
#include <sys/ipc.h> /* ftok */
#include <sys/sem.h> /* semget */
#include <termios.h> /* tcgetattr, tcsetattr */

#include <net/if_arp.h>
#include <netpacket/packet.h>
#include <sys/ioctl.h>
#include <netinet/in.h>

#include <string.h>
#include <syslog.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"
#include "mac2port.h"
#include "switch_if.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;
};




#define SWITCH_PIPE_KEY_PATH  "/proc/switch"
#define SWITCH_PIPE_PREFIX "/tmp/myfifo"
#define	PERMS0				IPC_CREAT|00666
#define	PERMS1				IPC_CREAT|IPC_EXCL|00666

#if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
   /* union semun is defined by including <sys/sem.h> */
#else
   /* according to X/OPEN we have to define it ourselves */
   union semun {
      int val;                  /* value for SETVAL */
      struct semid_ds *buf;     /* buffer for IPC_STAT, IPC_SET */
      unsigned short *array;    /* array for GETALL, SETALL */
                              /* Linux specific part: */
      struct seminfo *__buf;    /* buffer for IPC_INFO */
   };
#endif

static int logsem_p(int semid)
{ 
   	struct  sembuf sops;
	
	sops.sem_num = 0;
	sops.sem_op = -1;
	sops.sem_flg = SEM_UNDO;//IPC_NOWAIT;//SEM_UNDO; 
	
	if (semop(semid, &sops,1) == -1) {
		return 0;
	}
	return 1; 
}

static int logsem_v(int semid)
{
	
	struct sembuf sops;//={0, 1,SEM_UNDO}; 
	
	sops.sem_num = 0;
	sops.sem_op = 1;
	sops.sem_flg = SEM_UNDO;//IPC_NOWAIT;//SEM_UNDO; 
	
	if (semop(semid, &sops,1) == -1 ) {
		return 0;
	}
	return 1;
}

int switch_cli_pipe_write(char *command)
{
	int  semid = -1;
	union semun sem;
	char w_buff[100];
	int fd =0;
	int nwrite = 0;

  	semid = semget(ftok(SWITCH_PIPE_KEY_PATH,'y'), 1, PERMS1);
	//		fprintf(stderr, "\r\n1   ---->   switch_cli_pipe_write    : semid = %d\n", semid);
	if (semid == -1 && EEXIST == errno) {
	  	semid = semget(ftok(SWITCH_PIPE_KEY_PATH,'y'), 1, PERMS0);
	} else if (semid >= 0) {
  		sem.val = 1;
		semctl(semid, 0, SETVAL, sem);
	}
	//		fprintf(stderr, "2   ---->   switch_cli_pipe_write: semid = %d\n", semid);

	logsem_p(semid);

	fprintf(stderr, "CMD :   %s\n", command);

	fd = open(SWITCH_PIPE_PREFIX, O_WRONLY | O_NONBLOCK);

	strcpy(w_buff, command);
	if((nwrite = write(fd, w_buff, 100)) == -1){
		if(errno == EAGAIN)
		printf("switch_cli_pipe_write  write error \n");
	}
	else{
		printf("switch_cli_pipe_write  write OK \n");
	}
	usleep(50 * 1000);
	close(fd);

	if (!logsem_v(semid))
	{
		fprintf(stderr, "can't do sem v operation! \n");
		semctl(semid,0,IPC_RMID);	
		return -1;
	}
	return 0;

}

void AuthPort_init()
{
    char cCmdBuf[256];
    
    memset(cCmdBuf, 0, sizeof(cCmdBuf));
    sprintf(cCmdBuf, "auth8021x create\n");
    switch_cli_pipe_write(cCmdBuf);
    memset(cCmdBuf, 0, sizeof(cCmdBuf));
    sprintf(cCmdBuf, "auth init\n");
    switch_cli_pipe_write(cCmdBuf);
    memset(cCmdBuf, 0, sizeof(cCmdBuf));
    sprintf(cCmdBuf, "auth block pbm=0xffffff\n");
    switch_cli_pipe_write(cCmdBuf);
        
}
/*
	========================================================================
	
	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, int lPort)
{
    int     ret = 1;
	int i;
	
	struct sockaddr_ll daddr; //ken_send	
	daddr.sll_family = AF_PACKET;
	daddr.sll_protocol = ETH_P_ALL;
	daddr.sll_ifindex = 5;
	daddr.sll_hatype = 1;
	daddr.sll_halen = 8;	
	for ( i=0; i<6; i++)
		daddr.sll_addr[i] = data[i];
		
#if 0
    char    buf[1600];
    SWITCH_8021X_PACKET_S *pEapolPacket;
    int fd;
#define SWITCH_TX_PIPE  "/tmp/protocoltx"
    if(RTPRIV_IOCTL_RADIUS_DATA != param)
    {
        return -1;
    }

    if((fd = open(SWITCH_TX_PIPE,O_WRONLY)) < 0)
    {
        fprintf(stderr ," open pipe error \n");
        return -1;
    }
    if (data_len < 60)
    {
        data_len = 60;
    }
    pEapolPacket = (SWITCH_8021X_PACKET_S*)buf;
    memset(buf, 0, sizeof(buf));
    pEapolPacket->lLength = htonl(data_len);
    pEapolPacket->lPort = htonl(lPort);
    memcpy(pEapolPacket->cPacket, data, data_len);
//fprintf(stderr, "RT_ioctl\n");
    ret = write(fd, buf, data_len + 8);
    if(ret < 0)
    {
        fprintf(stderr, "write pipe to switch");        
    }
    close(fd);
#else
    if(RTPRIV_IOCTL_RADIUS_DATA != param)
    {
        return -1;
    }
    DBGPRINT(RT_DEBUG_INFO,"eth_sock =%d\n",rtapd->eth_sock);
    /*for debug*//*begin*/

    for(i=0; i<data_len; i++)
    {
        DBGPRINT(RT_DEBUG_TRACE, "%02x ", data[i]);
    }
    DBGPRINT(RT_DEBUG_TRACE,"\n");
	DBGPRINT(RT_DEBUG_TRACE,"send to (%d)\n",rtapd->eth_sock);
    /*for debug*//*end*/
	//ken_send	
	//ret = send(rtapd->eth_sock, data, data_len, 0);
	ret=sendto(rtapd->eth_sock, data, data_len, 0x00,(struct sockaddr *)&daddr, sizeof(daddr));
	if(ret < 0)
    {
        DBGPRINT(RT_DEBUG_ERROR, "send[RADIUS]1 errno(%d)\n",errno);
    }

#endif
    return ret;
    
}

/*for debug*/
int debugProc = 0;
int Code;
int TypeCode;
char eapol_start[] = 
{
    0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x03,0x47,0xdf,0x32,0x06,0x88,0x8e,0x01,0x01,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
char *EAP_code[] =
{
    "",
    "Request",
    "Respons",
    "Success",
    "Failure"
};
    
/*static int Recv_Eapol(char *pBuf, int lBufLength, int *plLength, int *pSrcPort)
{
    if(lBufLength < 1518)
    {
        return -1;
    }
    if(debugProc == 0)
    {
        *plLength = sizeof(eapol_start);
        memcpy(pBuf, eapol_start, *plLength);
    }

    *pSrcPort = 1;
    
    return 0;
}*/
void Recv_Eapol(char *pcBuf, int lPacketLength, int lSrcPort, void *p)
{
    priv_rec *rec;
    size_t left;
    u8 *sa, *pos, *pucPortMac, apidx=0;
    u16 ethertype,i;
    int lRetVal;
    rtapd *rtapd = p;
    
//fprintf(stderr, "    Recv_Eapol\n");
    if (lPacketLength < 0)
    {
        perror("recv");
        return;
    }
    
    rec = (priv_rec*)pcBuf;
    left = lPacketLength - 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];
    Code = rec->ethtype[2];
    if(ethertype == ETH_P_PAE)
    {
        DBGPRINT(RT_DEBUG_TRACE," Recve a PAEOL packet, %s, Src Port=%d  \n",EAP_code[Code],  lSrcPort);
        DBGPRINT(RT_DEBUG_INFO,"Recv_Eapol :: handle_frame(len=%d) :SRC_MAC %x:%x:%x:%x:%x:%x  DST_MAC %x:%x:%x:%x:%x:%x  Type=%x \n",
            lPacketLength, rec->saddr[0], rec->saddr[1], rec->saddr[2], rec->saddr[3], rec->saddr[4], rec->saddr[5],
            rec->daddr[0], rec->daddr[1], rec->daddr[2], rec->daddr[3], rec->daddr[4], rec->daddr[5], ethertype);
        apidx = 0;
        lRetVal = Mac2Port_FindMacByPort(lSrcPort, &pucPortMac);
        if(lRetVal == -1)/*输入参数错误*/
        {
            return;
        }
        else if(lRetVal == 1)
        {
            Mac2Port_AddMac(sa, lSrcPort);
        }
        else
        {
            if(0 != memcmp(pucPortMac, sa, 6))
            {
                fprintf(stderr, "8021x Mac not same in port=%d,SRC_MAC %x:%x:%x:%x:%x:%x  DST_MAC %x:%x:%x:%x:%x:%x\n", lSrcPort,
                    rec->saddr[0], rec->saddr[1], rec->saddr[2], rec->saddr[3], rec->saddr[4], rec->saddr[5],
                    rec->daddr[0], rec->daddr[1], rec->daddr[2], rec->daddr[3], rec->daddr[4], rec->daddr[5]);
                return;
            }
        }
    }
    else
        return;

    pos = rec->xframe;
    if (lPacketLength < 52 )
    {
        DBGPRINT(RT_DEBUG_INFO,"Recv_Eapol :: handle_short_frame: (len=%d, left=%d)\n", lPacketLength,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);

}

static void Handle_read(int sock, void *eloop_ctx, void *sock_ctx)
{                              
    rtapd *rtapd = eloop_ctx;
    int len,lPacketLength,lSrcPort;
    unsigned char buf[2000];
    u8 *sa, *pos, *pucPortMac, apidx=0;
    u16 ethertype,i;
    priv_rec *rec;
    size_t left;
    int lRetVal;

    len = recv(sock, buf, sizeof(buf), 0);
    lPacketLength = len;

    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];
    Code = rec->ethtype[2];
    lSrcPort = buf[len - 1];
    
    if(ethertype == ETH_P_PAE)
    {
    	for (i =0;i< lPacketLength;i++)
			DBGPRINT(RT_DEBUG_TRACE,"%02x ",buf[i]);
		DBGPRINT(RT_DEBUG_TRACE,"\n");
		
        DBGPRINT(RT_DEBUG_TRACE," Recve a PAEOL packet, %s, Src Port=%d  Lentgth=%d \n",EAP_code[Code],  lSrcPort, lPacketLength);
        DBGPRINT(RT_DEBUG_TRACE,"Recv_Eapol :: handle_frame(len=%d) :SRC_MAC %x:%x:%x:%x:%x:%x  DST_MAC %x:%x:%x:%x:%x:%x  Type=%x \n",
            lPacketLength, rec->saddr[0], rec->saddr[1], rec->saddr[2], rec->saddr[3], rec->saddr[4], rec->saddr[5],
            rec->daddr[0], rec->daddr[1], rec->daddr[2], rec->daddr[3], rec->daddr[4], rec->daddr[5], ethertype);
        apidx = 0;
        lRetVal = Mac2Port_FindMacByPort(lSrcPort, &pucPortMac);
        if(lRetVal == -1)/*输入参数错误*/
        {
            return;
        }
        else if(lRetVal == 1)
        {
            Mac2Port_AddMac(sa, lSrcPort);
        }
        else
        {
            if(0 != memcmp(pucPortMac, sa, 6))
            {
                fprintf(stderr, "8021x Mac not same in port=%d,SRC_MAC %x:%x:%x:%x:%x:%x  DST_MAC %x:%x:%x:%x:%x:%x\n", lSrcPort,
                    rec->saddr[0], rec->saddr[1], rec->saddr[2], rec->saddr[3], rec->saddr[4], rec->saddr[5],
                    rec->daddr[0], rec->daddr[1], rec->daddr[2], rec->daddr[3], rec->daddr[4], rec->daddr[5]);
                return;
            }
        }
    }
    else
        return;

    pos = rec->xframe;
    if (lPacketLength < 52 )
    {
        DBGPRINT(RT_DEBUG_INFO,"Recv_Eapol :: handle_short_frame: (len=%d, left=%d)\n", lPacketLength,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;

⌨️ 快捷键说明

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