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; +}