You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
685 lines
16 KiB
685 lines
16 KiB
/* |
|
* Linux port of dhd command line utility, hacked from wl utility. |
|
* |
|
* Copyright (C) 1999-2013, Broadcom Corporation |
|
* |
|
* Permission to use, copy, modify, and/or distribute this software for any |
|
* purpose with or without fee is hereby granted, provided that the above |
|
* copyright notice and this permission notice appear in all copies. |
|
* |
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY |
|
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION |
|
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN |
|
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|
* |
|
* $Id: dhdu_linux.c 378962 2013-01-15 13:18:28Z $ |
|
*/ |
|
|
|
#include <stdio.h> |
|
#include <stdlib.h> |
|
#include <unistd.h> |
|
#include <ctype.h> |
|
#include <string.h> |
|
#include <errno.h> |
|
#include <sys/types.h> |
|
#include <sys/wait.h> |
|
#include <sys/socket.h> |
|
#include <proto/ethernet.h> |
|
#include <proto/bcmip.h> |
|
#include <arpa/inet.h> |
|
#include <sys/ioctl.h> |
|
#include <net/if.h> |
|
#include <fcntl.h> |
|
#include <sys/ioctl.h> |
|
#include <unistd.h> |
|
|
|
#ifndef TARGETENV_android |
|
#include <error.h> |
|
typedef u_int64_t u64; |
|
typedef u_int32_t u32; |
|
typedef u_int16_t u16; |
|
typedef u_int8_t u8; |
|
#endif /* TARGETENV_android */ |
|
#include <linux/sockios.h> |
|
#include <linux/types.h> |
|
#include <linux/ethtool.h> |
|
|
|
#include <typedefs.h> |
|
#include <signal.h> |
|
#include <dhdioctl.h> |
|
#include <wlioctl.h> |
|
#include <bcmcdc.h> |
|
#include <bcmutils.h> |
|
|
|
#if defined(RWL_WIFI) || defined(RWL_SOCKET) ||defined(RWL_SERIAL) |
|
#define RWL_ENABLE |
|
#endif |
|
|
|
#include "dhdu.h" |
|
#ifdef RWL_ENABLE |
|
#include "wlu_remote.h" |
|
#include "wlu_client_shared.h" |
|
#include "wlu_pipe.h" |
|
#endif /* RWL_ENABLE */ |
|
#include <netdb.h> |
|
#include <netinet/in.h> |
|
#include <dhdioctl.h> |
|
#include "dhdu_common.h" |
|
#include "dhdu_nl80211.h" |
|
|
|
char *av0; |
|
static int rwl_os_type = LINUX_OS; |
|
/* Search the dhd_cmds table for a matching command name. |
|
* Return the matching command or NULL if no match found. |
|
*/ |
|
static cmd_t * |
|
dhd_find_cmd(char* name) |
|
{ |
|
cmd_t *cmd = NULL; |
|
/* search the dhd_cmds for a matching name */ |
|
for (cmd = dhd_cmds; cmd->name && strcmp(cmd->name, name); cmd++); |
|
if (cmd->name == NULL) |
|
cmd = NULL; |
|
return cmd; |
|
} |
|
|
|
static void |
|
syserr(const char *s) |
|
{ |
|
fprintf(stderr, "%s: ", av0); |
|
perror(s); |
|
exit(errno); |
|
} |
|
|
|
#ifdef NL80211 |
|
static int __dhd_driver_io(void *dhd, dhd_ioctl_t *ioc) |
|
{ |
|
struct dhd_netlink_info dhd_nli; |
|
struct ifreq *ifr = (struct ifreq *)dhd; |
|
int ret = 0; |
|
|
|
dhd_nli.ifidx = if_nametoindex(ifr->ifr_name); |
|
if (!dhd_nli.ifidx) { |
|
fprintf(stderr, "invalid device %s\n", ifr->ifr_name); |
|
return BCME_IOCTL_ERROR; |
|
} |
|
|
|
if (dhd_nl_sock_connect(&dhd_nli) < 0) |
|
syserr("socket"); |
|
|
|
ret = dhd_nl_do_testmode(&dhd_nli, ioc); |
|
dhd_nl_sock_disconnect(&dhd_nli); |
|
return ret; |
|
} |
|
#else |
|
static int __dhd_driver_io(void *dhd, dhd_ioctl_t *ioc) |
|
{ |
|
struct ifreq *ifr = (struct ifreq *)dhd; |
|
int s; |
|
int ret = 0; |
|
|
|
/* pass ioctl data */ |
|
ifr->ifr_data = (caddr_t)ioc; |
|
|
|
/* open socket to kernel */ |
|
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) |
|
syserr("socket"); |
|
|
|
ret = ioctl(s, SIOCDEVPRIVATE, ifr); |
|
if (ret < 0 && errno != EAGAIN) |
|
syserr(__FUNCTION__); |
|
|
|
/* cleanup */ |
|
close(s); |
|
return ret; |
|
} |
|
#endif /* NL80211 */ |
|
|
|
/* This function is called by ioctl_setinformation_fe or ioctl_queryinformation_fe |
|
* for executing remote commands or local commands |
|
*/ |
|
static int |
|
dhd_ioctl(void *dhd, int cmd, void *buf, int len, bool set) |
|
{ |
|
dhd_ioctl_t ioc; |
|
int ret = 0; |
|
|
|
/* By default try to execute wl commands */ |
|
int driver_magic = WLC_IOCTL_MAGIC; |
|
int get_magic = WLC_GET_MAGIC; |
|
|
|
/* For local dhd commands execute dhd. For wifi transport we still |
|
* execute wl commands. |
|
*/ |
|
if (remote_type == NO_REMOTE && strncmp (buf, RWL_WIFI_ACTION_CMD, |
|
strlen(RWL_WIFI_ACTION_CMD)) && strncmp(buf, RWL_WIFI_GET_ACTION_CMD, |
|
strlen(RWL_WIFI_GET_ACTION_CMD))) { |
|
driver_magic = DHD_IOCTL_MAGIC; |
|
get_magic = DHD_GET_MAGIC; |
|
} |
|
|
|
/* do it */ |
|
ioc.cmd = cmd; |
|
ioc.buf = buf; |
|
ioc.len = len; |
|
ioc.set = set; |
|
ioc.driver = driver_magic; |
|
|
|
ret = __dhd_driver_io(dhd, &ioc); |
|
if (ret < 0 && cmd != get_magic) |
|
ret = BCME_IOCTL_ERROR; |
|
return ret; |
|
} |
|
|
|
/* This function is called in wlu_pipe.c remote_wifi_ser_init() to execute |
|
* the initial set of wl commands for wifi transport (e.g slow_timer, fast_timer etc) |
|
*/ |
|
int wl_ioctl(void *wl, int cmd, void *buf, int len, bool set) |
|
{ |
|
return dhd_ioctl(wl, cmd, buf, len, set); /* Call actual wl_ioctl here: Shubhro */ |
|
} |
|
|
|
/* Search if dhd adapter or wl adapter is present |
|
* This is called by dhd_find to check if it supports wl or dhd |
|
* The reason for checking wl adapter is that we can still send remote dhd commands over |
|
* wifi transport. |
|
*/ |
|
static int |
|
dhd_get_dev_type(char *name, void *buf, char *type) |
|
{ |
|
int s; |
|
int ret; |
|
struct ifreq ifr; |
|
struct ethtool_drvinfo info; |
|
|
|
/* open socket to kernel */ |
|
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) |
|
syserr("socket"); |
|
|
|
/* get device type */ |
|
memset(&info, 0, sizeof(info)); |
|
info.cmd = ETHTOOL_GDRVINFO; |
|
strcpy(info.driver, "?"); |
|
strcat(info.driver, type); |
|
ifr.ifr_data = (caddr_t)&info; |
|
strncpy(ifr.ifr_name, name, IFNAMSIZ); |
|
if ((ret = ioctl(s, SIOCETHTOOL, &ifr)) < 0) { |
|
|
|
if (errno != EAGAIN) |
|
syserr(__FUNCTION__); |
|
|
|
*(char *)buf = '\0'; |
|
} |
|
else |
|
strcpy(buf, info.driver); |
|
|
|
close(s); |
|
return ret; |
|
} |
|
|
|
/* dhd_get/dhd_set is called by several functions in dhdu.c. This used to call dhd_ioctl |
|
* directly. However now we need to execute the dhd commands remotely. |
|
* So we make use of wl pipes to execute this. |
|
* wl_get or wl_set functions also check if it is a local command hence they in turn |
|
* call dhd_ioctl if required. Name wl_get/wl_set is retained because these functions are |
|
* also called by wlu_pipe.c wlu_client_shared.c |
|
*/ |
|
int |
|
dhd_get(void *dhd, int cmd, void *buf, int len) |
|
{ |
|
return wl_get(dhd, cmd, buf, len); |
|
} |
|
|
|
/* |
|
* To use /dev/node interface: |
|
* 1. mknod /dev/hnd0 c 248 0 |
|
* 2. chmod 777 /dev/hnd0 |
|
*/ |
|
#define NODE "/dev/hnd0" |
|
|
|
int |
|
dhd_set(void *dhd, int cmd, void *buf, int len) |
|
{ |
|
static int dnode = -1; |
|
|
|
switch (cmd) { |
|
case DHD_DLDN_ST: |
|
if (dnode == -1) |
|
dnode = open(NODE, O_RDWR); |
|
else |
|
fprintf(stderr, "devnode already opened!\n"); |
|
|
|
return dnode; |
|
break; |
|
case DHD_DLDN_WRITE: |
|
if (dnode > 0) |
|
return write(dnode, buf, len); |
|
break; |
|
case DHD_DLDN_END: |
|
if (dnode > 0) |
|
return close(dnode); |
|
break; |
|
default: |
|
return wl_set(dhd, cmd, buf, len); |
|
|
|
} |
|
|
|
return -1; |
|
} |
|
|
|
/* Verify the wl adapter found. |
|
* This is called by dhd_find to check if it supports wl |
|
* The reason for checking wl adapter is that we can still send remote dhd commands over |
|
* wifi transport. The function is copied from wlu.c. |
|
*/ |
|
int |
|
wl_check(void *wl) |
|
{ |
|
int ret; |
|
int val = 0; |
|
|
|
if (!dhd_check (wl)) |
|
return 0; |
|
|
|
/* |
|
* If dhd_check() fails then go for a regular wl driver verification |
|
*/ |
|
if ((ret = wl_get(wl, WLC_GET_MAGIC, &val, sizeof(int))) < 0) |
|
return ret; |
|
if (val != WLC_IOCTL_MAGIC) |
|
return BCME_ERROR; |
|
if ((ret = wl_get(wl, WLC_GET_VERSION, &val, sizeof(int))) < 0) |
|
return ret; |
|
if (val > WLC_IOCTL_VERSION) { |
|
fprintf(stderr, "Version mismatch, please upgrade\n"); |
|
return BCME_ERROR; |
|
} |
|
return 0; |
|
} |
|
/* Search and verify the request type of adapter (wl or dhd) |
|
* This is called by main before executing local dhd commands |
|
* or sending remote dhd commands over wifi transport |
|
*/ |
|
void |
|
dhd_find(struct ifreq *ifr, char *type) |
|
{ |
|
char proc_net_dev[] = "/proc/net/dev"; |
|
FILE *fp; |
|
static char buf[400]; |
|
char *c, *name; |
|
char dev_type[32]; |
|
|
|
ifr->ifr_name[0] = '\0'; |
|
/* eat first two lines */ |
|
if (!(fp = fopen(proc_net_dev, "r")) || |
|
!fgets(buf, sizeof(buf), fp) || |
|
!fgets(buf, sizeof(buf), fp)) |
|
return; |
|
|
|
while (fgets(buf, sizeof(buf), fp)) { |
|
c = buf; |
|
while (isspace(*c)) |
|
c++; |
|
if (!(name = strsep(&c, ":"))) |
|
continue; |
|
strncpy(ifr->ifr_name, name, IFNAMSIZ); |
|
if (dhd_get_dev_type(name, dev_type, type) >= 0 && |
|
!strncmp(dev_type, type, strlen(dev_type) - 1)) |
|
{ |
|
if (!wl_check((void*)ifr)) |
|
break; |
|
} |
|
ifr->ifr_name[0] = '\0'; |
|
} |
|
|
|
fclose(fp); |
|
} |
|
/* This function is called by wl_get to execute either local dhd command |
|
* or send a dhd command over wl transport |
|
*/ |
|
static int |
|
ioctl_queryinformation_fe(void *wl, int cmd, void* input_buf, int *input_len) |
|
{ |
|
if (remote_type == NO_REMOTE) { |
|
return dhd_ioctl(wl, cmd, input_buf, *input_len, FALSE); |
|
} |
|
#ifdef RWL_ENABLE |
|
else { |
|
return rwl_queryinformation_fe(wl, cmd, input_buf, |
|
(unsigned long*)input_len, 0, RDHD_GET_IOCTL); |
|
} |
|
#else /* RWL_ENABLE */ |
|
return BCME_IOCTL_ERROR; |
|
#endif /* RWL_ENABLE */ |
|
} |
|
|
|
/* This function is called by wl_set to execute either local dhd command |
|
* or send a dhd command over wl transport |
|
*/ |
|
static int |
|
ioctl_setinformation_fe(void *wl, int cmd, void* buf, int *len) |
|
{ |
|
if (remote_type == NO_REMOTE) { |
|
return dhd_ioctl(wl, cmd, buf, *len, TRUE); |
|
} |
|
#ifdef RWL_ENABLE |
|
else { |
|
return rwl_setinformation_fe(wl, cmd, buf, (unsigned long*)len, 0, RDHD_SET_IOCTL); |
|
|
|
} |
|
#else /* RWL_ENABLE */ |
|
return BCME_IOCTL_ERROR; |
|
#endif /* RWL_ENABLE */ |
|
} |
|
|
|
/* The function is replica of wl_get in wlu_linux.c. Optimize when we have some |
|
* common code between wlu_linux.c and dhdu_linux.c |
|
*/ |
|
int |
|
wl_get(void *wl, int cmd, void *buf, int len) |
|
{ |
|
int error = BCME_OK; |
|
/* For RWL: When interfacing to a Windows client, need t add in OID_BASE */ |
|
if ((rwl_os_type == WIN32_OS) && (remote_type != NO_REMOTE)) { |
|
error = (int)ioctl_queryinformation_fe(wl, WL_OID_BASE + cmd, buf, &len); |
|
} else { |
|
error = (int)ioctl_queryinformation_fe(wl, cmd, buf, &len); |
|
} |
|
if (error == BCME_SERIAL_PORT_ERR) |
|
return BCME_SERIAL_PORT_ERR; |
|
|
|
if (error != 0) |
|
return BCME_IOCTL_ERROR; |
|
|
|
return error; |
|
} |
|
|
|
/* The function is replica of wl_set in wlu_linux.c. Optimize when we have some |
|
* common code between wlu_linux.c and dhdu_linux.c |
|
*/ |
|
int |
|
wl_set(void *wl, int cmd, void *buf, int len) |
|
{ |
|
int error = BCME_OK; |
|
|
|
/* For RWL: When interfacing to a Windows client, need t add in OID_BASE */ |
|
if ((rwl_os_type == WIN32_OS) && (remote_type != NO_REMOTE)) { |
|
error = (int)ioctl_setinformation_fe(wl, WL_OID_BASE + cmd, buf, &len); |
|
} else { |
|
error = (int)ioctl_setinformation_fe(wl, cmd, buf, &len); |
|
} |
|
|
|
if (error == BCME_SERIAL_PORT_ERR) |
|
return BCME_SERIAL_PORT_ERR; |
|
|
|
if (error != 0) { |
|
return BCME_IOCTL_ERROR; |
|
} |
|
return error; |
|
} |
|
|
|
int |
|
wl_validatedev(void *dev_handle) |
|
{ |
|
int retval = 1; |
|
struct ifreq *ifr = (struct ifreq *)dev_handle; |
|
/* validate the interface */ |
|
if (!ifr->ifr_name || wl_check((void *)ifr)) { |
|
retval = 0; |
|
} |
|
return retval; |
|
} |
|
|
|
/* Main client function |
|
* The code is mostly from wlu_linux.c. This function takes care of executing remote dhd commands |
|
* along with the local dhd commands now. |
|
*/ |
|
int |
|
main(int argc, char **argv) |
|
{ |
|
struct ifreq ifr; |
|
char *ifname = NULL; |
|
int err = 0; |
|
int help = 0; |
|
int status = CMD_DHD; |
|
#ifdef RWL_SOCKET |
|
struct ipv4_addr temp; |
|
#endif /* RWL_SOCKET */ |
|
|
|
UNUSED_PARAMETER(argc); |
|
|
|
av0 = argv[0]; |
|
memset(&ifr, 0, sizeof(ifr)); |
|
argv++; |
|
|
|
if ((status = dhd_option(&argv, &ifname, &help)) == CMD_OPT) { |
|
if (ifname) |
|
strncpy(ifr.ifr_name, ifname, IFNAMSIZ); |
|
} |
|
/* Linux client looking for a Win32 server */ |
|
if (*argv && strncmp (*argv, "--wince", strlen(*argv)) == 0) { |
|
rwl_os_type = WIN32_OS; |
|
argv++; |
|
} |
|
|
|
/* RWL socket transport Usage: --socket ipaddr [port num] */ |
|
if (*argv && strncmp (*argv, "--socket", strlen(*argv)) == 0) { |
|
argv++; |
|
|
|
remote_type = REMOTE_SOCKET; |
|
#ifdef RWL_SOCKET |
|
if (!(*argv)) { |
|
rwl_usage(remote_type); |
|
return err; |
|
} |
|
|
|
if (!dhd_atoip(*argv, &temp)) { |
|
rwl_usage(remote_type); |
|
return err; |
|
} |
|
g_rwl_servIP = *argv; |
|
argv++; |
|
|
|
g_rwl_servport = DEFAULT_SERVER_PORT; |
|
if ((*argv) && isdigit(**argv)) { |
|
g_rwl_servport = atoi(*argv); |
|
argv++; |
|
} |
|
#endif /* RWL_SOCKET */ |
|
} |
|
|
|
/* RWL from system serial port on client to uart dongle port on server */ |
|
/* Usage: --dongle /dev/ttyS0 */ |
|
if (*argv && strncmp (*argv, "--dongle", strlen(*argv)) == 0) { |
|
argv++; |
|
remote_type = REMOTE_DONGLE; |
|
} |
|
|
|
/* RWL over wifi. Usage: --wifi mac_address */ |
|
if (*argv && strncmp (*argv, "--wifi", strlen(*argv)) == 0) { |
|
argv++; |
|
#ifdef RWL_WIFI |
|
remote_type = NO_REMOTE; |
|
if (!ifr.ifr_name[0]) |
|
{ |
|
dhd_find(&ifr, "wl"); |
|
} |
|
/* validate the interface */ |
|
if (!ifr.ifr_name[0] || wl_check((void*)&ifr)) { |
|
fprintf(stderr, "%s: wl driver adapter not found\n", av0); |
|
exit(1); |
|
} |
|
remote_type = REMOTE_WIFI; |
|
|
|
if (argc < 4) { |
|
rwl_usage(remote_type); |
|
return err; |
|
} |
|
/* copy server mac address to local buffer for later use by findserver cmd */ |
|
if (!dhd_ether_atoe(*argv, (struct ether_addr *)g_rwl_buf_mac)) { |
|
fprintf(stderr, |
|
"could not parse as an ethernet MAC address\n"); |
|
return FAIL; |
|
} |
|
argv++; |
|
#else /* RWL_WIFI */ |
|
remote_type = REMOTE_WIFI; |
|
#endif /* RWL_WIFI */ |
|
} |
|
|
|
/* Process for local dhd */ |
|
if (remote_type == NO_REMOTE) { |
|
err = process_args(&ifr, argv); |
|
return err; |
|
} |
|
|
|
#ifdef RWL_ENABLE |
|
if (*argv) { |
|
err = process_args(&ifr, argv); |
|
if ((err == BCME_SERIAL_PORT_ERR) && (remote_type == REMOTE_DONGLE)) { |
|
DPRINT_ERR(ERR, "\n Retry again\n"); |
|
err = process_args((struct ifreq*)&ifr, argv); |
|
} |
|
return err; |
|
} |
|
rwl_usage(remote_type); |
|
#endif /* RWL_ENABLE */ |
|
|
|
return err; |
|
} |
|
/* |
|
* Function called for 'local' execution and for 'remote' non-interactive session |
|
* (shell cmd, wl cmd) .The code is mostly from wlu_linux.c. This code can be |
|
* common to wlu_linux.c and dhdu_linux.c |
|
*/ |
|
static int |
|
process_args(struct ifreq* ifr, char **argv) |
|
{ |
|
char *ifname = NULL; |
|
int help = 0; |
|
int status = 0; |
|
int err = BCME_OK; |
|
cmd_t *cmd = NULL; |
|
while (*argv) { |
|
#ifdef RWL_ENABLE |
|
if ((strcmp (*argv, "sh") == 0) && (remote_type != NO_REMOTE)) { |
|
argv++; /* Get the shell command */ |
|
if (*argv) { |
|
/* Register handler in case of shell command only */ |
|
signal(SIGINT, ctrlc_handler); |
|
err = rwl_shell_cmd_proc((void*)ifr, argv, SHELL_CMD); |
|
} else { |
|
DPRINT_ERR(ERR, |
|
"Enter the shell command (e.g ls(Linux) or dir(Win CE) \n"); |
|
err = BCME_ERROR; |
|
} |
|
return err; |
|
} |
|
#endif /* RWL_ENABLE */ |
|
if ((status = dhd_option(&argv, &ifname, &help)) == CMD_OPT) { |
|
if (help) |
|
break; |
|
if (ifname) |
|
strncpy(ifr->ifr_name, ifname, IFNAMSIZ); |
|
continue; |
|
} |
|
/* parse error */ |
|
else if (status == CMD_ERR) |
|
break; |
|
|
|
if (remote_type == NO_REMOTE) { |
|
int ret; |
|
|
|
/* use default interface */ |
|
if (!ifr->ifr_name[0]) |
|
dhd_find(ifr, "dhd"); |
|
/* validate the interface */ |
|
if (!ifr->ifr_name[0]) { |
|
if (strcmp("dldn", *argv) != 0) { |
|
exit(ENXIO); |
|
syserr("interface"); |
|
} |
|
} |
|
if ((ret = dhd_check((void *)ifr)) != 0) { |
|
if (strcmp("dldn", *argv) != 0) { |
|
errno = -ret; |
|
syserr("dhd_check"); |
|
} |
|
} |
|
} |
|
/* search for command */ |
|
cmd = dhd_find_cmd(*argv); |
|
/* if not found, use default set_var and get_var commands */ |
|
if (!cmd) { |
|
cmd = &dhd_varcmd; |
|
} |
|
|
|
/* do command */ |
|
err = (*cmd->func)((void *) ifr, cmd, argv); |
|
break; |
|
} /* while loop end */ |
|
|
|
/* provide for help on a particular command */ |
|
if (help && *argv) { |
|
cmd = dhd_find_cmd(*argv); |
|
if (cmd) { |
|
dhd_cmd_usage(cmd); |
|
} else { |
|
DPRINT_ERR(ERR, "%s: Unrecognized command \"%s\", type -h for help\n", |
|
av0, *argv); |
|
} |
|
} else if (!cmd) |
|
dhd_usage(NULL); |
|
else if (err == BCME_USAGE_ERROR) |
|
dhd_cmd_usage(cmd); |
|
else if (err == BCME_IOCTL_ERROR) |
|
dhd_printlasterror((void *) ifr); |
|
|
|
return err; |
|
} |
|
|
|
int |
|
rwl_shell_createproc(void *wl) |
|
{ |
|
UNUSED_PARAMETER(wl); |
|
return fork(); |
|
} |
|
|
|
void |
|
rwl_shell_killproc(int pid) |
|
{ |
|
kill(pid, SIGKILL); |
|
} |
|
|
|
#ifdef RWL_SOCKET |
|
/* validate hostname/ip given by the client */ |
|
int |
|
validate_server_address() |
|
{ |
|
struct hostent *he; |
|
struct ipv4_addr temp; |
|
|
|
if (!dhd_atoip(g_rwl_servIP, &temp)) { |
|
/* Wrong IP address format check for hostname */ |
|
if ((he = gethostbyname(g_rwl_servIP)) != NULL) { |
|
if (!dhd_atoip(*he->h_addr_list, &temp)) { |
|
g_rwl_servIP = inet_ntoa(*(struct in_addr *)*he->h_addr_list); |
|
if (g_rwl_servIP == NULL) { |
|
DPRINT_ERR(ERR, "Error at inet_ntoa \n"); |
|
return FAIL; |
|
} |
|
} else { |
|
DPRINT_ERR(ERR, "Error in IP address \n"); |
|
return FAIL; |
|
} |
|
} else { |
|
DPRINT_ERR(ERR, "Enter correct IP address/hostname format\n"); |
|
return FAIL; |
|
} |
|
} |
|
return SUCCESS; |
|
} |
|
#endif /* RWL_SOCKET */
|
|
|