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

📄 driver_prism54.c

📁 最新的Host AP 新添加了许多pcmcia 的驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * hostapd / Driver interaction with Prism54 PIMFOR interface * Copyright (c) 2004, Bell Kin <bell_kin@pek.com.tw> * based on hostap driver.c, ieee802_11.c * Copyright (c) 2002-2007, Jouni Malinen <j@w1.fi> * * 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. * * Alternatively, this software may be distributed under the terms of BSD * license. * * See README and COPYING for more details. */#include "includes.h"#include <sys/ioctl.h>#include <sys/select.h>#ifdef USE_KERNEL_HEADERS/* compat-wireless does not include linux/compiler.h to define __user, so * define it here */#ifndef __user#define __user#endif /* __user */#include <asm/types.h>#include <linux/if_packet.h>#include <linux/if_ether.h>   /* The L2 protocols */#include <linux/if_arp.h>#include <linux/wireless.h>#else /* USE_KERNEL_HEADERS */#include <net/if_arp.h>#include <netpacket/packet.h>#include "wireless_copy.h"#endif /* USE_KERNEL_HEADERS */#include "hostapd.h"#include "driver.h"#include "ieee802_1x.h"#include "eloop.h"#include "ieee802_11.h"#include "prism54.h"#include "wpa.h"#include "radius/radius.h"#include "sta_info.h"#include "accounting.h"const int PIM_BUF_SIZE = 4096;struct prism54_driver_data {	struct hostapd_data *hapd;	char iface[IFNAMSIZ + 1];	int sock; /* raw packet socket for 802.3 access */	int pim_sock; /* socket for pimfor packet */	char macs[2007][6];};static int mac_id_refresh(struct prism54_driver_data *data, int id, char *mac){	if (id < 0 || id > 2006) {		return -1;	}	memcpy(&data->macs[id][0], mac, ETH_ALEN);	return 0;}static char * mac_id_get(struct prism54_driver_data *data, int id){	if (id < 0 || id > 2006) {		return NULL;	}	return &data->macs[id][0];}/* wait for a specific pimfor, timeout in 10ms resolution *//* pim_sock must be non-block to prevent dead lock from no response *//* or same response type in series */static int prism54_waitpim(void *priv, unsigned long oid, void *buf, int len,			   int timeout){	struct prism54_driver_data *drv = priv;	struct timeval tv, stv, ctv;	fd_set pfd;	int rlen;	pimdev_hdr *pkt;	pkt = malloc(8192);	if (pkt == NULL)		return -1;	FD_ZERO(&pfd);	gettimeofday(&stv, NULL);	do {		FD_SET(drv->pim_sock, &pfd);		tv.tv_sec = 0;		tv.tv_usec = 10000;		if (select(drv->pim_sock + 1, &pfd, NULL, NULL, &tv)) {			rlen = recv(drv->pim_sock, pkt, 8192, 0);			if (rlen > 0) {				if (pkt->oid == htonl(oid)) {					if (rlen <= len) {						if (buf != NULL) {							memcpy(buf, pkt, rlen);						}						free(pkt);						return rlen;					} else {						printf("buffer too small\n");						free(pkt);						return -1;					}				} else {					gettimeofday(&ctv, NULL);					continue;				}			}		}		gettimeofday(&ctv, NULL);	} while (((ctv.tv_sec - stv.tv_sec) * 100 +		  (ctv.tv_usec - stv.tv_usec) / 10000) > timeout);	free(pkt);	return 0;}/* send an eapol packet */static int prism54_send_eapol(void *priv, const u8 *addr,			      const u8 *data, size_t data_len, int encrypt,			      const u8 *own_addr){	struct prism54_driver_data *drv = priv;	ieee802_3_hdr *hdr;	size_t len;	u8 *pos;	int res;	len = sizeof(*hdr) + data_len;	hdr = os_zalloc(len);	if (hdr == NULL) {		printf("malloc() failed for prism54_send_data(len=%lu)\n",		       (unsigned long) len);		return -1;	}	memcpy(&hdr->da[0], addr, ETH_ALEN);	memcpy(&hdr->sa[0], own_addr, ETH_ALEN);	hdr->type = htons(ETH_P_PAE);	pos = (u8 *) (hdr + 1);	memcpy(pos, data, data_len);	res = send(drv->sock, hdr, len, 0);	free(hdr);	if (res < 0) {		perror("hostapd_send_eapol: send");		printf("hostapd_send_eapol - packet len: %lu - failed\n",		       (unsigned long) len);	}	return res;}/* open data channel(auth-1) or eapol only(unauth-0) */static int prism54_set_sta_authorized(void *priv, const u8 *addr,				      int authorized){	struct prism54_driver_data *drv = priv;	pimdev_hdr *hdr;	char *pos;	hdr = malloc(sizeof(*hdr) + ETH_ALEN);	if (hdr == NULL)		return -1;	hdr->op = htonl(PIMOP_SET);	if (authorized) {		hdr->oid = htonl(DOT11_OID_EAPAUTHSTA);	} else {		hdr->oid = htonl(DOT11_OID_EAPUNAUTHSTA);	}	pos = (char *) (hdr + 1);	memcpy(pos, addr, ETH_ALEN);	send(drv->pim_sock, hdr, sizeof(*hdr) + ETH_ALEN, 0);	prism54_waitpim(priv, hdr->oid, hdr, sizeof(*hdr) + ETH_ALEN, 10);	free(hdr);	return 0;}static intprism54_sta_set_flags(void *priv, const u8 *addr, int total_flags,		      int flags_or, int flags_and){	/* For now, only support setting Authorized flag */	if (flags_or & WLAN_STA_AUTHORIZED)		return prism54_set_sta_authorized(priv, addr, 1);	if (flags_and & WLAN_STA_AUTHORIZED)		return prism54_set_sta_authorized(priv, addr, 0);	return 0;}/* set per station key */static int prism54_set_encryption(const char *ifname, void *priv,				  const char *alg, const u8 *addr,				  int idx, const u8 *key, size_t key_len,				  int txkey){	struct prism54_driver_data *drv = priv;	pimdev_hdr *hdr;	struct obj_stakey *keys;	u8 *buf;	size_t blen;	int ret = 0;	blen = sizeof(struct obj_stakey) + sizeof(pimdev_hdr);	hdr = malloc(blen);	if (hdr == NULL) {		printf("memory low\n");		return -1;	}	keys = (struct obj_stakey *) &hdr[1];	if (!addr) {		memset(&keys->address[0], 0xff, ETH_ALEN);	} else {		memcpy(&keys->address[0], addr, ETH_ALEN);	}	if (!strcmp(alg, "WEP")) {		keys->type = DOT11_PRIV_WEP;	} else if (!strcmp(alg, "TKIP")) {		keys->type = DOT11_PRIV_TKIP;	} else if (!strcmp(alg, "none")) {		/* the only way to clear the key is to deauth it */		/* and prism54 is capable to receive unencrypted packet */		/* so we do nothing here */		free(hdr);		return 0;	} else {		printf("bad auth type: %s\n", alg);	}	buf = (u8 *) &keys->key[0];	keys->length = key_len;	keys->keyid = idx;	keys->options = htons(DOT11_STAKEY_OPTION_DEFAULTKEY);	keys->reserved = 0;	hdr->op = htonl(PIMOP_SET);	hdr->oid = htonl(DOT11_OID_STAKEY);	memcpy(buf, key, key_len);		ret = send(drv->pim_sock, hdr, blen, 0);	if (ret < 0) {		free(hdr);		return ret;	}	prism54_waitpim(priv, hdr->oid, hdr, blen, 10);	free(hdr);	return 0;}/* get TKIP station sequence counter, prism54 is only 6 bytes */static int prism54_get_seqnum(const char *ifname, void *priv, const u8 *addr,			      int idx, u8 *seq){	struct prism54_driver_data *drv = priv;	struct obj_stasc *stasc;	pimdev_hdr *hdr;	size_t blen;	int ret = 0;	blen = sizeof(*stasc) + sizeof(*hdr);	hdr = malloc(blen);	if (hdr == NULL)		return -1;	stasc = (struct obj_stasc *) &hdr[1];		if (addr == NULL)		memset(&stasc->address[0], 0xff, ETH_ALEN);	else		memcpy(&stasc->address[0], addr, ETH_ALEN);	hdr->oid = htonl(DOT11_OID_STASC);	hdr->op = htonl(PIMOP_GET);	stasc->keyid = idx;	if (send(drv->pim_sock,hdr,blen,0) <= 0) {		free(hdr);		return -1;	}	if (prism54_waitpim(priv, DOT11_OID_STASC, hdr, blen, 10) <= 0) {		ret = -1;	} else {		if (hdr->op == (int) htonl(PIMOP_RESPONSE)) {			memcpy(seq + 2, &stasc->sc_high, ETH_ALEN);			memset(seq, 0, 2);		} else {			ret = -1;		}	}	free(hdr);	return ret;}/* include unencrypted, set mlme autolevel to extended */static int prism54_init_1x(void *priv){	struct prism54_driver_data *drv = priv;	pimdev_hdr *hdr;	unsigned long *ul;	int blen = sizeof(*hdr) + sizeof(*ul);	hdr = malloc(blen);	if (hdr == NULL)		return -1;	ul = (unsigned long *) &hdr[1];	hdr->op = htonl(PIMOP_SET);	hdr->oid = htonl(DOT11_OID_EXUNENCRYPTED);	*ul = htonl(DOT11_BOOL_TRUE); /* not accept */	send(drv->pim_sock, hdr, blen, 0);	prism54_waitpim(priv, DOT11_OID_EXUNENCRYPTED, hdr, blen, 10);	hdr->op = htonl(PIMOP_SET);	hdr->oid = htonl(DOT11_OID_MLMEAUTOLEVEL);	*ul = htonl(DOT11_MLME_EXTENDED);	send(drv->pim_sock, hdr, blen, 0);	prism54_waitpim(priv, DOT11_OID_MLMEAUTOLEVEL, hdr, blen, 10);	hdr->op = htonl(PIMOP_SET);	hdr->oid = htonl(DOT11_OID_DOT1XENABLE);	*ul = htonl(DOT11_BOOL_TRUE);	send(drv->pim_sock, hdr, blen, 0);	prism54_waitpim(priv, DOT11_OID_DOT1XENABLE, hdr, blen, 10);	hdr->op = htonl(PIMOP_SET);	hdr->oid = htonl(DOT11_OID_AUTHENABLE);	*ul = htonl(DOT11_AUTH_OS); /* OS */	send(drv->pim_sock, hdr, blen, 0);	prism54_waitpim(priv, DOT11_OID_AUTHENABLE, hdr, blen, 10);	free(hdr);	return 0;}static int prism54_set_privacy_invoked(const char *ifname, void *priv,				       int flag){	struct prism54_driver_data *drv = priv;	pimdev_hdr *hdr;	unsigned long *ul;	int ret;	int blen = sizeof(*hdr) + sizeof(*ul);	hdr = malloc(blen);	if (hdr == NULL)		return -1;	ul = (unsigned long *) &hdr[1];	hdr->op = htonl(PIMOP_SET);	hdr->oid = htonl(DOT11_OID_PRIVACYINVOKED);	if (flag) {		*ul = htonl(DOT11_BOOL_TRUE); /* has privacy */	} else {		*ul = 0;	}	ret = send(drv->pim_sock, hdr, blen, 0);	if (ret >= 0) {		ret = prism54_waitpim(priv, DOT11_OID_PRIVACYINVOKED, hdr,				      blen, 10);	}	free(hdr);	return ret;} static int prism54_ioctl_setiwessid(const char *ifname, void *priv,				    const u8 *buf, int len){#if 0	struct prism54_driver_data *drv = priv;	struct iwreq iwr;	memset(&iwr, 0, sizeof(iwr));	os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);	iwr.u.essid.flags = 1; /* SSID active */	iwr.u.essid.pointer = (caddr_t) buf;	iwr.u.essid.length = len + 1;	if (ioctl(drv->pim_sock, SIOCSIWESSID, &iwr) < 0) {		perror("ioctl[SIOCSIWESSID]");		printf("len=%d\n", len);		return -1;	}#endif	return 0;}/* kick all stations *//* does not work during init, but at least it won't crash firmware */static int prism54_flush(void *priv){	struct prism54_driver_data *drv = priv;	struct obj_mlmeex *mlme;	pimdev_hdr *hdr;	int ret;	unsigned int i;	long *nsta;	int blen = sizeof(*hdr) + sizeof(*mlme);	char *mac_id;	hdr = os_zalloc(blen);	if (hdr == NULL)		return -1;	mlme = (struct obj_mlmeex *) &hdr[1];	nsta = (long *) &hdr[1];	hdr->op = htonl(PIMOP_GET);	hdr->oid = htonl(DOT11_OID_CLIENTS);	ret = send(drv->pim_sock, hdr, sizeof(*hdr) + sizeof(long), 0);	ret = prism54_waitpim(priv, DOT11_OID_CLIENTS, hdr, blen, 10);	if ((ret < 0) || (hdr->op != (int) htonl(PIMOP_RESPONSE)) ||	    (le_to_host32(*nsta) > 2007)) {		free(hdr);		return 0;	}	for (i = 0; i < le_to_host32(*nsta); i++) {		mlme->id = -1;		mac_id = mac_id_get(drv, i);		if (mac_id)			memcpy(&mlme->address[0], mac_id, ETH_ALEN);		mlme->code = host_to_le16(WLAN_REASON_UNSPECIFIED);		mlme->state = htons(DOT11_STATE_NONE);		mlme->size = 0;		hdr->op = htonl(PIMOP_SET);		hdr->oid = htonl(DOT11_OID_DISASSOCIATEEX);		ret = send(drv->pim_sock, hdr, blen, 0);		prism54_waitpim(priv, DOT11_OID_DISASSOCIATEEX, hdr, blen,				100);	}	for (i = 0; i < le_to_host32(*nsta); i++) {		mlme->id = -1;		mac_id = mac_id_get(drv, i);		if (mac_id)			memcpy(&mlme->address[0], mac_id, ETH_ALEN);		mlme->code = host_to_le16(WLAN_REASON_UNSPECIFIED);		mlme->state = htons(DOT11_STATE_NONE);		mlme->size = 0;		hdr->op = htonl(PIMOP_SET);		hdr->oid = htonl(DOT11_OID_DEAUTHENTICATEEX);		ret = send(drv->pim_sock, hdr, blen, 0);		prism54_waitpim(priv, DOT11_OID_DEAUTHENTICATEEX, hdr, blen,				100);	}	free(hdr);	return 0;}static int prism54_sta_deauth(void *priv, const u8 *addr, int reason){	struct prism54_driver_data *drv = priv;	pimdev_hdr *hdr;	struct obj_mlmeex *mlme;	int ret;	int blen = sizeof(*hdr) + sizeof(*mlme);	hdr = malloc(blen);	if (hdr == NULL)		return -1;	mlme = (struct obj_mlmeex *) &hdr[1];	hdr->op = htonl(PIMOP_SET);	hdr->oid = htonl(DOT11_OID_DEAUTHENTICATEEX);	memcpy(&mlme->address[0], addr, ETH_ALEN);	mlme->id = -1;	mlme->state = htons(DOT11_STATE_NONE);	mlme->code = host_to_le16(reason);	mlme->size = 0;	ret = send(drv->pim_sock, hdr, blen, 0);	prism54_waitpim(priv, DOT11_OID_DEAUTHENTICATEEX, hdr, blen, 10);	free(hdr);	return ret;}static int prism54_sta_disassoc(void *priv, const u8 *addr, int reason){	struct prism54_driver_data *drv = priv;        pimdev_hdr *hdr;        struct obj_mlmeex *mlme;	int ret;        int blen = sizeof(*hdr) + sizeof(*mlme);        hdr = malloc(blen);	if (hdr == NULL)		return -1;        mlme = (struct obj_mlmeex *) &hdr[1];        hdr->op = htonl(PIMOP_SET);        hdr->oid = htonl(DOT11_OID_DISASSOCIATEEX);        memcpy(&mlme->address[0], addr, ETH_ALEN);        mlme->id = -1;        mlme->state = htons(DOT11_STATE_NONE);        mlme->code = host_to_le16(reason);	mlme->size = 0;        ret = send(drv->pim_sock, hdr, blen, 0);        prism54_waitpim(priv, DOT11_OID_DISASSOCIATEEX, hdr, blen, 10);        free(hdr);        return ret;}static int prism54_get_inact_sec(void *priv, const u8 *addr){	struct prism54_driver_data *drv = priv;	pimdev_hdr *hdr;	struct obj_sta *sta;	int blen = sizeof(*hdr) + sizeof(*sta);	int ret;	hdr = malloc(blen);	if (hdr == NULL)		return -1;	hdr->op = htonl(PIMOP_GET);	hdr->oid = htonl(DOT11_OID_CLIENTFIND);	sta = (struct obj_sta *) &hdr[1];	memcpy(&sta->address[0], addr, ETH_ALEN);	ret = send(drv->pim_sock, hdr, blen, 0);	ret = prism54_waitpim(priv, DOT11_OID_CLIENTFIND, hdr, blen, 10);	if (ret != blen) {		printf("get_inact_sec: bad return %d\n", ret);		free(hdr);		return -1;	}	if (hdr->op != (int) htonl(PIMOP_RESPONSE)) {		printf("get_inact_sec: bad resp\n");		free(hdr);		return -1;	}	free(hdr);	return le_to_host16(sta->age);}

⌨️ 快捷键说明

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