📄 ctosl-linux.c
字号:
{
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 = (uint32_t*) data;
#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 | fNX | fMW);
return TLV_GET_SUCCEEDED;
}
int
get_physical_medium(void *data)
{
/* TLVDEF( uint32_t, physical_medium, , 3, Access_unset ) */
uint32_t* pm = (uint32_t*) data;
/* Since this interface is bridged, we should actually return two responses,
* one for the wireless, and one for the ethernet switch. It's probably OK to
* just say "ethernet" though... */
//!! *pm = htonl(71); // "wireless"
*pm = htonl(6); // "ethernet"
return TLV_GET_SUCCEEDED;
}
/* Note that most of the code in this block is not pertinent to the WRT, and has not been tested. In particular,
* there may be many cases of network byte order not being observed.... */
#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->interface, sizeof(req.ifr_ifrn.ifrn_name));
//*/printf("get_wireless_mode: requesting addr for interface \'%s\'\n",g_osl->interface);
rqfd = socket(AF_INET,SOCK_DGRAM,0);
if (rqfd<0)
{
warn("get_wireless_mode: FAILED creating request socket for \'%s\' : %s\n",g_osl->interface,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)
warn("get_wireless_mode: get associated Access Point MAC failed: %s\n",
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;
default:
/* this is a pretty complex wireless device (probably acting
* as an AP); we can't express its features just 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 this is actually quite
* meaningless. */
int
get_bssid(void *data)
{
/* TLVDEF( etheraddr_t, bssid, , 5, Access_unset ) */
#ifdef NOT_ACCESSPOINT
etheraddr_t* bssid = (etheraddr_t*) data;
struct iwreq req;
int ret;
memset(&req, 0, sizeof(req));
strncpy(req.ifr_ifrn.ifrn_name, g_osl->interface, 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;
#else
return TLV_GET_FAILED; // This is an AP - no associated BSSID //
#endif
}
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(uint32_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 = (uint16_t*) data;
*morate = htons(108); /* 54 Mbs / 0.5 Mbs = 108 */
return TLV_GET_SUCCEEDED;
}
int
get_tsc_ticks_per_sec(void *data)
{
/* TLVDEF( uint64_t, tsc_ticks_per_sec, , 0xA, Access_unset ) */
uint64_t ticks;
uint8_t *srcticks = (uint8_t*)(&ticks) + sizeof(uint64_t) - 1;
uint8_t *dstticks = (uint8_t*) data;
int i;
ticks = (uint64_t) 0x999e36LL; // 10M (100ns) ticks - YMMV
/* do our own htonll() here.... */
for (i=0; i<sizeof(uint64_t); i++) *dstticks++ = *srcticks--;
return TLV_GET_SUCCEEDED;
}
int
get_link_speed(void *data)
{
/* TLVDEF( uint32_t, link_speed, , 0xC, Access_unset ) // 100bps increments */
uint32_t* speed = (uint32_t*) data;
/* Since this is a bridged pair of interfaces (br0 = eth1 + wl0), I am returning the
* wireless speed, which is the lowest of the upper limits on the two interfaces... */
*speed = htonl(540000); // 54Mbit wireless... (540k x 100 = 54Mbs)
return TLV_GET_SUCCEEDED;
}
/* Unless this box is used as a wireless client, RSSI is meaningless - which client should be measured? */
int
get_rssi(void *data)
{
/* TLVDEF( uint32_t, rssi, , 0xD, Access_unset ) */
uint32_t* rssi = (uint32_t*) data;
return TLV_GET_FAILED;
}
int
get_icon_image(void *data)
{
/* TLVDEF( icon_file_t, icon_image, , 0xE ) // Usually LTLV style (Windows .ico file > 1k long) */
icon_file_t* icon = (icon_file_t*) data;
int fd;
/* The configuration file (lld2d.conf, in /etc) may have specified an icon file, which will be sent as
* a TLV if it is smaller than the lesser of 1k and whatever space is left in the send-buffer... Such a
* determination will be made at the time of the write, tho....
*
* In main.c, we read the config file, and established a value for the iconfile_path in "g_icon_path".
* This path-value ( a char* ) MAY be NULL, if no path was configured correctly.
* Here, we test that path, opening a file descriptor if it exists, and save its size for the writer-routine. */
/* Close any still-open fd to a previously "gotten" iconfile */
if (icon->fd_icon != -1 && icon->sz_iconfile != 0)
close(icon->fd_icon);
/* set defaults */
icon->sz_iconfile = 0;
icon->fd_icon = -1;
if (g_icon_path == NULL || g_icon_path[0] == 0)
{
return TLV_GET_FAILED; // No iconfile was correctly declared. This may NOT be an error!
}
fd = open(g_icon_path, O_RDONLY);
if (fd < 0)
{
warn("get_icon_image: reading iconfile %s FAILED : %s\n",
g_icon_path, strerror(errno));
return TLV_GET_FAILED;
} else {
/* size the file, for the writer to determine if it needs to force an LTLV */
struct stat filestats;
int statstat;
statstat = fstat( fd, &filestats );
if (statstat < 0)
{
warn("get_icon_image: stat-ing iconfile %s FAILED : %s\n",
g_icon_path, strerror(errno));
return TLV_GET_FAILED;
} else {
/* Finally! SUCCESS! */
icon->sz_iconfile = filestats.st_size;
icon->fd_icon = fd;
IF_TRACED(TRC_TLVINFO)
printf("get_icon_image: stat\'ing iconfile %s returned length=%d\n",g_icon_path, icon->sz_iconfile);
END_TRACE
}
}
return TLV_GET_SUCCEEDED;
}
int
get_machine_name(void *data)
{
/* TLVDEF( ucs2char_t, machine_name, [16], 0xF, Access_unset ) */
ucs2char_t* name = (ucs2char_t*) data;
int ret;
struct utsname unamebuf;
/* use uname() to get the system's hostname */
ret = uname(&unamebuf);
if (ret != -1)
{
/* nuke any '.' in what should be a nodename, not a FQDN */
char *p = strchr(unamebuf.nodename, '.');
if (p)
*p = '\0';
size_t namelen = strlen(unamebuf.nodename);
/* because I am a fool, and can't remember how to refer to the sizeof a structure
* element directly, there is an unnecessary declaration here... */
tlv_info_t* fool;
util_copy_ascii_to_ucs2(name, sizeof(fool->machine_name), unamebuf.nodename);
IF_TRACED(TRC_TLVINFO)
dbgprintf("get_machine_name(): space= %d, len=%d, machine name = %s\n",
sizeof(fool->machine_name), namelen, unamebuf.nodename);
END_TRACE
return TLV_GET_SUCCEEDED;
}
IF_TRACED(TRC_TLVINFO)
dbgprintf("get_machine_name(): uname() FAILED, returning %d\n", ret);
END_TRACE
return TLV_GET_FAILED;
}
int
get_support_info(void *data)
{
/* TLVDEF( ucs2char_t, support_info, [32], 0x10, Access_unset ) // RLS: was "contact_info" */
ucs2char_t * support = (ucs2char_t*) data;
return TLV_GET_FAILED;
}
int
get_friendly_name(void *data)
{
/* TLVDEF( ucs2char_t, friendly_name, [32], 0x11, Access_unset ) */
ucs2char_t * fname = (ucs2char_t*) data;
return TLV_GET_FAILED;
}
int
get_upnp_uuid(void *data)
{
/* TLVDEF( uuid_t, upnp_uuid, , 0x12, Access_unset ) // 16 bytes long */
// uuid_t* uuid = (uuid_t*) data;
return TLV_GET_FAILED;
}
int
get_hw_id(void *data)
{
/* TLVDEF( ucs2char_t, hw_id, [200], 0x13, Access_unset ) // 400 bytes long, max */
ucs2char_t * hwid = (ucs2char_t*) data;
return TLV_GET_FAILED;
}
int
get_qos_flags(void *data)
{
/* TLVDEF( uint32_t, qos_flags, , 0x14, Access_unset ) */
int32_t* qosf = (int32_t*) data;
#define TAG8P 0x20000000 // supports 802.1p priority tagging
#define TAG8Q 0x40000000 // supports 802.1q VLAN tagging
#define QW 0x80000000 // has Microsoft qWave service implemented; this is not LLTD QoS extensions
*qosf = htonl(TAG8P);
return TLV_GET_SUCCEEDED;
}
int
get_wl_physical_medium(void *data)
{
/* TLVDEF( uint8_t, wl_physical_medium, , 0x15, Access_unset ) */
uint8_t* wpm = (uint8_t*) data;
return TLV_GET_FAILED;
}
int
get_accesspt_assns(void *data)
{
/* TLVDEF( ltlv_t, accesspt_assns, , 0x16, Access_unset ) // RLS: Large_TLV */
// ltlv_t* assns = (ltlv_t*) data;
return TLV_GET_FAILED;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -