summaryrefslogtreecommitdiffstats
path: root/isys/wireless.c
diff options
context:
space:
mode:
authorJeremy Katz <katzj@redhat.com>2004-05-24 21:49:52 +0000
committerJeremy Katz <katzj@redhat.com>2004-05-24 21:49:52 +0000
commitfc2ae88ce331dc39317bbb2f5033b2e89a393653 (patch)
treed1c42375fff9be579fbc09586043886964234305 /isys/wireless.c
parent859eb35a06aa1d415f677acb4e3a3a354fe86e72 (diff)
downloadanaconda-fc2ae88ce331dc39317bbb2f5033b2e89a393653.tar.gz
anaconda-fc2ae88ce331dc39317bbb2f5033b2e89a393653.tar.xz
anaconda-fc2ae88ce331dc39317bbb2f5033b2e89a393653.zip
add initial wireless bits. allows determining if this is a wireless
interface, get/set essid and set wep key
Diffstat (limited to 'isys/wireless.c')
-rw-r--r--isys/wireless.c255
1 files changed, 255 insertions, 0 deletions
diff --git a/isys/wireless.c b/isys/wireless.c
new file mode 100644
index 000000000..231dc5774
--- /dev/null
+++ b/isys/wireless.c
@@ -0,0 +1,255 @@
+/*
+ * wireless.c - wireless card manipulation
+ *
+ * Copyright 2004 Red Hat, Inc.
+ *
+ * Some portions from wireless_tools
+ * copyright (c) 1997-2003 Jean Tourrilhes <jt@hpl.hp.com>
+ *
+ * Jeremy Katz <katzj@redhat.com>
+ *
+ * This software may be freely redistributed under the terms of the GNU
+ * general public license.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+
+#include <sys/socket.h>
+#include <sys/types.h>
+
+#ifdef DIET
+typedef void * caddr_t;
+#endif
+
+#include <linux/wireless.h>
+
+static struct iwreq get_wreq(char * ifname) {
+ struct iwreq wreq;
+
+ memset(&wreq, 0, sizeof(wreq));
+ strncpy(wreq.ifr_name, ifname, IFNAMSIZ);
+
+ return wreq;
+}
+
+static int get_socket() {
+ int sock;
+
+ if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+#ifdef STANDALONE
+ fprintf(stderr, "Error creating socket: %s\n", strerror(errno));
+#endif
+ return -1;
+ }
+
+ return sock;
+}
+
+int is_wireless_interface(char * ifname) {
+ int sock = get_socket();
+ struct iwreq wreq = get_wreq(ifname);
+
+ int rc = ioctl(sock, SIOCGIWNAME, &wreq);
+ close(sock);
+
+ if (rc < 0) {
+ return 0;
+ }
+
+ return 1;
+}
+
+/* set the essid for ifname to essid. if essid is NULL, do automatically */
+int set_essid(char * ifname, char * essid) {
+ int sock;
+ struct iwreq wreq;
+
+ if (strlen(essid) > IW_ESSID_MAX_SIZE) {
+ fprintf(stderr, "essid too long\n");
+ return -1;
+ }
+
+ sock = get_socket();
+ wreq = get_wreq(ifname);
+
+ if (essid) {
+ wreq.u.essid.flags = 1;
+ wreq.u.essid.pointer = (caddr_t) essid;
+ wreq.u.essid.length = strlen(essid) + 1;
+ } else {
+ wreq.u.essid.flags = 0;
+ wreq.u.essid.pointer = (caddr_t) NULL;
+ wreq.u.essid.length = 0;
+ }
+
+ int rc = ioctl(sock, SIOCSIWESSID, &wreq);
+ close(sock);
+
+ if (rc < 0) {
+ fprintf(stderr, "failed to set essid: %s\n", strerror(errno));
+ return -1;
+ }
+
+ return 0;
+}
+
+char * get_essid(char * ifname) {
+ int sock;
+ struct iwreq wreq;
+
+ sock = get_socket();
+ wreq = get_wreq(ifname);
+
+ wreq.u.essid.pointer = (caddr_t) malloc(IW_ESSID_MAX_SIZE + 1);
+ wreq.u.essid.length = IW_ESSID_MAX_SIZE + 1;
+ wreq.u.essid.flags = 0;
+ int rc = ioctl(sock, SIOCGIWESSID, &wreq);
+ close(sock);
+
+ if (rc < 0) {
+ fprintf(stderr, "failed to get essid for %s: %s\n", ifname,
+ strerror(errno));
+ return NULL;
+ }
+
+ return wreq.u.essid.pointer;
+}
+
+/* based off iw_in_key from wireless-tools/iwlib.c */
+static int parse_wep_key(char * in, unsigned char * key) {
+ int len = 0;
+
+ if (!strncmp(in, "s:", 2)) {
+ /* the key is a string */
+ len = strlen(in + 2);
+ strncpy(key, in + 2, len);
+ } else {
+ char *buff, *hex, *out, *p;
+
+ /* hexadecimal digits, straight from iwlib.c */
+ buff = alloca(IW_ENCODING_TOKEN_MAX + strlen(in) + 1);
+ if(buff == NULL) {
+ fprintf(stderr, "Malloc failed (string too long ?)\n");
+ return(-1);
+ }
+ /* Preserve original buffers (both in & out) */
+ hex = buff + IW_ENCODING_TOKEN_MAX;
+ strcpy(hex, in);
+ out = buff;
+ /* Parse */
+ p = strtok(hex, "-:;.,");
+ while((p != (char *) NULL) && (len < IW_ENCODING_TOKEN_MAX)) {
+ int temph, templ, count, l;
+
+ /* Get each char separatly (and not by two) so that we don't
+ * get confused by 'enc' (=> '0E'+'0C') and similar */
+ count = sscanf(p, "%1X%1X", &temph, &templ);
+ if(count < 1)
+ return(-1); /* Error -> non-hex char */
+ /* Fixup odd strings such as '123' is '01'+'23' and not '12'+'03'*/
+ l = strlen(p);
+ if(l % 2)
+ count = 1;
+ /* Put back two chars as one byte */
+ if(count == 2)
+ templ |= temph << 4;
+ else
+ templ = temph;
+ out[len++] = (unsigned char) (templ & 0xFF);
+ /* Check where to get next char from */
+ if(l > count) /* Token not finished yet */
+ p += count;
+ else
+ p = strtok((char *) NULL, "-:;.,");
+ }
+ memcpy(key, out, len);
+ free(buff);
+ }
+
+ return len;
+}
+
+int set_wep_key(char * ifname, char * key) {
+ int sock;
+ struct iwreq wreq;
+ unsigned char thekey[IW_ENCODING_TOKEN_MAX];
+
+ if (strlen(key) > IW_ENCODING_TOKEN_MAX) {
+ fprintf(stderr, "wep key too long\n");
+ return -1;
+ }
+
+ sock = get_socket();
+ wreq = get_wreq(ifname);
+
+ if (key) {
+ int len = parse_wep_key(key, thekey);
+ if (len > 0) {
+ wreq.u.data.flags = IW_ENCODE_ENABLED;
+ wreq.u.data.length = len;
+ wreq.u.data.pointer = (caddr_t) thekey;
+ }
+ } else {
+ wreq.u.data.flags = IW_ENCODE_DISABLED;
+ wreq.u.data.pointer = (caddr_t) NULL;
+ wreq.u.data.length = 0;
+ }
+
+ int rc = ioctl(sock, SIOCSIWENCODE, &wreq);
+ close(sock);
+
+ if (rc < 0) {
+ fprintf(stderr, "failed to set wep key: %s\n", strerror(errno));
+ return -1;
+ }
+
+ return 0;
+}
+
+
+#ifdef STANDALONE
+int main(int argc, char **argv) {
+ if (argc < 4) {
+ fprintf(stderr, "Usage: %s [interface] [essid] [key]\n", argv[0]);
+ exit(1);
+ }
+
+ if (!is_wireless_interface(argv[1])) {
+ fprintf(stderr, "%s isn't a wireless interface!\n", argv[1]);
+ exit(2);
+ }
+
+ /* if (set_essid(argv[1], NULL) < 0) {
+ fprintf(stderr, "Unable to set essid to %s\n", argv[2]);
+ exit(3);
+ }
+ exit(0);*/
+
+ if (set_essid(argv[1], argv[2]) < 0) {
+ fprintf(stderr, "Unable to set essid to %s\n", argv[2]);
+ exit(3);
+ }
+
+ /* if (set_wep_key(argv[1], NULL) < 0) {
+ fprintf(stderr, "Unable to set wepkey to %s\n", argv[2]);
+ exit(4);
+ }
+ exit(0);*/
+
+ if (set_wep_key(argv[1], argv[3]) < 0) {
+ fprintf(stderr, "Unable to set wepkey to %s\n", argv[2]);
+ exit(4);
+ }
+
+ return 0;
+}
+#endif