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

📄 cardif_freebsd.c

📁 linux 下通过802.1认证的安装包
💻 C
📖 第 1 页 / 共 2 页
字号:
/*******************************************************************
 * FreeBSD card interface implementation.
 *
 * Licensed under a dual GPL/BSD license.  (See LICENSE file for more info.)
 *
 * File: cardif_freebsd.c
 *
 * Authors: Fernando Schapachnik <fernando@mecon.gov.ar>, based
 * on the work of Ivan Voras <ivoras@fer.hr> and the Linux version by
 * Chris.Hessing@utah.edu.
 *
 * $Id: cardif_freebsd.c,v 1.8.2.6 2006/12/29 19:28:16 chessing Exp $
 * $Date: 2006/12/29 19:28:16 $
 * $Log: cardif_freebsd.c,v $
 * Revision 1.8.2.6  2006/12/29 19:28:16  chessing
 * Changes to bring Mac/Linux versions in sync with Windows work.
 *
 * Revision 1.8.2.5  2006/11/10 23:31:34  chessing
 * Replaced all malloc()+memset() with Malloc().
 *
 * Revision 1.8.2.4  2006/09/28 03:19:53  galimorerpg
 * Remove cruft: cardif_valid_dest.
 *
 * Revision 1.8.2.3  2006/09/28 03:09:31  galimorerpg
 * strncpy cleanups.
 *
 * Revision 1.8.2.2  2006/09/23 00:04:42  chessing
 * Changed free()+=NULL to FREE().
 *
 * Revision 1.8.2.1  2006/08/20 04:42:23  chessing
 * Can build under OS-X now.  Need to add wireless support.
 *
 * Revision 1.8  2006/06/01 22:49:49  galimorerpg
 * Converted all instances of u_char to uint8_t
 * Fixed a bad #include in the generic frame handler.
 *
 * Revision 1.7  2006/05/13 05:56:44  chessing
 * Removed last pieces of code that relied on SIGALRM.  Active scan timeout is now configurable so that people that wish to hammer on their cards now have the option to do that. ;)
 *
 * Revision 1.6  2006/01/19 05:37:04  chessing
 * WPA2 is working correctly.  Added the ability to query the card to gather encryption/authentication capabilities.  1.2.3 is now ready to go.
 *
 * Revision 1.5  2005/09/05 01:00:36  chessing
 * Major overhaul to most of the state machines in Xsupplicant.  Also added additional error messages to the TLS functions to try to debug the one of the problems reported on the list.  Basic testing shows this new code to be more stable than previous code, but it needs more testing.
 *
 * Revision 1.4  2005/08/25 03:34:05  chessing
 * Removed a bunch of functions from config.c that could be handled better in other ways.
 *
 * Revision 1.3  2005/08/25 02:20:20  chessing
 * Some cleanup in xsup_debug.c, added the ability to wait for an interface to come up if it is down when Xsupplicant is started.  Roughed in the ability to choose between having Xsupplicant auto associate you, or allow you to set the ssid manually.  The stale key timer can now be set in the config file.  The association timeout can be set in the config file, and will also be used once the functionality is in place to attempt to guess the key settings needed for association, as well as the functionality to auto associate.
 *
 * Revision 1.2  2005/08/09 01:39:14  chessing
 * Cleaned out old commit notes from the released version.  Added a few small features including the ability to disable the friendly warnings that are spit out.  (Such as the warning that is displayed when keys aren't rotated after 10 minutes.)  We should also be able to start when the interface is down.  Last, but not least, we can handle empty network configs.  (This may be useful for situations where there isn't a good reason to have a default network defined.)
 *
 *
 *******************************************************************/

#ifdef FREEBSD_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/bpf.h>

#include "config.h"
#include "context.h"
#include "config_ssid.h"
#include "xsup_common.h"
#include "cardif/cardif.h"
#include "xsup_debug.h"
#include "xsup_err.h"
#include "snmp.h"
#include "statemachine.h"
#include "cardif/freebsd/cardif_freebsd.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;

    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;
}

/* open a bpf device; return fd handle */
static int _bpf_setup(struct interface_data *idata) {
    char basedev[] = "/dev/bpf";
    char devname[15];
    int ndev = 0, fd;
    struct ifreq ifr;
    int one = 1, zero = 0;
    struct fbsd_sock_data *sockData;

    struct bpf_insn progcodes[] = {
        BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12), // inspect ethernet_frame_type
        BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ETH_P_EAPOL, 0, 1), // if EAPOL frame, continue with next instruction, else jump
        BPF_STMT(BPF_RET+BPF_K, (u_int)-1),
        BPF_STMT(BPF_RET+BPF_K, 0)
    };
    
    struct bpf_program prog = {
        4,
        (struct bpf_insn*) &progcodes
    };

    struct timeval tv;


    do {    // try and open a bpf device
        sprintf(devname, "%s%d", basedev, ndev);
        fd = open(devname, O_RDWR);
        ndev++;
    } while(fd < 0 && ndev < 15);

    if (fd < 0) {
        debug_printf(DEBUG_INT, "Cannot open a bpf device\n");
        return FALSE;
    };

    idata->sockData= Malloc(sizeof(struct fbsd_sock_data));
    if (idata->sockData == NULL) {
        debug_printf(DEBUG_INT, "malloc(%d) of sockData failed\n", sizeof(struct fbsd_sock_data));
        return FALSE;
    }
    sockData= (struct fbsd_sock_data *) idata->sockData;
    sockData->bpf = fd;

    if (ioctl(fd, BIOCGBLEN, &sockData->buf_size) < 0) {
        debug_printf(DEBUG_INT, "BIOCGBLEN failed\n");
        return FALSE;
    }
    
    Strncpy(ifr.ifr_name, idata->intName, IFNAMSIZ);
    if (ioctl(fd, BIOCSETIF, &ifr) < 0) {
        debug_printf(DEBUG_INT, "BIOCSETIF failed on %s\n", ifr.ifr_name);
        return FALSE;
    }

    sockData->buf = Malloc(sockData->buf_size);
    if (sockData->buf == NULL) {
        debug_printf(DEBUG_INT, "malloc(%d) of buf failed\n", sockData->buf_size);
        return FALSE;
    }

    if (ioctl(fd, BIOCIMMEDIATE, &one) < 0) {
        debug_printf(DEBUG_INT, "BIOCIMMEDIATE failed\n");
        return FALSE;
    }

    tv.tv_sec = 0;
    tv.tv_usec = 500000;
    if (ioctl(fd, BIOCSRTIMEOUT, &tv) < 0) {
        debug_printf(DEBUG_INT, "BIOCSRTIMEOUT failed\n");
        return FALSE;
    }

    if (ioctl(fd, BIOCSSEESENT, &zero) < 0) {
        debug_printf(DEBUG_INT, "BIOCSSEESENT failes\n");
        return FALSE;
    }

    if (ioctl(fd, BIOCSETF, &prog) < 0) {
        debug_printf(DEBUG_INT, "BIOCSETF failed\n");
        return FALSE;
    }

    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(struct interface_data *intdata)
{
  debug_printf(DEBUG_EXCESSIVE, "%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)
{
  switch (driver)
    {
    case DRIVER_NONE:
      wireless = NULL;
      break;

    /* No wireless drivers supported by now. */
    }
}

/***********************************************
 *
 * 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 interface_data structure.
 *
 ***********************************************/
int cardif_init(struct interface_data *thisint, char driver)
{
  struct ifreq ifr;
  struct fbsd_sock_data *sockData;
  struct config_globals *globals;

  if (thisint == NULL)
    {
      debug_printf(DEBUG_NORMAL, "Invalid interface data in %s!\n",
		   __FUNCTION__);
      return XEGENERROR;
    }
  
  globals = config_get_globals();

  if (globals == NULL)
    {
      debug_printf(DEBUG_NORMAL, "No valid configuration globals available!\n");
      return XEGENERROR;
    }

  debug_printf(DEBUG_INT, "Initializing bpf for interface %s..\n",
	       thisint->intName);

  // Keep track of which driver we were assigned.
  thisint->driver_in_use = driver;

  // Find out what the interface index is.
  thisint->intIndex = if_nametoindex(thisint->intName);
  debug_printf(DEBUG_INT, "Index : %d\n", thisint->intIndex);

  if (!_bpf_setup(thisint)) {
      debug_printf(DEBUG_INT, "--> Cannot setup bpf! This is fatal!\n");
      return XENOSOCK;
  }

  // Get our MAC address.  (Needed for sending frames out correctly.)
  if (!_getmac(thisint->source_mac, thisint->intName)) {
      debug_printf(DEBUG_INT, "Cannot get MAC address\n");
      return XENOSOCK;
  }

  // Establish a socket handle.
  sockData= (struct fbsd_sock_data *) thisint->sockData;
  sockData->sockInt = socket(AF_INET, SOCK_DGRAM, 0);
  if (sockData->sockInt < 0)
    {
      debug_printf(DEBUG_NORMAL, 
		   "Couldn't initialize socket for interface %s!\n",
		   thisint->intName);
      return XENOSOCK;
    }        

  // Check if we want ALLMULTI mode, and enable it.
  if (TEST_FLAG(globals->flags, CONFIG_GLOBALS_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 determine if ALLMULTI is enabled!\n");
	} else {
	  if (ifr.ifr_flags & IFF_ALLMULTI)
	    {
	      debug_printf(DEBUG_INT, "Allmulti mode is already enabled on this device!\n");
	      thisint->flags |= ALLMULTI;
	    } else {
	      debug_printf(DEBUG_INT, "Allmulti is currently disabled on this device!\n");
	      thisint->flags &= ~ALLMULTI;
	    }
	}

      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");
	}
    }

  // Set up wireless card drivers.
  cardif_set_driver(driver);

  if (!block_wpa) 
  {
    debug_printf(DEBUG_NORMAL, "WPA support not available!\n");
  } else {
    debug_printf(DEBUG_NORMAL, "Not turning on WPA support!\n");
  }

  return XENONE;
}

/**************************************************************
 *
 * Tell the wireless card to start scanning for wireless networks.
 *
 **************************************************************/
int cardif_do_wireless_scan(struct interface_data *thisint)
{
  if (wireless == NULL) return -1;

  debug_printf(DEBUG_EXCESSIVE, "%s not implemented.\n", __FUNCTION__);
  return -1;
}

/**************************************************************
 *
 * Send a disassociate message.
 *
 **************************************************************/
int cardif_disassociate(struct interface_data *thisint, int reason_code)
{
  if (wireless == NULL) return -1;
  debug_printf(DEBUG_EXCESSIVE, "%s not implemented.\n", __FUNCTION__);
  return -1;
}

/******************************************
 *
 * Return the socket number for functions that need it.
 *
 ******************************************/
int cardif_get_socket(struct interface_data *thisint)
{
  debug_printf(DEBUG_EXCESSIVE, "%s not needed in BSD.\n", __FUNCTION__);
  return 0;
}

/******************************************
 *
 * 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(struct interface_data *thisint)
{
  struct ifreq ifr;
  debug_printf(DEBUG_EVERYTHING, "Cleaning up interface %s...\n",thisint->intName);
  struct fbsd_sock_data *sockData;
  sockData= (struct fbsd_sock_data *) thisint->sockData;

  // 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);

  close(sockData->bpf);
  FREE(sockData->buf);
  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(struct interface_data *thisint, uint8_t *key, 
		       int keylen, int index)
{
  if (wireless == NULL) return -1;
  debug_printf(DEBUG_EXCESSIVE, "set_wep_key not implemented.\n");
  return -1;
}

/**********************************************************
 *
 * Set a TKIP key. 
 *
 **********************************************************/
int cardif_set_tkip_key(struct interface_data *thisint, char *addr, 
			      int keyidx, int settx, char *seq, int seqlen, 
			      char *key, int keylen)
{
  if (wireless == NULL) return -1;
  debug_printf(DEBUG_EXCESSIVE, "set_tkip_key not implemented.\n");
  return -1;
}

/**********************************************************
 *
 * Set a CCMP (AES) key
 *
 **********************************************************/
int cardif_set_ccmp_key(struct interface_data *thisint, char *addr, int keyidx,
			int settx, char *seq, int seqlen, char *key,
			int keylen)
{

⌨️ 快捷键说明

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