From b654ef7d7e0b424a7d50af8ac7d155b10407dd67 Mon Sep 17 00:00:00 2001 From: Matt Madia Date: Wed, 7 Apr 2010 04:37:00 +0000 Subject: [PATCH] Added a CLI application "setwep", contributed by Alex Botero-Lowry. It is a temporary means for joining an unencrypted or WEP encrypted wifi network. setwep works with 64- and 128-bit WEP and supports both text keys as well as hex digit keys. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@36057 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- build/jam/HaikuImage | 4 +- src/bin/network/Jamfile | 1 + src/bin/network/setwep/Jamfile | 13 +++ src/bin/network/setwep/setwep.c | 191 ++++++++++++++++++++++++++++++++ 4 files changed, 207 insertions(+), 2 deletions(-) create mode 100644 src/bin/network/setwep/Jamfile create mode 100644 src/bin/network/setwep/setwep.c diff --git a/build/jam/HaikuImage b/build/jam/HaikuImage index af1cbd2fb5..997e58da74 100644 --- a/build/jam/HaikuImage +++ b/build/jam/HaikuImage @@ -52,8 +52,8 @@ SYSTEM_BIN = "[" addattr alert arp base64 basename bash bc beep bootman bzip2 rc readlink ReadOnlyBootPrompt reindex release renice rlog rm rmattr rmindex rmdir roster route safemode screen_blanker screenmode sdiff setdecor settype setversion - setvolume seq sha1sum shar shred shuf shutdown sleep sort spamdbm split - stat strace stty su sum sync sysinfo + setvolume setwep seq sha1sum shar shred shuf shutdown sleep sort spamdbm + split stat strace stty su sum sync sysinfo tac tail tcpdump tcptester tee telnet telnetd test timeout top touch tput tr traceroute translate trash true truncate tsort tty uname unchop unexpand unmount uniq unlink unrar unshar unzip unzipsfx diff --git a/src/bin/network/Jamfile b/src/bin/network/Jamfile index e1c321bca2..05d170aa61 100644 --- a/src/bin/network/Jamfile +++ b/src/bin/network/Jamfile @@ -16,6 +16,7 @@ SubInclude HAIKU_TOP src bin network netstat ; #SubInclude HAIKU_TOP src bin network ppp_up ; SubInclude HAIKU_TOP src bin network ping ; SubInclude HAIKU_TOP src bin network route ; +SubInclude HAIKU_TOP src bin network setwep ; SubInclude HAIKU_TOP src bin network tcpdump ; SubInclude HAIKU_TOP src bin network telnet ; SubInclude HAIKU_TOP src bin network telnetd ; diff --git a/src/bin/network/setwep/Jamfile b/src/bin/network/setwep/Jamfile new file mode 100644 index 0000000000..287e8ee092 --- /dev/null +++ b/src/bin/network/setwep/Jamfile @@ -0,0 +1,13 @@ +SubDir HAIKU_TOP src bin network setwep ; + +UsePrivateHeaders net ; +UsePrivateHeaders kernel ; +UsePrivateSystemHeaders ; +UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd_network compat ] + : true ; +UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd_wlan ] : true ; + +BinCommand setwep : + setwep.c + : $(TARGET_NETWORK_LIBS) +; diff --git a/src/bin/network/setwep/setwep.c b/src/bin/network/setwep/setwep.c new file mode 100644 index 0000000000..ae1b176e7c --- /dev/null +++ b/src/bin/network/setwep/setwep.c @@ -0,0 +1,191 @@ +/* + * + * Copyright 2010 Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Many parts + * + * Copyright 2001 The Aerospace Corporation. All rights reserved. + * Copyright (c) 1997, 1998, 2000 The NetBSD Foundation, Inc. All rights reserved. + * Distributed under the terms of the 2-clause BSD license. + * + * Authors: + * Alex Botero-Lowry, alex.boterolowry@gmail.com + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include + +static const char* +get_string(const char* val, const char* sep, u_int8_t* buf, int* lenp) +{ + int len; + int hexstr; + u_int8_t* p; + + len = *lenp; + p = buf; + hexstr = (val[0] == '0' && tolower((u_char) val[1]) == 'x'); + if (hexstr) + val += 2; + for (;;) { + if (*val == '\0') + break; + if (sep != NULL && strchr(sep, *val) != NULL) { + val++; + break; + } + if (hexstr) { + if (!isxdigit((u_char) val[0])) { + printf("%s: bad hexadecimal digits", __func__); + return NULL; + } + if (!isxdigit((u_char) val[1])) { + printf("%s: odd count hexadecimal digits", + __func__); + return NULL; + } + } + if (p >= buf + len) { + if (hexstr) + printf("%s: hexadecimal digits too long", + __func__); + else + printf("string too long", __func__); + return NULL; + } + if (hexstr) { +#define tohex(x) (isdigit(x) ? (x) - '0' : tolower(x) - 'a' + 10) + *p++ = (tohex((u_char) val[0]) << 4) + | tohex((u_char) val[1]); +#undef tohex + val += 2; + } else + *p++ = *val++; + } + len = p - buf; + /* The string "-" is treated as the empty string. */ + if (!hexstr && len == 1 && buf[0] == '-') { + len = 0; + memset(buf, 0, *lenp); + } else if (len < *lenp) + memset(p, 0, *lenp - len); + *lenp = len; + return val; +} + + +static void +set80211(int s, const char* dev, int type, int val, int len, void* data) +{ + struct ieee80211req ireq; + + (void)memset(&ireq, 0, sizeof(ireq)); + (void)strncpy(ireq.i_name, dev, sizeof(ireq.i_name)); + ireq.i_type = type; + ireq.i_val = val; + ireq.i_len = len; + ireq.i_data = data; + if (ioctl(s, SIOCS80211, &ireq, sizeof(struct ieee80211req)) < 0) + printf("%s: error in handling SIOCS80211\n", __func__); +} + + +static void +set80211ssid(const char* dev, const char* val, int s) +{ + int ssid; + int len; + u_int8_t data[IEEE80211_NWID_LEN]; + + ssid = 0; + len = strlen(val); + if (len > 2 && isdigit((int)val[0]) && val[1] == ':') { + ssid = atoi(val) - 1; + val += 2; + } + bzero(data, sizeof(data)); + len = sizeof(data); + if (get_string(val, NULL, data, &len) == NULL) + exit(1); + + set80211(s, dev, IEEE80211_IOC_SSID, ssid, len, data); +} + + +static void +set80211nwkey(const char* dev, const char* val, int s) +{ + int txkey; + int i, len; + u_int8_t data[IEEE80211_KEYBUF_SIZE]; + + set80211(s, dev, IEEE80211_IOC_WEP, IEEE80211_WEP_ON, 0, NULL); + + if (isdigit((int)val[0]) && val[1] == ':') { + txkey = val[0] - '0' - 1; + val += 2; + + for (i = 0; i < 4; i++) { + bzero(data, sizeof(data)); + len = sizeof(data); + val = get_string(val, ",", data, &len); + if (val == NULL) + exit(1); + + set80211(s, dev, IEEE80211_IOC_WEPKEY, i, len, data); + } + } else { + bzero(data, sizeof(data)); + len = sizeof(data); + get_string(val, NULL, data, &len); + txkey = 0; + + set80211(s, dev, IEEE80211_IOC_WEPKEY, 0, len, data); + + bzero(data, sizeof(data)); + for (i = 1; i < 4; i++) + set80211(s, dev, IEEE80211_IOC_WEPKEY, i, 0, data); + } + + set80211(s, dev, IEEE80211_IOC_WEPTXKEY, txkey, 0, NULL); +} + + +void +usage() +{ + fprintf(stderr, "usage: setwep device_path ssid [key]\n"); + exit(1); +} + + +int +main(int argc, char **argv) +{ + int s = socket(AF_INET, SOCK_DGRAM, 0); + + if (argc < 3) { + usage(); + } + set80211ssid(argv[1], argv[2], s); + + if (argc == 4) { + set80211nwkey(argv[1], argv[3], s); + } + return 0; +}