osl-linux.c
来自「Vista 核心Rally技术之-LLTD 实现源代码」· C语言 代码 · 共 1,126 行 · 第 1/3 页
C
1,126 行
fclose(netdev);
return FALSE;
}
/* see if there's an optional ":DIGITS" virtual interface here */
p = colon+1;
while (isdigit(*p))
p++;
if (*p == ':')
*p = '\0'; /* virtual interface name */
else
*colon = '\0'; /* normal interface name */
fn(name, state);
}
if (ferror(netdev))
{
warn("foreach_interface: error during reading of /proc/net/dev\n");
fclose(netdev);
return FALSE;
}
#if CAN_FOPEN_IN_SELECT_LOOP
fclose(netdev);
#endif
return TRUE;
}
/* Recipe from section 1.7 of the Unix Programming FAQ */
/* http://www.erlenstar.demon.co.uk/unix/faq_toc.html */
void
osl_become_daemon(osl_t *osl)
{
/* 1) fork */
pid_t pid = fork();
if (pid == -1)
die("osl_become_daemon: fork to drop process group leadership failed: %s\n",
strerror(errno));
if (pid != 0)
exit(0); /* parent exits; child continues */
/* we are now guaranteed not to be a process group leader */
/* 2) setsid() */
pid = setsid();
if (pid == -1)
die("osl_become_daemon: setsid failed?!: %s\n", strerror(errno));
/* we are now the new group leader, and have successfully
* jettisonned our controlling terminal - hooray! */
/* 3) fork again */
pid = fork();
if (pid == -1)
die("osl_become_daemon: fork to lose group leadership (again) failed: %s\n",
strerror(errno));
if (pid != 0)
exit(0); /* parent exits; child continues */
/* we now have no controlling terminal, and are not a group leader
(and thus have no way of acquiring a controlling terminal). */
/* 4) chdir("/") */
if (chdir("/") != 0)
die("osl_become_daemon: chdir(\"/\") failed: %s\n", strerror(errno));
/* this allows admins to umount filesystems etc since we're not
* keeping them busy.*/
/* 5) umask(0) */
umask(0); /* if we create any files, we specify full mode bits */
/* 6) close fds */
/* 7) re-establish stdin/out/err to logfiles or /dev/console as needed */
}
/************************* E X T E R N A L S f o r T L V _ G E T _ F N s ***************************/
#define TLVDEF(_type, _name, _repeat, _number, _access, _inHello) \
extern int get_ ## _name (void *data);
#include "tlvdef.h"
#undef TLVDEF
/********************** T L V _ G E T _ F N s ******************************/
/* Return a 6-byte identifier which will be unique and consistent for
* this host, across all of its interfaces. Here we enumerate all the
* interfaces that are up and have assigned Ethernet addresses, and
* pick the lowest of them to represent this host. */
int
get_hostid(void *data)
{
/* TLVDEF( etheraddr_t, hostid, , 1, Access_unset ) */
etheraddr_t *hid = (etheraddr_t*) data;
memcpy(hid,&Etheraddr_broadcast,sizeof(etheraddr_t));
if (!foreach_interface(pick_lowest_address, hid))
{
if (TRACE(TRC_TLVINFO))
dbgprintf("get_hostid(): FAILED picking lowest address.\n");
return TLV_GET_FAILED;
}
if (ETHERADDR_EQUALS(hid, &Etheraddr_broadcast))
{
if (TRACE(TRC_TLVINFO))
dbgprintf("get_hostid(): FAILED, because chosen hostid = broadcast address\n");
return TLV_GET_FAILED;
} else {
if (TRACE(TRC_TLVINFO))
dbgprintf("get_hostid: hostid=" ETHERADDR_FMT "\n", ETHERADDR_PRINT(hid));
return TLV_GET_SUCCEEDED;
}
}
int
get_net_flags(void *data)
{
/* TLVDEF( uint32_t, net_flags, , 2, Access_unset ) */
uint32_t nf;
#define fLP 0x08000000 // Looping back outbound packets, if set
#define fMW 0x10000000 // Has management web page accessible via HTTP, if set
#define fFD 0x20000000 // Full Duplex if set
#define fNX 0x40000000 // NAT private-side if set
#define fNP 0x80000000 // NAT public-side if set
/* If your device has a management page at the url
http://<device-ip-address>/
then use the fMW flag, otherwise, remove it */
nf = htonl(fFD | fMW);
memcpy(data,&nf,4);
return TLV_GET_SUCCEEDED;
}
int
get_physical_medium(void *data)
{
/* TLVDEF( uint32_t, physical_medium, , 3, Access_unset ) */
uint32_t pm;
pm = htonl(6); // "ethernet"
memcpy(data,&pm,4);
return TLV_GET_SUCCEEDED;
}
#ifdef HAVE_WIRELESS
/* Return TRUE on successful query, setting "wireless_mode" to:
* 0 = ad-hoc mode
* 1 = infrastructure mode ie ESS (Extended Service Set) mode
* 2 = auto/unknown (device may auto-switch between ad-hoc and infrastructure modes)
*/
int
get_wireless_mode(void *data)
{
/* TLVDEF( uint32_t, wireless_mode, , 4, Access_unset ) */
uint32_t* wl_mode = (uint32_t*) data;
int rqfd;
struct iwreq req;
int ret;
memset(&req, 0, sizeof(req));
strncpy(req.ifr_ifrn.ifrn_name, g_osl->wireless_if, sizeof(req.ifr_ifrn.ifrn_name));
//*/printf("get_wireless_mode: requesting addr for interface \'%s\'\n",g_osl->wireless_if);
rqfd = socket(AF_INET,SOCK_DGRAM,0);
if (rqfd<0)
{
warn("get_wireless_mode: FAILED creating request socket for \'%s\' : %s\n",g_osl->wireless_if,strerror(errno));
return FALSE;
}
ret = ioctl(rqfd, SIOCGIWMODE, &req);
close(rqfd);
if (ret != 0)
{
/* We don't whine about "Operation Not Supported" since that
* just means the interface does not have wireless extensions. */
if (errno != EOPNOTSUPP && errno != EFAULT)
warn("get_wireless_mode: get associated Access Point MAC failed: Error %d, %s\n",
errno,strerror(errno));
return TLV_GET_FAILED;
}
switch (req.u.mode) {
case IW_MODE_AUTO:
*wl_mode = 2;
break;
case IW_MODE_ADHOC:
*wl_mode = 0;
break;
case IW_MODE_INFRA:
*wl_mode = 1;
break;
case IW_MODE_MASTER:
*wl_mode = 1;
break;
case IW_MODE_REPEAT:
*wl_mode = 1;
break;
case IW_MODE_SECOND:
*wl_mode = 1;
break;
default:
/* this is a wireless device that is probably acting
* as a listen-only monitor; we can't express its features like
* this, so we'll not return a wireless mode TLV. */
IF_TRACED(TRC_TLVINFO)
printf("get_wireless_mode(): mode (%d) unrecognizable - FAILING the get...\n", req.u.mode);
END_TRACE
return TLV_GET_FAILED;
}
IF_TRACED(TRC_TLVINFO)
printf("get_wireless_mode(): wireless_mode=%d\n", *wl_mode);
END_TRACE
return TLV_GET_SUCCEEDED;
}
/* If the interface is 802.11 wireless in infrastructure mode, and it
* has successfully associated to an AP (Access Point) then it will
* have a BSSID (Basic Service Set Identifier), which is usually the
* AP's MAC address.
* Of course, this code resides in an AP, so we just return the AP's
* BSSID. */
int
get_bssid(void *data)
{
/* TLVDEF( etheraddr_t, bssid, , 5, Access_unset ) */
etheraddr_t* bssid = (etheraddr_t*) data;
struct iwreq req;
int ret;
memset(&req, 0, sizeof(req));
strncpy(req.ifr_ifrn.ifrn_name, g_osl->wireless_if, sizeof(req.ifr_ifrn.ifrn_name));
ret = ioctl(g_osl->sock, SIOCGIWAP, &req);
if (ret != 0)
{
/* We don't whine about "Operation Not Supported" since that
* just means the interface does not have wireless extensions. */
if (errno != EOPNOTSUPP)
warn("get_bssid: get associated Access Point MAC failed: %s\n",
strerror(errno));
return TLV_GET_FAILED;
}
if (req.u.ap_addr.sa_family != ARPHRD_ETHER)
{
warn("get_bssid: expecting Ethernet address back, not sa_family=%d\n",
req.u.ap_addr.sa_family);
return TLV_GET_FAILED;
}
memcpy(bssid, req.u.ap_addr.sa_data, sizeof(etheraddr_t));
IF_TRACED(TRC_TLVINFO)
printf("get_bssid(): bssid=" ETHERADDR_FMT "\n", ETHERADDR_PRINT(bssid));
END_TRACE
return TLV_GET_SUCCEEDED;
}
int
get_ssid(void *data)
{
/* TLVDEF( ssid_t, ssid, , 6, Access_unset ) */
// ssid_t* ssid = (ssid_t*) data;
return TLV_GET_FAILED;
}
#endif /* HAVE_WIRELESS */
int
get_ipv4addr(void *data)
{
/* TLVDEF( ipv4addr_t, ipv4addr, , 7, Access_unset ) */
int rqfd, ret;
struct ifreq req;
ipv4addr_t* ipv4addr = (ipv4addr_t*) data;
char dflt_if[] = {"br0"};
char *interface = g_interface;
if (interface == NULL) interface = dflt_if;
memset(&req, 0, sizeof(req));
strncpy(req.ifr_name, interface, sizeof(req.ifr_name));
rqfd = socket(AF_INET,SOCK_DGRAM,0);
if (rqfd<0)
{
warn("get_ipv4addr: FAILED creating request socket for \'%s\' : %s\n",interface,strerror(errno));
return TLV_GET_FAILED;
}
ret = ioctl(rqfd, SIOCGIFADDR, &req);
if (ret < 0)
{
warn("get_ipv4addr(%d,%s): FAILED : %s\n", rqfd, interface, strerror(errno));
return TLV_GET_FAILED;
}
close(rqfd);
IF_DEBUG
/* Interestingly, the ioctl to get the ipv4 address returns that
address offset by 2 bytes into the buf. Leaving this in case
one of the ports results in a different offset... */
unsigned char *d;
d = (unsigned char*)req.ifr_addr.sa_data;
/* Dump out the whole 14-byte buffer */
printf("get_ipv4addr: sa_data = 0x%02x-0x%02x-0x%02x-0x%02x-0x%02x-0x%02x-0x%02x-0x%02x-0x%02x-0x%02x-0x%02x-0x%02x-0x%02x-0x%02x\n",d[0],d[1],d[2],d[3],d[4],d[5],d[6],d[7],d[8],d[9],d[10],d[11],d[12],d[13]);
END_DEBUG
memcpy(ipv4addr,&req.ifr_addr.sa_data[2],sizeof(ipv4addr_t));
IF_DEBUG
printf("get_ipv4addr: returning %d.%d.%d.%d as ipv4addr\n", \
*((uint8_t*)ipv4addr),*((uint8_t*)ipv4addr +1), \
*((uint8_t*)ipv4addr +2),*((uint8_t*)ipv4addr +3));
END_DEBUG
return TLV_GET_SUCCEEDED;
}
int
get_ipv6addr(void *data)
{
/* TLVDEF( ipv6addr_t, ipv6addr, , 8, Access_unset ) */
ipv6addr_t* ipv6addr = (ipv6addr_t*) data;
return TLV_GET_FAILED;
}
int
get_max_op_rate(void *data)
{
/* TLVDEF( uint16_t, max_op_rate, , 9, Access_unset ) units of 0.5 Mbs */
uint16_t morate;
morate = htons(108); /* (OpenWRT, 802.11g) 54 Mbs / 0.5 Mbs = 108 */
memcpy(data, &morate, 2);
return TLV_GET_SUCCEEDED;
}
int
get_tsc_ticks_per_sec(void *data)
{
/* TLVDEF( uint64_t, tsc_ticks_per_sec, , 0xA, Access_unset ) */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?