3 * Copyright 2010 Haiku Inc. All rights reserved.
4 * Distributed under the terms of the MIT License.
8 * Copyright 2001 The Aerospace Corporation.
9 * Copyright (c) 1997, 1998, 2000 The NetBSD Foundation, Inc.
10 * All rights reserved.
11 * Distributed under the terms of the 2-clause BSD license.
14 * Alex Botero-Lowry, alex.boterolowry@gmail.com
23 #include <sys/ioctl.h>
24 #include <sys/kernel.h>
25 #include <sys/sockio.h>
26 #include <sys/types.h>
27 #include <sys/socket.h>
31 #include <net80211/ieee80211_ioctl.h>
32 #include <net80211/ieee80211_haiku.h>
35 extern const char* __progname
;
39 get_string(const char* val
, const char* sep
, u_int8_t
* buf
, int* lenp
)
47 hexstr
= (val
[0] == '0' && tolower((u_char
) val
[1]) == 'x');
53 if (sep
!= NULL
&& strchr(sep
, *val
) != NULL
) {
58 if (!isxdigit((u_char
) val
[0])) {
59 printf("%s: bad hexadecimal digits", __func__
);
62 if (!isxdigit((u_char
) val
[1])) {
63 printf("%s: odd count hexadecimal digits", __func__
);
69 printf("%s: hexadecimal digits too long", __func__
);
71 printf("%s: string too long", __func__
);
75 #define tohex(x) (isdigit(x) ? (x) - '0' : tolower(x) - 'a' + 10)
76 *p
++ = (tohex((u_char
) val
[0]) << 4)
77 | tohex((u_char
) val
[1]);
84 /* The string "-" is treated as the empty string. */
85 if (!hexstr
&& len
== 1 && buf
[0] == '-') {
87 memset(buf
, 0, *lenp
);
88 } else if (len
< *lenp
)
89 memset(p
, 0, *lenp
- len
);
97 set80211(int s
, const char* dev
, int type
, int val
, int len
, void* data
)
99 struct ieee80211req ireq
;
101 (void)memset(&ireq
, 0, sizeof(ireq
));
102 (void)strncpy(ireq
.i_name
, dev
, sizeof(ireq
.i_name
));
107 if (ioctl(s
, SIOCS80211
, &ireq
, sizeof(struct ieee80211req
)) < 0) {
108 fprintf(stderr
, "%s: error in handling SIOCS80211 (type %d): %s\n",
109 __progname
, type
, strerror(errno
));
115 set80211ssid(const char* dev
, const char* val
, int s
)
119 u_int8_t data
[IEEE80211_NWID_LEN
];
123 if (len
> 2 && isdigit((int)val
[0]) && val
[1] == ':') {
124 ssid
= atoi(val
) - 1;
127 bzero(data
, sizeof(data
));
129 if (get_string(val
, NULL
, data
, &len
) == NULL
)
132 set80211(s
, dev
, IEEE80211_IOC_SSID
, ssid
, len
, data
);
137 set80211nwkey(const char* dev
, const char* val
, int s
)
142 u_int8_t data
[IEEE80211_KEYBUF_SIZE
];
144 set80211(s
, dev
, IEEE80211_IOC_WEP
, IEEE80211_WEP_ON
, 0, NULL
);
146 if (isdigit((int)val
[0]) && val
[1] == ':') {
147 txkey
= val
[0] - '0' - 1;
150 for (i
= 0; i
< 4; i
++) {
151 bzero(data
, sizeof(data
));
153 val
= get_string(val
, ",", data
, &len
);
157 set80211(s
, dev
, IEEE80211_IOC_WEPKEY
, i
, len
, data
);
160 bzero(data
, sizeof(data
));
162 get_string(val
, NULL
, data
, &len
);
165 set80211(s
, dev
, IEEE80211_IOC_WEPKEY
, 0, len
, data
);
167 bzero(data
, sizeof(data
));
168 for (i
= 1; i
< 4; i
++)
169 set80211(s
, dev
, IEEE80211_IOC_WEPKEY
, i
, 0, data
);
172 set80211(s
, dev
, IEEE80211_IOC_WEPTXKEY
, txkey
, 0, NULL
);
177 get80211val(int s
, const char* dev
, int type
, int* val
)
179 struct ieee80211req ireq
;
181 (void) memset(&ireq
, 0, sizeof(ireq
));
182 (void) strncpy(ireq
.i_name
, dev
, sizeof(ireq
.i_name
));
184 if (ioctl(s
, SIOCG80211
, &ireq
) < 0)
192 getid(int s
, const char* dev
, int ix
, void* data
, size_t len
, int* plen
,
195 struct ieee80211req ireq
;
197 (void)memset(&ireq
, 0, sizeof(ireq
));
198 (void)strncpy(ireq
.i_name
, dev
, sizeof(ireq
.i_name
));
199 ireq
.i_type
= (!mesh
) ? IEEE80211_IOC_SSID
: IEEE80211_IOC_MESH_ID
;
203 if (ioctl(s
, SIOCG80211
, &ireq
) < 0)
211 print_string(const u_int8_t
* buf
, int len
)
218 for (; i
< len
; i
++) {
219 if (!isprint(buf
[i
]) && buf
[i
] != '\0')
225 if (hasspc
|| len
== 0 || buf
[0] == '\0')
226 printf("\"%.*s\"", len
, buf
);
228 printf("%.*s", len
, buf
);
231 for (i
= 0; i
< len
; i
++)
232 printf("%02x", buf
[i
]);
238 show_status(const char* dev
, int s
)
245 if (getid(s
, dev
, -1, data
, sizeof(data
), &len
, 0) < 0) {
246 fprintf(stderr
, "error: not a wifi device\n");
250 if (get80211val(s
, dev
, IEEE80211_IOC_NUMSSIDS
, &num
) < 0)
254 for (i
= 0; i
< num
; i
++) {
255 if (getid(s
, dev
, i
, data
, sizeof(data
), &len
, 0) >= 0
257 printf(" %d:", i
+ 1);
258 print_string(data
, len
);
262 print_string(data
, len
);
271 fprintf(stderr
, "usage: setwep device_path [ssid] [key]\n");
277 main(int argc
, char** argv
)
279 int s
= socket(AF_INET
, SOCK_DGRAM
, 0);
285 show_status(argv
[1], s
);
288 set80211ssid(argv
[1], argv
[2], s
);
291 set80211nwkey(argv
[1], argv
[3], s
);