📄 cardif_macosx.c
字号:
/**
* Mac OS X card interface implementation.
*
* Licensed under a dual GPL/BSD license. (See LICENSE file for more info.)
*
* \file cardif_macosx.c
*
* \author Chris.Hessing@utah.edu with some code from the BSD implementation
* that was done by Fednando Schapachnik <fernando@mecon.gov.ar> and
* Ivan Voras <ivoras@fer.hr>.
*
* $Id: cardif_macosx.c,v 1.1.2.40 2007/08/14 22:12:29 galimorerpg Exp $
* $Date: 2007/08/14 22:12:29 $
*
**/
#ifdef MACOSX_FRAMER
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <ifaddrs.h>
#include <net/if_arp.h>
#include <net/if_media.h>
#include <net/ethernet.h>
#include <net/ndrv.h>
#include <net/route.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
#include <resolv.h>
#include <netdb.h>
#include "xsupconfig_structs.h"
#include "xsupconfig.h"
#include "context.h"
#include "config_ssid.h"
#include "cardif/cardif.h"
#include "xsup_debug.h"
#include "xsup_err.h"
#include "snmp.h"
#include "statemachine.h"
#include "wireless_sm.h"
#include "xsup_common.h"
#include "event_core.h"
#include "eapol.h"
#include "interfaces.h"
#ifdef DARWIN_WIRELESS
#include "darwinwireless.h"
#endif
#include "cardif/macosx/cardif_macosx.h"
#include "cardif/macosx/cardif_macosx_wireless.h"
#include "cardif/macosx/ndrv_socket.h"
#include "timer.h"
#ifndef ETH_P_EAPOL
#define ETH_P_EAPOL 0x888e
#endif
/***********************************************
* Get the MAC address of an interface
***********************************************/
static int _getmac(char *dest, char *ifname) {
struct ifaddrs *ifap;
debug_printf(DEBUG_INT, "Looking for MAC address for %s!\n", ifname);
if (getifaddrs(&ifap) == 0) {
struct ifaddrs *p;
for (p = ifap; p; p = p->ifa_next) {
if (p->ifa_addr->sa_family == AF_LINK && strcmp(p->ifa_name, ifname) == 0) {
struct sockaddr_dl* sdp = (struct sockaddr_dl*) p->ifa_addr;
memcpy(dest, sdp->sdl_data + sdp->sdl_nlen, 6);
// printf("I think I saw a MAC address: %s: %x:%x:%x:%x:%x:%x\n", p->ifa_name, dest[0], dest[1], dest[2], dest[3], dest[4], dest[5]);
freeifaddrs(ifap);
return TRUE;
}
}
freeifaddrs(ifap);
}
return FALSE;
}
static int _getiff(char *ifname, int *flags) {
struct ifaddrs *ifa_master, *ifa;
getifaddrs(&ifa_master);
for (ifa = ifa_master; ifa; ifa = ifa->ifa_next) {
if (ifa->ifa_addr->sa_family == AF_LINK && strcmp(ifa->ifa_name, ifname) == 0)
break;
}
if (ifa == NULL)
return FALSE;
*flags = ifa->ifa_flags;
freeifaddrs(ifa_master);
return TRUE;
}
// Define this, so the compiler doesn't complain.
extern unsigned int if_nametoindex(const char *);
// This contains a pointer to the functions needed for wireless.
struct cardif_funcs *wireless;
/***********************************************
*
* Determine if we are currently associated.
*
***********************************************/
int cardif_check_associated(context *intdata)
{
debug_printf(DEBUG_INT, "%s not implemented.\n", __FUNCTION__);
return -1;
}
/***********************************************
*
* Set up the wireless cardif_funcs structure to the driver that the user
* has requested.
*
***********************************************/
void cardif_set_driver(char driver)
{
#ifndef DARWIN_WIRELESS
switch (driver)
{
case DRIVER_NONE:
wireless = NULL;
break;
default:
debug_printf(DEBUG_NORMAL, "Unknown driver id of %d!\n", driver);
break;
}
#else
wireless = &cardif_macosx_wireless_driver;
#endif
}
/***********************************************
*
* Do whatever is needed to get the interface in to a state that we can send
* and recieve frames on the network. Any information that we need to later
* use should be stored in the context structure.
*
***********************************************/
int cardif_init(context *ctx, char driver)
{
struct darwin_sock_data *sockData;
struct config_globals *globals;
if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE))
return -1;
globals = config_get_globals();
if (globals == NULL)
{
debug_printf(DEBUG_NORMAL, "No valid configuration globals available!\n");
return XEGENERROR;
}
ctx->sockData = (void *)malloc(sizeof(struct darwin_sock_data));
if (ctx->sockData == NULL)
{
debug_printf(DEBUG_NORMAL, "Couldn't allocate memory for socket "
"data in %s()!\n", __FUNCTION__);
return XEMALLOC;
}
memset(ctx->sockData, 0x00, sizeof(struct darwin_sock_data));
sockData = (struct darwin_sock_data *)ctx->sockData;
// Set up wireless card drivers.
cardif_set_driver(driver);
// Set up wireless data.
#ifdef DARWIN_WIRELESS
if (cardif_int_is_wireless(ctx) == TRUE)
{
debug_printf(DEBUG_INT, "Interface is wireless.\n");
ctx->intType = ETH_802_11_INT;
if (context_create_wireless_ctx((wireless_ctx **)&ctx->intTypeData, 0) != XENONE)
{
debug_printf(DEBUG_NORMAL, "Couldn't create wireless context for "
"interface!\n");
return -1;
}
darwin_init_wireless(&sockData->wireless_blob);
}
cardif_disassociate(ctx, 0);
#endif
debug_printf(DEBUG_INT, "Initializing frame socket for interface %s..\n",
ctx->intName);
// Find out what the interface index is.
// ctx->intIndex = if_nametoindex(ctx->intName);
// debug_printf(DEBUG_INT, "Index : %d\n", ctx->intIndex);
// Get our MAC address. (Needed for sending frames out correctly.)
if (!_getmac(ctx->source_mac, ctx->intName)) {
debug_printf(DEBUG_INT, "Cannot get MAC address\n");
return XENOSOCK;
}
// Establish a socket handle.
sockData->sockInt = ndrv_socket(ctx->intName);
if (sockData->sockInt < 0)
{
debug_printf(DEBUG_NORMAL,
"Couldn't initialize socket for interface %s!\n",
ctx->intName);
debug_printf(DEBUG_NORMAL, "\n\nIt is likely that the native Mac OS X "
"supplicant is already running. If it is, then "
"Xsupplicant won't be able to start. You should kill all "
"instances of 'eapolclient' and try again.\n");
return XENOSOCK;
}
if (ndrv_socket_bind(sockData->sockInt, EAPOL_802_1_X_FAMILY, ETH_P_EAPOL) < 0)
{
debug_printf(DEBUG_NORMAL, "Couldn't bind to ndrv socket!\n");
return XENOSOCK;
}
ctx->sendframe = malloc(FRAMESIZE);
if (ctx->sendframe == NULL)
{
debug_printf(DEBUG_NORMAL, "Couldn't allocate memory to store frames to "
"be sent!\n");
return XEMALLOC;
}
memset(ctx->sendframe, 0x00, FRAMESIZE);
ctx->send_size = 0;
event_core_register(cardif_get_socket(ctx), ctx, eapol_withframe,
LOW_PRIORITY, "frame handler");
return XENONE;
}
/**************************************************************
*
* Tell the wireless card to start scanning for wireless networks.
*
**************************************************************/
int cardif_do_wireless_scan(context *thisint, char passive)
{
if (wireless == NULL) return -1;
if (wireless->scan == NULL)
{
debug_printf(DEBUG_INT, "%s not implemented.\n", __FUNCTION__);
return -1;
}
return wireless->scan(thisint, passive);
}
/**************************************************************
*
* Send a disassociate message.
*
**************************************************************/
int cardif_disassociate(context *thisint, int reason_code)
{
if (wireless == NULL)
{
printf("No wireless handler found!\n");
return -1;
}
if (wireless->disassociate == NULL)
{
debug_printf(DEBUG_INT, "%s not implemented.\n", __FUNCTION__);
return -1;
}
return wireless->disassociate(thisint, reason_code);
}
/******************************************
*
* Return the socket number for functions that need it.
*
******************************************/
int cardif_get_socket(context *ctx)
{
struct darwin_sock_data *sockData;
if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE))
return -1;
if (!xsup_assert((ctx->sockData != NULL), "ctx->sockData != NULL", FALSE))
return -1;
sockData = (struct darwin_sock_data *)ctx->sockData;
return sockData->sockInt;
}
/******************************************
*
* Clean up anything that was created during the initialization and operation
* of the interface. This will be called before the program terminates.
*
******************************************/
int cardif_deinit(context *thisint)
{
debug_printf(DEBUG_INT | DEBUG_DEINIT, "Cleaning up interface %s...\n",thisint->intName);
struct darwin_sock_data *sockData;
sockData= (struct darwin_sock_data *) thisint->sockData;
#ifdef DARWIN_WIRELESS
darwin_deinit_wireless(sockData->wireless_blob);
#endif
/*
// Check if we want ALLMULTI mode, and enable it.
if (TEST_FLAG(thisint->flags, ALLMULTI))
{
// Tell the ifreq struct which interface we want to use.
Strncpy((char *)&ifr.ifr_name, thisint->intName, sizeof(ifr.ifr_name));
if (ioctl(sockData->sockInt, SIOCGIFFLAGS, &ifr) < 0)
{
debug_printf(DEBUG_NORMAL, "Couldn't get interface flags!\n");
} else {
// Check if allmulti was disabled when we started. If it was,
// then disable it again, so everything is good.
if (!(thisint->flags & ALLMULTI))
{
debug_printf(DEBUG_INT, "Turning off ALLMULTI mode!\n");
ifr.ifr_flags &= ~IFF_ALLMULTI;
if (ioctl(sockData->sockInt, SIOCSIFFLAGS, &ifr) < 0)
{
debug_printf(DEBUG_NORMAL, "Couldn't set ALLMULTI mode on this interface! We will continue anyway!\n");
}
}
}
}
*/
close(sockData->sockInt);
FREE(thisint->sockData);
return XENONE;
}
/******************************************
*
* Set a WEP key. Also, based on the index, we may change the transmit
* key.
*
******************************************/
int cardif_set_wep_key(context *thisint, uint8_t *key,
int keylen, int index)
{
if (wireless == NULL) return -1;
if (wireless->set_wep_key == NULL)
{
debug_printf(DEBUG_INT, "set_wep_key not implemented.\n");
return -1;
}
return wireless->set_wep_key(thisint, key, keylen, index);
}
/**********************************************************
*
* Set a TKIP key.
*
**********************************************************/
int cardif_set_tkip_key(context *thisint, char *addr,
int keyidx, int settx, char *key, int keylen)
{
if (wireless == NULL) return -1;
if (wireless->set_tkip_key == NULL)
{
debug_printf(DEBUG_INT, "set_tkip_key not implemented.\n");
return -1;
}
return wireless->set_tkip_key(thisint, (uint8_t *)addr, keyidx, settx, key,
keylen);
}
/**********************************************************
*
* Set a CCMP (AES) key
*
**********************************************************/
int cardif_set_ccmp_key(context *thisint, char *addr, int keyidx,
int settx, char *key, int keylen)
{
if (wireless == NULL) return -1;
if (wireless->set_ccmp_key == NULL)
{
debug_printf(DEBUG_INT, "set_ccmp_key not implemented.\n");
return -1;
}
return wireless->set_ccmp_key(thisint, (uint8_t *)addr, keyidx, settx, key,
keylen);
}
/**********************************************************
*
* Delete a key
*
**********************************************************/
int cardif_delete_key(context *intdata, int key_idx, int set_tx)
{
if (wireless == NULL) return -1;
if (wireless->delete_key == NULL)
{
debug_printf(DEBUG_INT, "delete_key not implemented.\n");
return -1;
}
return wireless->delete_key(intdata, key_idx, set_tx);
}
/******************************************
*
* If our association timer expires, we need to attempt to associate again.
*
******************************************/
void cardif_association_timeout_expired(context *intdata)
{
// And try to associate again.
cardif_associate(intdata);
}
/******************************************
*
* Do whatever we need to do in order to associate based on the flags in
* the ssids_list struct.
*
******************************************/
void cardif_associate(context *intdata)
{
if (intdata == NULL)
{
debug_printf(DEBUG_NORMAL, "Invalid interface struct passed to %s!\n",
__FUNCTION__);
return;
}
if (wireless == NULL) return;
if (wireless->associate == NULL)
{
debug_printf(DEBUG_INT, "%s not implemented.\n", __FUNCTION__);
return;
}
wireless->associate(intdata);
}
/******************************************
*
* Ask the wireless card for the ESSID that we are currently connected to. If
* this is not a wireless card, or the information is not available, we should
* return an error.
*
* @param[in] ssidsize The size of the ssid_name buffer.
******************************************/
int cardif_GetSSID(context *thisint, char *ssid_name, unsigned int ssidsize)
{
if (wireless == NULL)
{
debug_printf(DEBUG_NORMAL, "No valid call to get SSID for this driver!"
"\n");
return -1;
}
if ((thisint == NULL) || (ssid_name == NULL))
{
debug_printf(DEBUG_INT, "NULL value passed to %s!\n", __FUNCTION__);
return -1;
}
if (wireless->get_ssid == NULL)
{
debug_printf(DEBUG_INT, "%s not implemented.\n", __FUNCTION__);
return -1;
}
return wireless->get_ssid(thisint, ssid_name, ssidsize);
}
/******************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -