* Just print the ESSID or NWID...
*
* This file is released under the GPL license.
- * Copyright (c) 1997-2002 Jean Tourrilhes <jt@hpl.hp.com>
+ * Copyright (c) 1997-2004 Jean Tourrilhes <jt@hpl.hp.com>
*/
#include "iwlib.h" /* Header */
#include <getopt.h>
-#define FORMAT_DEFAULT 0 /* Nice looking display for the user */
-#define FORMAT_SCHEME 1 /* To be used as a Pcmcia Scheme */
-#define WTYPE_ESSID 0 /* Display ESSID or NWID */
-#define WTYPE_AP 1 /* Display AP/Cell Address */
-
/*
* Note on Pcmcia Schemes :
* ----------------------
* Jean II - 29/3/01
*/
-/*************************** SUBROUTINES ***************************/
-/*
- * Just for the heck of it, let's try to not link with iwlib.
- * This will keep the binary small and tiny...
- */
-
-/*------------------------------------------------------------------*/
-/*
- * Open a socket.
- * Depending on the protocol present, open the right socket. The socket
- * will allow us to talk to the driver.
- */
-int
-iw_sockets_open(void)
-{
- int ipx_sock = -1; /* IPX socket */
- int ax25_sock = -1; /* AX.25 socket */
- int inet_sock = -1; /* INET socket */
- int ddp_sock = -1; /* Appletalk DDP socket */
-
- /*
- * Now pick any (exisiting) useful socket family for generic queries
- * Note : don't open all the socket, only returns when one matches,
- * all protocols might not be valid.
- * Workaround by Jim Kaba <jkaba@sarnoff.com>
- * Note : in 99% of the case, we will just open the inet_sock.
- * The remaining 1% case are not fully correct...
- */
- inet_sock=socket(AF_INET, SOCK_DGRAM, 0);
- if(inet_sock!=-1)
- return inet_sock;
- ipx_sock=socket(AF_IPX, SOCK_DGRAM, 0);
- if(ipx_sock!=-1)
- return ipx_sock;
- ax25_sock=socket(AF_AX25, SOCK_DGRAM, 0);
- if(ax25_sock!=-1)
- return ax25_sock;
- ddp_sock=socket(AF_APPLETALK, SOCK_DGRAM, 0);
- /*
- * If this is -1 we have no known network layers and its time to jump.
- */
- return ddp_sock;
-}
+/**************************** CONSTANTS ****************************/
-/*------------------------------------------------------------------*/
-/*
- * Display an Ethernet address in readable format.
- */
-void
-iw_ether_ntop(const struct ether_addr* eth, char* buf)
-{
- sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X",
- eth->ether_addr_octet[0], eth->ether_addr_octet[1],
- eth->ether_addr_octet[2], eth->ether_addr_octet[3],
- eth->ether_addr_octet[4], eth->ether_addr_octet[5]);
-}
+#define FORMAT_DEFAULT 0 /* Nice looking display for the user */
+#define FORMAT_SCHEME 1 /* To be used as a Pcmcia Scheme */
+#define FORMAT_RAW 2 /* Raw value, for shell scripts */
+#define WTYPE_ESSID 0 /* Display ESSID or NWID */
+#define WTYPE_AP 1 /* Display AP/Cell Address */
+#define WTYPE_FREQ 2 /* Display frequency/channel */
+#define WTYPE_CHANNEL 3 /* Display channel (converted from freq) */
+#define WTYPE_MODE 4 /* Display mode */
+#define WTYPE_PROTO 5 /* Display protocol name */
/************************ DISPLAY ESSID/NWID ************************/
unsigned int i;
unsigned int j;
+ /* Make sure ESSID is always NULL terminated */
+ memset(essid, 0, sizeof(essid));
+
/* Get ESSID */
- strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
wrq.u.essid.pointer = (caddr_t) essid;
- wrq.u.essid.length = 0;
+ wrq.u.essid.length = IW_ESSID_MAX_SIZE + 1;
wrq.u.essid.flags = 0;
- if(ioctl(skfd, SIOCGIWESSID, &wrq) < 0)
+ if(iw_get_ext(skfd, ifname, SIOCGIWESSID, &wrq) < 0)
return(-1);
switch(format)
return(-2);
printf("%s\n", pessid);
break;
+ case FORMAT_RAW:
+ printf("%s\n", essid);
+ break;
default:
- printf("%-8.8s ESSID:\"%s\"\n", ifname, essid);
+ printf("%-8.16s ESSID:\"%s\"\n", ifname, essid);
break;
}
struct iwreq wrq;
/* Get network ID */
- strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
- if(ioctl(skfd, SIOCGIWNWID, &wrq) < 0)
+ if(iw_get_ext(skfd, ifname, SIOCGIWNWID, &wrq) < 0)
return(-1);
switch(format)
/* Prefix with nwid to avoid name space collisions */
printf("nwid%X\n", wrq.u.nwid.value);
break;
+ case FORMAT_RAW:
+ printf("%X\n", wrq.u.nwid.value);
+ break;
default:
- printf("%-8.8s NWID:%X\n", ifname, wrq.u.nwid.value);
+ printf("%-8.16s NWID:%X\n", ifname, wrq.u.nwid.value);
break;
}
char buffer[64];
/* Get AP Address */
- strncpy(wrq.ifr_name, ifname, IFNAMSIZ);
- if(ioctl(skfd, SIOCGIWAP, &wrq) < 0)
+ if(iw_get_ext(skfd, ifname, SIOCGIWAP, &wrq) < 0)
return(-1);
/* Print */
case FORMAT_SCHEME:
/* I think ':' are not problematic, because Pcmcia scripts
* seem to handle them properly... */
+ case FORMAT_RAW:
printf("%s\n", buffer);
break;
default:
- printf("%-8.8s Access Point: %s\n", ifname, buffer);
+ printf("%-8.16s Access Point/Cell: %s\n", ifname, buffer);
+ break;
+ }
+
+ return(0);
+}
+
+/****************************** OTHER ******************************/
+
+/*------------------------------------------------------------------*/
+/*
+ * Display the frequency (or channel) if possible
+ */
+static int
+print_freq(int skfd,
+ const char * ifname,
+ int format)
+{
+ struct iwreq wrq;
+ double freq;
+ char buffer[64];
+
+ /* Get frequency / channel */
+ if(iw_get_ext(skfd, ifname, SIOCGIWFREQ, &wrq) < 0)
+ return(-1);
+
+ /* Print */
+ freq = iw_freq2float(&(wrq.u.freq));
+ switch(format)
+ {
+ case FORMAT_SCHEME:
+ /* Prefix with freq to avoid name space collisions */
+ printf("freq%g\n", freq);
+ break;
+ case FORMAT_RAW:
+ printf("%g\n", freq);
+ break;
+ default:
+ iw_print_freq(buffer, sizeof(buffer), freq, -1, wrq.u.freq.flags);
+ printf("%-8.16s %s\n", ifname, buffer);
+ break;
+ }
+
+ return(0);
+}
+
+/*------------------------------------------------------------------*/
+/*
+ * Display the channel (converted from frequency) if possible
+ */
+static int
+print_channel(int skfd,
+ const char * ifname,
+ int format)
+{
+ struct iwreq wrq;
+ struct iw_range range;
+ double freq;
+ int channel;
+
+ /* Get frequency / channel */
+ if(iw_get_ext(skfd, ifname, SIOCGIWFREQ, &wrq) < 0)
+ return(-1);
+
+ /* Convert to channel */
+ if(iw_get_range_info(skfd, ifname, &range) < 0)
+ return(-2);
+ freq = iw_freq2float(&(wrq.u.freq));
+ if(freq < KILO)
+ channel = (int) freq;
+ else
+ {
+ channel = iw_freq_to_channel(freq, &range);
+ if(channel < 0)
+ return(-3);
+ }
+
+ /* Print */
+ switch(format)
+ {
+ case FORMAT_SCHEME:
+ /* Prefix with freq to avoid name space collisions */
+ printf("channel%d\n", channel);
+ break;
+ case FORMAT_RAW:
+ printf("%d\n", channel);
+ break;
+ default:
+ printf("%-8.16s Channel:%d\n", ifname, channel);
+ break;
+ }
+
+ return(0);
+}
+
+/*------------------------------------------------------------------*/
+/*
+ * Display the mode if possible
+ */
+static int
+print_mode(int skfd,
+ const char * ifname,
+ int format)
+{
+ struct iwreq wrq;
+
+ /* Get frequency / channel */
+ if(iw_get_ext(skfd, ifname, SIOCGIWMODE, &wrq) < 0)
+ return(-1);
+ if(wrq.u.mode >= IW_NUM_OPER_MODE)
+ return(-2);
+
+ /* Print */
+ switch(format)
+ {
+ case FORMAT_SCHEME:
+ /* Strip all white space and stuff */
+ if(wrq.u.mode == IW_MODE_ADHOC)
+ printf("AdHoc\n");
+ else
+ printf("%s\n", iw_operation_mode[wrq.u.mode]);
+ break;
+ case FORMAT_RAW:
+ printf("%d\n", wrq.u.mode);
+ break;
+ default:
+ printf("%-8.16s Mode:%s\n", ifname, iw_operation_mode[wrq.u.mode]);
+ break;
+ }
+
+ return(0);
+}
+
+/*------------------------------------------------------------------*/
+/*
+ * Display the ESSID if possible
+ */
+static int
+print_protocol(int skfd,
+ const char * ifname,
+ int format)
+{
+ struct iwreq wrq;
+ char proto[IFNAMSIZ + 1]; /* Protocol */
+ char pproto[IFNAMSIZ + 1]; /* Pcmcia format */
+ unsigned int i;
+ unsigned int j;
+
+ /* Get Protocol name */
+ if(iw_get_ext(skfd, ifname, SIOCGIWNAME, &wrq) < 0)
+ return(-1);
+ strncpy(proto, wrq.u.name, IFNAMSIZ);
+ proto[IFNAMSIZ] = '\0';
+
+ switch(format)
+ {
+ case FORMAT_SCHEME:
+ /* Strip all white space and stuff */
+ j = 0;
+ for(i = 0; i < strlen(proto); i++)
+ if(isalnum(proto[i]))
+ pproto[j++] = proto[i];
+ pproto[j] = '\0';
+ if((j == 0) || (j > 32))
+ return(-2);
+ printf("%s\n", pproto);
+ break;
+ case FORMAT_RAW:
+ printf("%s\n", proto);
+ break;
+ default:
+ printf("%-8.16s Protocol Name:\"%s\"\n", ifname, proto);
break;
}
int ret;
/* Check wtype */
- if(wtype == WTYPE_AP)
+ switch(wtype)
{
+ case WTYPE_AP:
/* Try to print an AP */
ret = print_ap(skfd, ifname, format);
- return(ret);
- }
+ break;
- /* Try to print an ESSID */
- ret = print_essid(skfd, ifname, format);
+ case WTYPE_CHANNEL:
+ /* Try to print channel */
+ ret = print_channel(skfd, ifname, format);
+ break;
- if(ret < 0)
- {
- /* Try to print a nwid */
- ret = print_nwid(skfd, ifname, format);
+ case WTYPE_FREQ:
+ /* Try to print frequency */
+ ret = print_freq(skfd, ifname, format);
+ break;
+
+ case WTYPE_MODE:
+ /* Try to print the mode */
+ ret = print_mode(skfd, ifname, format);
+ break;
+
+ case WTYPE_PROTO:
+ /* Try to print the protocol */
+ ret = print_protocol(skfd, ifname, format);
+ break;
+
+ default:
+ /* Try to print an ESSID */
+ ret = print_essid(skfd, ifname, format);
+ if(ret < 0)
+ {
+ /* Try to print a nwid */
+ ret = print_nwid(skfd, ifname, format);
+ }
}
return(ret);
/*------------------------------------------------------------------*/
/*
* Try the various devices until one return something we can use
+ *
+ * Note : we can't use iw_enum_devices() because we want a different
+ * behaviour :
+ * 1) Stop at the first valid wireless device
+ * 2) Only go through active devices
*/
static int
scan_devices(int skfd,
{
fputs("Usage iwgetid [OPTIONS] [ifname]\n"
" Options are:\n"
- " -a,--ap Print the access point address\n"
- " -h,--help Print this message\n"
- " -s,--scheme Format the output as a PCMCIA scheme identifier\n",
+ " -a,--ap Print the access point address\n"
+ " -c,--channel Print the current channel\n"
+ " -f,--freq Print the current frequency\n"
+ " -m,--mode Print the current mode\n"
+ " -p,--protocol Print the protocol name\n"
+ " -r,--raw Format the output as raw value for shell scripts\n"
+ " -s,--scheme Format the output as a PCMCIA scheme identifier\n"
+ " -h,--help Print this message\n",
status ? stderr : stdout);
exit(status);
}
static const struct option long_opts[] = {
{ "ap", no_argument, NULL, 'a' },
+ { "channel", no_argument, NULL, 'c' },
+ { "freq", no_argument, NULL, 'f' },
+ { "mode", no_argument, NULL, 'm' },
+ { "protocol", no_argument, NULL, 'p' },
{ "help", no_argument, NULL, 'h' },
+ { "raw", no_argument, NULL, 'r' },
{ "scheme", no_argument, NULL, 's' },
{ NULL, 0, NULL, 0 }
};
int ret = -1;
/* Check command line arguments */
- while((opt = getopt_long(argc, argv, "ahs", long_opts, NULL)) > 0)
+ while((opt = getopt_long(argc, argv, "acfhmprs", long_opts, NULL)) > 0)
{
switch(opt)
{
wtype = WTYPE_AP;
break;
+ case 'c':
+ /* User wants channel only */
+ wtype = WTYPE_CHANNEL;
+ break;
+
+ case 'f':
+ /* User wants frequency/channel */
+ wtype = WTYPE_FREQ;
+ break;
+
+ case 'm':
+ /* User wants the mode */
+ wtype = WTYPE_MODE;
+ break;
+
+ case 'p':
+ /* User wants the protocol */
+ wtype = WTYPE_PROTO;
+ break;
+
case 'h':
iw_usage(0);
break;
+ case 'r':
+ /* User wants a Raw format */
+ format = FORMAT_RAW;
+ break;
+
case 's':
/* User wants a Scheme format */
format = FORMAT_SCHEME;
}
fflush(stdout);
- close(skfd);
+ iw_sockets_close(skfd);
return(ret);
}