Ticket #5697: add-wep.diff

File add-wep.diff, 6.6 KB (added by alexbl, 14 years ago)
  • src/bin/network/ifconfig/ifconfig.cpp

    diff --git a/src/bin/network/ifconfig/ifconfig.cpp b/src/bin/network/ifconfig/ifconfig.cpp
    index 6ae74eb..f719b2f 100644
    a b  
    1717#include <net/if_media.h>
    1818#include <net/if_types.h>
    1919#include <netinet/in.h>
     20#include <sys/ioctl.h>
     21#include <sys/kernel.h>
    2022#include <sys/socket.h>
    2123#include <sys/sockio.h>
     24#include <sys/types.h>
    2225
     26#include <net80211/ieee80211_ioctl.h>
     27#include <net80211/ieee80211_haiku.h>
     28
     29#include <ctype>
    2330#include <errno.h>
    2431#include <stdio.h>
    2532#include <stdlib.h>
    2633#include <string.h>
     34#include <strings.h>
    2735#include <unistd.h>
    2836
    2937#include <NetServer.h>
    media_parse_subtype(const char* string, int media, int* type)  
    170178    return false;
    171179}
    172180
     181static const char*
     182get_string(const char* val, const char* sep, u_int8_t* buf, int* lenp)
     183{
     184        int             len;
     185        int             hexstr;
     186        u_int8_t* p;
     187
     188        len = *lenp;
     189        p = buf;
     190        hexstr = (val[0] == '0' && tolower((u_char) val[1]) == 'x');
     191        if (hexstr)
     192                val += 2;
     193        for (;;) {
     194                if (*val == '\0')
     195                        break;
     196                if (sep != NULL && strchr(sep, *val) != NULL) {
     197                        val++;
     198                        break;
     199                }
     200                if (hexstr) {
     201                        if (!isxdigit((u_char) val[0])) {
     202                                printf("%s: bad hexadecimal digits", __func__);
     203                                return NULL;
     204                        }
     205                        if (!isxdigit((u_char) val[1])) {
     206                                printf("%s: odd count hexadecimal digits",
     207                                __func__);
     208                                return NULL;
     209                        }
     210                }
     211                if (p >= buf + len) {
     212                        if (hexstr)
     213                                printf("%s: hexadecimal digits too long",
     214                                __func__);
     215                        else
     216                                printf("string too long", __func__);
     217                        return NULL;
     218                }
     219                if (hexstr) {
     220#define tohex(x) (isdigit(x) ? (x) - '0' : tolower(x) - 'a' + 10)
     221                        *p++ = (tohex((u_char) val[0]) << 4)
     222                                | tohex((u_char) val[1]);
     223#undef tohex
     224                        val += 2;
     225                } else
     226                        *p++ = *val++;
     227        }
     228        len = p - buf;
     229        /* The string "-" is treated as the empty string. */
     230        if (!hexstr && len == 1 && buf[0] == '-') {
     231                len = 0;
     232                memset(buf, 0, *lenp);
     233        } else if (len < *lenp)
     234                memset(p, 0, *lenp - len);
     235        *lenp = len;
     236        return val;
     237}
     238
     239
     240static void
     241set80211(int s, const char* dev, int type, int val, int len, void* data)
     242{
     243        struct ieee80211req ireq;
     244
     245        (void)memset(&ireq, 0, sizeof(ireq));
     246        (void)strncpy(ireq.i_name, dev, sizeof(ireq.i_name));
     247        ireq.i_type = type;
     248        ireq.i_val = val;
     249        ireq.i_len = len;
     250        ireq.i_data = data;
     251        if (ioctl(s, SIOCS80211, &ireq, sizeof(struct ieee80211req)) < 0)
     252                printf("%s: error in handling SIOCS80211\n", __func__);
     253}
     254
     255
     256static void
     257set80211ssid(const char* dev, const char* val, int s)
     258{
     259        int             ssid;
     260        int             len;
     261        u_int8_t        data[IEEE80211_NWID_LEN];
     262
     263        ssid = 0;
     264        len = strlen(val);
     265        if (len > 2 && isdigit((int)val[0]) && val[1] == ':') {
     266                ssid = atoi(val) - 1;
     267                val += 2;
     268        }
     269        bzero(data, sizeof(data));
     270        len = sizeof(data);
     271        if (get_string(val, NULL, data, &len) == NULL)
     272                exit(1);
     273
     274        set80211(s, dev, IEEE80211_IOC_SSID, ssid, len, data);
     275}
     276
     277
     278static void
     279set80211nwkey(const char* dev, const char* val, int s)
     280{
     281        int             txkey;
     282        int             i, len;
     283        u_int8_t        data[IEEE80211_KEYBUF_SIZE];
     284
     285        set80211(s, dev, IEEE80211_IOC_WEP, IEEE80211_WEP_ON, 0, NULL);
     286
     287        if (isdigit((int)val[0]) && val[1] == ':') {
     288                txkey = val[0] - '0' - 1;
     289                val += 2;
     290
     291                for (i = 0; i < 4; i++) {
     292                        bzero(data, sizeof(data));
     293                        len = sizeof(data);
     294                        val = get_string(val, ",", data, &len);
     295                        if (val == NULL)
     296                                exit(1);
     297
     298                        set80211(s, dev, IEEE80211_IOC_WEPKEY, i, len, data);
     299                }
     300        } else {
     301                bzero(data, sizeof(data));
     302                len = sizeof(data);
     303                get_string(val, NULL, data, &len);
     304                txkey = 0;
     305
     306                set80211(s, dev, IEEE80211_IOC_WEPKEY, 0, len, data);
     307
     308                bzero(data, sizeof(data));
     309                for (i = 1; i < 4; i++)
     310                        set80211(s, dev, IEEE80211_IOC_WEPKEY, i, 0, data);
     311        }
     312
     313        set80211(s, dev, IEEE80211_IOC_WEPTXKEY, txkey, 0, NULL);
     314}
    173315
    174316//  #pragma mark -
    175317
    configure_interface(int socket, const char* name, char* const* args,  
    509651
    510652    bool hasAddress = false, hasMask = false, hasPeer = false;
    511653    bool hasBroadcast = false, doAutoConfig = false;
     654    bool hasSsid = false, hasWepkey = false;
    512655    struct sockaddr address, mask, peer, broadcast;
    513656    int mtu = -1, metric = -1, media = -1;
     657    char *ssid, *wepkey;
    514658    int addFlags = 0, currentFlags = 0, removeFlags = 0;
    515659
    516660    // try to parse address family
    configure_interface(int socket, const char* name, char* const* args,  
    631775                exit(1);
    632776            }
    633777            i++;
     778        } else if (!strcmp(args[i], "ssid")) {
     779            if (i + 1 >= argCount) {
     780                fprintf(stderr, "%s: Option 'ssid expected paramater\n",
     781                        kProgramName);
     782                exit(1);
     783            }
     784            hasSsid = true;
     785            ssid = args[i + 1];
     786        } else if (!stcmp(args[i], "wepkey")) {
     787            if (i + 1 >= argCount) {
     788                fprintf(stderr, "%s: Option 'ssid expected paramater\n",
     789                        kProgramName);
     790                exit(1);
     791            }
     792            hasWepkey = true;
     793            wepkey = args[i + 1];
    634794        } else if (!strcmp(args[i], "up") || !strcmp(args[i], "-down")) {
    635795            addFlags |= IFF_UP;
    636796        } else if (!strcmp(args[i], "down") || !strcmp(args[i], "-up")) {
    configure_interface(int socket, const char* name, char* const* args,  
    755915        }
    756916    }
    757917
     918    if (hasSsid) {
     919        set80211ssid(name, ssid, socket);
     920    }
     921
     922    if (hasWepkey) {
     923        set80211nwkey(name, wepkey, socket);
     924    }
     925
    758926    // start auto configuration, if asked for
    759927
    760928    if (doAutoConfig) {