~ubuntu-branches/ubuntu/lucid/wpasupplicant/lucid-updates

« back to all changes in this revision

Viewing changes to wpa_ctrl.c

  • Committer: Bazaar Package Importer
  • Author(s): Kel Modderman
  • Date: 2006-10-05 08:04:01 UTC
  • mfrom: (1.1.5 upstream) (3 etch)
  • mto: This revision was merged to the branch mainline in revision 4.
  • Revision ID: james.westby@ubuntu.com-20061005080401-r8lqlix4390yos7b
Tags: 0.5.5-2
* Update madwifi headers to latest SVN. (Closes: #388316)
* Remove failed attempt at action locking. [debian/functions.sh,
  debian/wpa_action.sh]
* Add hysteresis checking functions, to avoid "event loops" while
  using wpa-roam. [debian/functions.sh, debian/wpa_action.sh]
* Change of co-maintainer email address.
* Add ishex() function to functions.sh to determine wpa-psk value type in
  plaintext or hex. This effectively eliminates the need for the bogus and
  somewhat confusing wpa-passphrase contruct specific to our scripts and
  allows wpa-psk to work with either a 8 to 63 character long plaintext
  string or 64 character long hex string.
* Adjust README.modes to not refer to the redundant wpa-passphrase stuff.
* Add big fat NOTE about acceptable wpa-psk's to top of example gallery.
* Strip surrounding quotes from wpa-ssid if present, instead of just whining
  about them.
* Update email address in copyright blurb of functions.sh, ifupdown.sh and
  wpa_action.sh.  

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * wpa_supplicant/hostapd control interface library
3
 
 * Copyright (c) 2004-2005, Jouni Malinen <jkmaline@cc.hut.fi>
 
3
 * Copyright (c) 2004-2006, Jouni Malinen <jkmaline@cc.hut.fi>
4
4
 *
5
5
 * This program is free software; you can redistribute it and/or modify
6
6
 * it under the terms of the GNU General Public License version 2 as
16
16
 
17
17
#ifdef CONFIG_CTRL_IFACE
18
18
 
19
 
#ifndef CONFIG_CTRL_IFACE_UDP
 
19
#ifdef CONFIG_CTRL_IFACE_UNIX
20
20
#include <sys/un.h>
21
 
#endif /* CONFIG_CTRL_IFACE_UDP */
 
21
#endif /* CONFIG_CTRL_IFACE_UNIX */
22
22
 
23
23
#include "wpa_ctrl.h"
24
24
#include "common.h"
25
25
 
26
26
 
 
27
#if defined(CONFIG_CTRL_IFACE_UNIX) || defined(CONFIG_CTRL_IFACE_UDP)
 
28
#define CTRL_IFACE_SOCKET
 
29
#endif /* CONFIG_CTRL_IFACE_UNIX || CONFIG_CTRL_IFACE_UDP */
 
30
 
 
31
 
27
32
/**
28
33
 * struct wpa_ctrl - Internal structure for control interface library
29
34
 *
34
39
 * the arguments for most of the control interface library functions.
35
40
 */
36
41
struct wpa_ctrl {
 
42
#ifdef CONFIG_CTRL_IFACE_UDP
37
43
        int s;
38
 
#ifdef CONFIG_CTRL_IFACE_UDP
39
44
        struct sockaddr_in local;
40
45
        struct sockaddr_in dest;
41
 
#else /* CONFIG_CTRL_IFACE_UDP */
 
46
        char *cookie;
 
47
#endif /* CONFIG_CTRL_IFACE_UDP */
 
48
#ifdef CONFIG_CTRL_IFACE_UNIX
 
49
        int s;
42
50
        struct sockaddr_un local;
43
51
        struct sockaddr_un dest;
44
 
#endif /* CONFIG_CTRL_IFACE_UDP */
 
52
#endif /* CONFIG_CTRL_IFACE_UNIX */
 
53
#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
 
54
        HANDLE pipe;
 
55
#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
45
56
};
46
57
 
47
58
 
 
59
#ifdef CONFIG_CTRL_IFACE_UNIX
 
60
 
48
61
struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path)
49
62
{
50
63
        struct wpa_ctrl *ctrl;
51
 
#ifndef CONFIG_CTRL_IFACE_UDP
52
64
        static int counter = 0;
53
 
#endif /* CONFIG_CTRL_IFACE_UDP */
54
65
 
55
66
        ctrl = malloc(sizeof(*ctrl));
56
67
        if (ctrl == NULL)
57
68
                return NULL;
58
69
        memset(ctrl, 0, sizeof(*ctrl));
59
70
 
60
 
#ifdef CONFIG_CTRL_IFACE_UDP
61
 
        ctrl->s = socket(PF_INET, SOCK_DGRAM, 0);
62
 
        if (ctrl->s < 0) {
63
 
                perror("socket");
64
 
                free(ctrl);
65
 
                return NULL;
66
 
        }
67
 
 
68
 
        ctrl->local.sin_family = AF_INET;
69
 
        ctrl->local.sin_addr.s_addr = htonl((127 << 24) | 1);
70
 
        if (bind(ctrl->s, (struct sockaddr *) &ctrl->local,
71
 
                 sizeof(ctrl->local)) < 0) {
72
 
                close(ctrl->s);
73
 
                free(ctrl);
74
 
                return NULL;
75
 
        }
76
 
 
77
 
        ctrl->dest.sin_family = AF_INET;
78
 
        ctrl->dest.sin_addr.s_addr = htonl((127 << 24) | 1);
79
 
        ctrl->dest.sin_port = htons(WPA_CTRL_IFACE_PORT);
80
 
        if (connect(ctrl->s, (struct sockaddr *) &ctrl->dest,
81
 
                    sizeof(ctrl->dest)) < 0) {
82
 
                perror("connect");
83
 
                close(ctrl->s);
84
 
                free(ctrl);
85
 
                return NULL;
86
 
        }
87
 
#else /* CONFIG_CTRL_IFACE_UDP */
88
71
        ctrl->s = socket(PF_UNIX, SOCK_DGRAM, 0);
89
72
        if (ctrl->s < 0) {
90
73
                free(ctrl);
111
94
                free(ctrl);
112
95
                return NULL;
113
96
        }
114
 
#endif /* CONFIG_CTRL_IFACE_UDP */
115
97
 
116
98
        return ctrl;
117
99
}
119
101
 
120
102
void wpa_ctrl_close(struct wpa_ctrl *ctrl)
121
103
{
122
 
#ifndef CONFIG_CTRL_IFACE_UDP
123
104
        unlink(ctrl->local.sun_path);
 
105
        close(ctrl->s);
 
106
        free(ctrl);
 
107
}
 
108
 
 
109
#endif /* CONFIG_CTRL_IFACE_UNIX */
 
110
 
 
111
 
 
112
#ifdef CONFIG_CTRL_IFACE_UDP
 
113
 
 
114
struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path)
 
115
{
 
116
        struct wpa_ctrl *ctrl;
 
117
        char buf[128];
 
118
        size_t len;
 
119
 
 
120
        ctrl = malloc(sizeof(*ctrl));
 
121
        if (ctrl == NULL)
 
122
                return NULL;
 
123
        memset(ctrl, 0, sizeof(*ctrl));
 
124
 
 
125
        ctrl->s = socket(PF_INET, SOCK_DGRAM, 0);
 
126
        if (ctrl->s < 0) {
 
127
                perror("socket");
 
128
                free(ctrl);
 
129
                return NULL;
 
130
        }
 
131
 
 
132
        ctrl->local.sin_family = AF_INET;
 
133
        ctrl->local.sin_addr.s_addr = htonl((127 << 24) | 1);
 
134
        if (bind(ctrl->s, (struct sockaddr *) &ctrl->local,
 
135
                 sizeof(ctrl->local)) < 0) {
 
136
                close(ctrl->s);
 
137
                free(ctrl);
 
138
                return NULL;
 
139
        }
 
140
 
 
141
        ctrl->dest.sin_family = AF_INET;
 
142
        ctrl->dest.sin_addr.s_addr = htonl((127 << 24) | 1);
 
143
        ctrl->dest.sin_port = htons(WPA_CTRL_IFACE_PORT);
 
144
        if (connect(ctrl->s, (struct sockaddr *) &ctrl->dest,
 
145
                    sizeof(ctrl->dest)) < 0) {
 
146
                perror("connect");
 
147
                close(ctrl->s);
 
148
                free(ctrl);
 
149
                return NULL;
 
150
        }
 
151
 
 
152
        len = sizeof(buf) - 1;
 
153
        if (wpa_ctrl_request(ctrl, "GET_COOKIE", 10, buf, &len, NULL) == 0) {
 
154
                buf[len] = '\0';
 
155
                ctrl->cookie = strdup(buf);
 
156
        }
 
157
 
 
158
        return ctrl;
 
159
}
 
160
 
 
161
 
 
162
void wpa_ctrl_close(struct wpa_ctrl *ctrl)
 
163
{
 
164
        close(ctrl->s);
 
165
        free(ctrl->cookie);
 
166
        free(ctrl);
 
167
}
 
168
 
124
169
#endif /* CONFIG_CTRL_IFACE_UDP */
125
 
        close(ctrl->s);
126
 
        free(ctrl);
127
 
}
128
 
 
129
 
 
 
170
 
 
171
 
 
172
#ifdef CTRL_IFACE_SOCKET
130
173
int wpa_ctrl_request(struct wpa_ctrl *ctrl, const char *cmd, size_t cmd_len,
131
174
                     char *reply, size_t *reply_len,
132
175
                     void (*msg_cb)(char *msg, size_t len))
134
177
        struct timeval tv;
135
178
        int res;
136
179
        fd_set rfds;
137
 
 
138
 
        if (send(ctrl->s, cmd, cmd_len, 0) < 0)
 
180
        const char *_cmd;
 
181
        char *cmd_buf = NULL;
 
182
        size_t _cmd_len;
 
183
 
 
184
#ifdef CONFIG_CTRL_IFACE_UDP
 
185
        if (ctrl->cookie) {
 
186
                char *pos;
 
187
                _cmd_len = strlen(ctrl->cookie) + 1 + cmd_len;
 
188
                cmd_buf = malloc(_cmd_len );
 
189
                if (cmd_buf == NULL)
 
190
                        return -1;
 
191
                _cmd = cmd_buf;
 
192
                pos = cmd_buf;
 
193
                strcpy(pos, ctrl->cookie);
 
194
                pos += strlen(ctrl->cookie);
 
195
                *pos++ = ' ';
 
196
                memcpy(pos, cmd, cmd_len);
 
197
        } else
 
198
#endif /* CONFIG_CTRL_IFACE_UDP */
 
199
        {
 
200
                _cmd = cmd;
 
201
                _cmd_len = cmd_len;
 
202
        }
 
203
 
 
204
        if (send(ctrl->s, _cmd, _cmd_len, 0) < 0) {
 
205
                free(cmd_buf);
139
206
                return -1;
 
207
        }
 
208
        free(cmd_buf);
140
209
 
141
210
        for (;;) {
142
211
                tv.tv_sec = 2;
171
240
        }
172
241
        return 0;
173
242
}
 
243
#endif /* CTRL_IFACE_SOCKET */
174
244
 
175
245
 
176
246
static int wpa_ctrl_attach_helper(struct wpa_ctrl *ctrl, int attach)
201
271
}
202
272
 
203
273
 
 
274
#ifdef CTRL_IFACE_SOCKET
 
275
 
204
276
int wpa_ctrl_recv(struct wpa_ctrl *ctrl, char *reply, size_t *reply_len)
205
277
{
206
278
        int res;
232
304
        return ctrl->s;
233
305
}
234
306
 
 
307
#endif /* CTRL_IFACE_SOCKET */
 
308
 
 
309
 
 
310
#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
 
311
 
 
312
#ifndef WPA_SUPPLICANT_NAMED_PIPE
 
313
#define WPA_SUPPLICANT_NAMED_PIPE "WpaSupplicant"
 
314
#endif
 
315
#define NAMED_PIPE_PREFIX TEXT("\\\\.\\pipe\\") TEXT(WPA_SUPPLICANT_NAMED_PIPE)
 
316
 
 
317
struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path)
 
318
{
 
319
        struct wpa_ctrl *ctrl;
 
320
        DWORD mode;
 
321
        TCHAR name[256];
 
322
        int i;
 
323
 
 
324
        ctrl = malloc(sizeof(*ctrl));
 
325
        if (ctrl == NULL)
 
326
                return NULL;
 
327
        memset(ctrl, 0, sizeof(*ctrl));
 
328
 
 
329
#ifdef UNICODE
 
330
        if (ctrl_path == NULL)
 
331
                _snwprintf(name, 256, NAMED_PIPE_PREFIX);
 
332
        else
 
333
                _snwprintf(name, 256, NAMED_PIPE_PREFIX TEXT("-%S"),
 
334
                           ctrl_path);
 
335
#else /* UNICODE */
 
336
        if (ctrl_path == NULL)
 
337
                snprintf(name, 256, NAMED_PIPE_PREFIX);
 
338
        else
 
339
                snprintf(name, 256, NAMED_PIPE_PREFIX "-%s",
 
340
                         ctrl_path);
 
341
#endif /* UNICODE */
 
342
 
 
343
        for (i = 0; i < 10; i++) {
 
344
                ctrl->pipe = CreateFile(name, GENERIC_READ | GENERIC_WRITE, 0,
 
345
                                        NULL, OPEN_EXISTING, 0, NULL);
 
346
                /*
 
347
                 * Current named pipe server side in wpa_supplicant is
 
348
                 * re-opening the pipe for new clients only after the previous
 
349
                 * one is taken into use. This leaves a small window for race
 
350
                 * conditions when two connections are being opened at almost
 
351
                 * the same time. Retry if that was the case.
 
352
                 */
 
353
                if (ctrl->pipe != INVALID_HANDLE_VALUE ||
 
354
                    GetLastError() != ERROR_PIPE_BUSY)
 
355
                        break;
 
356
                WaitNamedPipe(name, 1000);
 
357
        }
 
358
        if (ctrl->pipe == INVALID_HANDLE_VALUE) {
 
359
                free(ctrl);
 
360
                return NULL;
 
361
        }
 
362
 
 
363
        mode = PIPE_READMODE_MESSAGE;
 
364
        if (!SetNamedPipeHandleState(ctrl->pipe, &mode, NULL, NULL)) {
 
365
                CloseHandle(ctrl->pipe);
 
366
                free(ctrl);
 
367
                return NULL;
 
368
        }
 
369
 
 
370
        return ctrl;
 
371
}
 
372
 
 
373
 
 
374
void wpa_ctrl_close(struct wpa_ctrl *ctrl)
 
375
{
 
376
        CloseHandle(ctrl->pipe);
 
377
        free(ctrl);
 
378
}
 
379
 
 
380
 
 
381
int wpa_ctrl_request(struct wpa_ctrl *ctrl, const char *cmd, size_t cmd_len,
 
382
                     char *reply, size_t *reply_len,
 
383
                     void (*msg_cb)(char *msg, size_t len))
 
384
{
 
385
        DWORD written;
 
386
        DWORD readlen = *reply_len;
 
387
 
 
388
        if (!WriteFile(ctrl->pipe, cmd, cmd_len, &written, NULL))
 
389
                return -1;
 
390
 
 
391
        if (!ReadFile(ctrl->pipe, reply, *reply_len, &readlen, NULL))
 
392
                return -1;
 
393
        *reply_len = readlen;
 
394
 
 
395
        return 0;
 
396
}
 
397
 
 
398
 
 
399
int wpa_ctrl_recv(struct wpa_ctrl *ctrl, char *reply, size_t *reply_len)
 
400
{
 
401
        DWORD len = *reply_len;
 
402
        if (!ReadFile(ctrl->pipe, reply, *reply_len, &len, NULL))
 
403
                return -1;
 
404
        *reply_len = len;
 
405
        return 0;
 
406
}
 
407
 
 
408
 
 
409
int wpa_ctrl_pending(struct wpa_ctrl *ctrl)
 
410
{
 
411
        DWORD left;
 
412
 
 
413
        if (!PeekNamedPipe(ctrl->pipe, NULL, 0, NULL, &left, NULL))
 
414
                return -1;
 
415
        return left ? 1 : 0;
 
416
}
 
417
 
 
418
 
 
419
int wpa_ctrl_get_fd(struct wpa_ctrl *ctrl)
 
420
{
 
421
        return -1;
 
422
}
 
423
 
 
424
#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
 
425
 
235
426
#endif /* CONFIG_CTRL_IFACE */