给FreeBSD写了个802.1X认证客户端(见http:\\my.chinaunix.net\xdkui)
实验室里上网先要经过802.1X认证。网关用的FreeBSD,但没有找到其下面的认证客户端,所以自己写了个,基于BPF。还好BPF就是来自BSD,不需要libpcap和libnet就可以实现对数据链路层的控制。代码写的很烂,拿出来都嫌丢能,只能自己用^_^不过程序已用了几个月,可以正常工作。
主要文件mysupplicant.c部分代码如下(其实上层交换机是实达的,它的802.1X认证和标准的不同,添加了自己的认证算法,但因为某些原因不方便公开,所以本文中删除了实达认证算法的代码。有需要的话可以找一个程序mystarV0[1].1-src,感谢其作者netxray@byhh,里面对实达的认证机制分析的很详细。不过我用mystar里代码的时候还是有点问题,分析了些截获的认证数据包才搞定^_^):
#include <stdio.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/types.h>
#include <stdlib.h>
#include <sys/uio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <net/bpf.h>
#include <net/if.h>
#include <string.h>
#include <sys/select.h>
#include <signal.h>
#include "global.h"
#include "md5.h"
#define ETHERTYPE_8021X 0x888e
#define EAPOL_Packet 0x00
#define EAPOL_Start 0x01
#define EAPOL_Logoff 0x02
#define EAP_Request 1
#define EAP_Response 2
#define EAP_Success 3
#define EAP_Failure 4
#define EAP_TYPE_Identity 1
#define EAP_TYPE_MD5Challenge 4
typedef unsigned char int8;
typedef unsigned short int16;
typedef unsigned long int32;
struct bpf_insn insns[] = {
BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),//加载halfword以太网链路层的type
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ETHERTYPE_8021X, 0, 1),//判断是否是802.1X数据包,是则返回给本程序
BPF_STMT(BPF_RET+BPF_K, (u_int)-1),
BPF_STMT(BPF_RET+BPF_K, 0),
};
typedef struct EAPOLforEthernet//EAPOL在Ethernet上的帧格式
{
int16 ethertype;
int8 version;
int8 type;
int16 length;
}EAPOL;
typedef struct EAPformat//EAP的帧格式
{
int8 code;
int8 id;
int16 length;
int8 type;
}__attribute__((packed)) EAP;
typedef union
{
u_int32_t ulValue;
u_int8_t btValue[4];
}ULONG_BYTEARRAY;
ULONG_BYTEARRAY m_serialNo; //序列号,收到第一个有效的Authentication-Success-packet时初始化
ULONG_BYTEARRAY m_key; //密码加密键值,在main()函数开始时初始化
char standardMAC[6]=;//标准802.1X组播MAC地址
char name[7]="username";//用户名
会员注册
会员登录
个人空间