📄 cardif_macosx.c
字号:
return;
}
if (wireless == NULL) return;
if (wireless->associate == NULL)
{
debug_printf(DEBUG_INT, "%s not implemented.\n", __FUNCTION__);
return;
}
wireless->associate(intdata);
}
void cardif_get_abilities(context *intdata)
{
if (wireless == NULL)
{
debug_printf(DEBUG_INT, "%s not implemented!\n", __FUNCTION__);
return;
}
if (wireless->enc_capabilities == NULL)
{
debug_printf(DEBUG_INT, "%s not implemented!\n", __FUNCTION__);
return;
}
wireless->enc_capabilities(intdata);
}
void cardif_wait_for_int(char *intname)
{
// XXX Do we need to write something here? In most cases, people won't add
// additional interfaces to their machines. They just use what it comes with.
}
void cardif_passive_scan_timeout(context *ctx)
{
// Nothing to do here, since we don't support passive scanning on the Mac!
}
int cardif_enc_disable(context *ctx)
{
// The Airport API doesn't have an option to disable encryption.
return XENONE;
}
int cardif_wep_associate(context *ctx, int zeros)
{
if (wireless == NULL) return -1;
if (wireless->wep_associate == NULL)
{
debug_printf(DEBUG_INT, "%s not implemented!\n", __FUNCTION__);
return -1;
}
return wireless->wep_associate(ctx, zeros);
}
void cardif_operstate(context *ctx, uint8_t newstate)
{
// No operstate stuff for OS X.
}
/**
* \brief Determine if an interface is wireless based on it's name.
*
* @param[in] intname The interface name to check on.
*
* \retval TRUE if the interface is wireless
* \retval FALSE if the interface isn't wireless
*
* \todo Actually figure out if the interface is wireless or not, instead of
* just assuming it is interface en1!
**/
int is_wireless(char *intname)
{
#ifdef DARWIN_WIRELESS
// This is a hack for now.. Find something better!
if (strcmp(intname, "en1") == 0) return TRUE;
return FALSE;
#else
// If we aren't built with wireless, don't bother checking.
return FALSE;
#endif
}
/**
* \brief Enumerate all of the interfaces that are on the machine, and put
* them in the interface cache.
**/
void cardif_enum_ints()
{
struct if_nameindex *ifnames;
int i = 0;
char mac[6];
ifnames = if_nameindex();
if (ifnames == NULL)
{
debug_printf(DEBUG_NORMAL, "Got an error with if_nameindex() call!\n");
debug_printf(DEBUG_NORMAL, "Are there no interfaces on this machine?\n");
return;
}
while ((ifnames[i].if_index != 0) && (ifnames[i].if_name != NULL))
{
printf("Interface %d named %s.\n", ifnames[i].if_index, ifnames[i].if_name);
// Make sure we aren't looking at any loopback interfaces.
if (strcasestr(ifnames[i].if_name, "lo") == NULL)
{
if (_getmac((char *)&mac, ifnames[i].if_name) == TRUE)
{
// Add it to our interface cache!
interfaces_add(ifnames[i].if_name, ifnames[i].if_name, mac,
is_wireless(ifnames[i].if_name));
}
}
i++;
}
if_freenameindex(ifnames);
}
/**
* \brief Determine the signal strength (as a percentage) of the wireless
* connection.
*
* @param[in] ctx The context for the interface we want to get the signal
* strength for.
*
* \retval >=0 The signal strength for the context.
* \retval <0 An error.
**/
int cardif_get_signal_strength_percent(context *ctx)
{
if (!xsup_assert((ctx != NULL), "ctx != NULL", FALSE))
return -1;
if (wireless == NULL) return -1;
if (!wireless->get_signal_percent)
{
debug_printf(DEBUG_INT, "No function defined to get the signal strength!\n");
return -1;
}
return wireless->get_signal_percent(ctx);
}
struct ifaddrs *find_ip_int(context *ctx, struct ifaddrs *root)
{
struct ifaddrs *cur = NULL;
if (root == NULL) return NULL;
if (ctx == NULL) return NULL;
cur = root;
while (cur)
{
if ((strcmp(ctx->intName, cur->ifa_name) == 0) &&
(cur->ifa_addr->sa_family == AF_INET))
return cur;
cur = cur->ifa_next;
}
return NULL; // Not found!
}
/**
* \brief Return the IP address of the interface pointed to by ctx.
*
* @param[in] ctx The context for the interface we want to get information
* about.
*
* \retval NULL on error.
* \retval ptr to an IP address on success
**/
char *cardif_get_ip(context *ctx)
{
struct ifaddrs *ifs = NULL, *cur = NULL;
char *ipaddr = NULL;
if (ctx == NULL)
{
debug_printf(DEBUG_NORMAL, "Context is invalid!\n");
return NULL;
}
if (getifaddrs(&ifs) != 0)
{
debug_printf(DEBUG_NORMAL, "Couldn't get interface information!\n");
return NULL;
}
cur = find_ip_int(ctx, ifs);
if (cur == NULL)
{
debug_printf(DEBUG_NORMAL, "Couldn't locate IPv4 information for interface"
" %s!\n", ctx->intName);
freeifaddrs(ifs);
return NULL;
}
// The value returned by inet_ntoa() resides in a static buffer. So we need
// to make a copy of it.
ipaddr = strdup(inet_ntoa(((struct sockaddr_in *)(cur->ifa_addr))->sin_addr));
if (ipaddr == NULL)
{
debug_printf(DEBUG_NORMAL, "Couldn't convert IP address to a string!\n");
freeifaddrs(ifs);
return NULL;
}
debug_printf(DEBUG_INT, "Found IP address %s for interface %s.\n",
ipaddr, ctx->intName);
freeifaddrs(ifs);
return ipaddr;
}
char *cardif_get_netmask(context *ctx)
{
struct ifaddrs *ifs = NULL, *cur = NULL;
char *netmask = NULL;
if (ctx == NULL)
{
debug_printf(DEBUG_NORMAL, "Context is invalid!\n");
return NULL;
}
if (getifaddrs(&ifs) != 0)
{
debug_printf(DEBUG_NORMAL, "Couldn't get interface information!\n");
return NULL;
}
cur = find_ip_int(ctx, ifs);
if (cur == NULL)
{
debug_printf(DEBUG_NORMAL, "Couldn't locate IPv4 information for interface"
" %s!\n", ctx->intName);
freeifaddrs(ifs);
return NULL;
}
// The return value of inet_ntoa is a static buffer, so we need to make a
// copy of the resulting string.
netmask = strdup(inet_ntoa(((struct sockaddr_in *)(cur->ifa_netmask))->sin_addr));
if (netmask == NULL)
{
debug_printf(DEBUG_NORMAL, "Couldn't convert netmask to a string!\n");
freeifaddrs(ifs);
return NULL;
}
debug_printf(DEBUG_INT, "Found netmask %s for interface %s.\n",
netmask, ctx->intName);
freeifaddrs(ifs);
return netmask;
}
/**
* \brief Round up an integer to a multiple of 4.
*
* @param[in] a The integer value to round up.
*
* \retval int The multiple of 4.
**/
int div4(int a)
{
int t;
t = (a % 4);
if (t > 0)
{
t = a + (4 - t);
}
else
{
t = a;
}
return t;
}
/**
* \brief Determine the default gateway that is in use for this host.
*
* @param[in] ctx The context for the interface that we want to determine
* the default gateway for.
*
* \retval NULL on error
* \retval ptr to IP address of the default gateway on success.
**/
char *cardif_get_gw(context *ctx)
{
struct sockaddr *sockdata = NULL;
struct sockaddr_in *sin = NULL;
struct rt_msghdr *rtm = NULL;
char buf[512];
int seq = 0, s = 0, l = 0;
char *retval = NULL;
memset(&buf, 0x00, 512);
rtm = (struct rt_msghdr *)&buf[0];
rtm->rtm_type = RTM_GET;
rtm->rtm_flags = RTF_UP | RTF_GATEWAY;
rtm->rtm_version = RTM_VERSION;
rtm->rtm_seq = ++seq;
rtm->rtm_addrs = RTA_DST | RTA_NETMASK;
sockdata = (struct sockaddr *)&buf[div4(sizeof(struct rt_msghdr))];
sockdata->sa_family = AF_INET;
sockdata->sa_len = sizeof(struct sockaddr_in);
sockdata = (struct sockaddr *)&buf[div4(sizeof(struct rt_msghdr)) + div4(sizeof(struct sockaddr_in))];
sockdata->sa_family = AF_INET;
sockdata->sa_len = sizeof(struct sockaddr_in);
rtm->rtm_msglen = (div4(sizeof(struct sockaddr_in)) * 2) + div4(sizeof(struct rt_msghdr));;
s = socket(PF_ROUTE, SOCK_RAW, 0);
if (s < 0)
{
debug_printf(DEBUG_NORMAL, "Error getting RTNetlink socket!\n");
return NULL;
}
if (write(s, &buf, rtm->rtm_msglen) < 0)
{
debug_printf(DEBUG_NORMAL, "Error writing routing socket!\n");
debug_printf(DEBUG_NORMAL, "Error %d : %s\n", errno, strerror(errno));
return NULL;
}
do {
// Look for the proper sequence number for the response.
l = read(s, (char *)&buf, sizeof(buf));
} while ((l > 0) && (rtm->rtm_seq != seq));
close(s);
sin = (struct sockaddr_in *)&buf[div4(sizeof(struct rt_msghdr))];
sin = (struct sockaddr_in *)&buf[div4(sizeof(struct rt_msghdr)) + div4(sizeof(struct sockaddr_in))];
retval = strdup(inet_ntoa(sin->sin_addr));
debug_printf(DEBUG_INT, "Default Route : %s\n", retval);
return retval;
}
/**
* \brief Get the first DNS in our list.
*
* @param[in] ctx Get the DNS for the context listed.
*
* \retval NULL on error
* \retval ptr the first DNS
**/
char *cardif_get_dns1(context *ctx)
{
struct __res_state res;
int numservs = 0;
union res_sockaddr_union u[MAXNS];
char *retval = NULL;
if (res_ninit(&res) != 0)
{
debug_printf(DEBUG_NORMAL, "Couldn't init resolver library!\n");
return NULL;
}
numservs = res_getservers(&res, &u, MAXNS);
if (numservs < 1) return NULL;
retval = strdup(inet_ntoa(u[0].sin.sin_addr));
res_nclose(&res);
return retval;
}
/**
* \brief Get the first DNS in our list.
*
* @param[in] ctx Get the DNS for the context listed.
*
* \retval NULL on error
* \retval ptr the first DNS
**/
char *cardif_get_dns2(context *ctx)
{
struct __res_state res;
int numservs = 0;
union res_sockaddr_union u[MAXNS];
char *retval = NULL;
if (res_ninit(&res) != 0)
{
debug_printf(DEBUG_NORMAL, "Couldn't init resolver library!\n");
return NULL;
}
numservs = res_getservers(&res, &u, MAXNS);
if (numservs < 2) return NULL;
retval = strdup(inet_ntoa(u[1].sin.sin_addr));
res_nclose(&res);
return retval;
}
/**
* \brief Get the first DNS in our list.
*
* @param[in] ctx Get the DNS for the context listed.
*
* \retval NULL on error
* \retval ptr the first DNS
**/
char *cardif_get_dns3(context *ctx)
{
struct __res_state res;
int numservs = 0;
union res_sockaddr_union u[MAXNS];
char *retval = NULL;
if (res_ninit(&res) != 0)
{
debug_printf(DEBUG_NORMAL, "Couldn't init resolver library!\n");
return NULL;
}
numservs = res_getservers(&res, &u, MAXNS);
if (numservs < 3) return NULL;
retval = strdup(inet_ntoa(u[2].sin.sin_addr));
res_nclose(&res);
return retval;
}
/**
* \brief Determine in an interface is wireless based on it's OS specific
* interface name.
*
* @param[in] intname The OS specific interface name that we want to check
* to see if it is wireless.
*
* \retval TRUE if the interface is wireless
* \retval FALSE if the interface is *NOT* wireless
**/
int cardif_is_wireless_by_name(char *intname)
{
return is_wireless(intname);
}
/**
* \brief Determine the device description based on the OS specific interface
* name. For Darwin, the OS specific interface name, and the
* device description will be the same.
*
* @param[in] intname The OS specific interface name to search for.
*
* \retval NULL on error, or interface not found.
* \retval ptr to the interface description
**/
char *cardif_find_description(char *intname)
{
return strdup(intname);
}
/**
* \brief Get a string representation of an interface's MAC address based on the
* OS specific interface name.
*
* @param[in] intname The OS specific interface name for the interface we want \
to
* get information on.
*
* \retval NULL on error
* \retval ptr to MAC address string on success
**/
char *cardif_get_mac_str(char *intname)
{
uint8_t mac[6];
char *resmac = NULL;
if (_getmac((char *)&mac, intname) != TRUE) return NULL;
resmac = Malloc(25);
if (resmac == NULL) return NULL;
sprintf(resmac, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2]\
, mac[3],
mac[4], mac[5]);
return resmac;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -