2
* WPA Supplicant - wpa_supplicant control interface library
3
* Copyright (c) 2004-2005, Jouni Malinen <jkmaline@cc.hut.fi>
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License version 2 as
7
* published by the Free Software Foundation.
9
* Alternatively, this software may be distributed under the terms of BSD
12
* See README and COPYING for more details.
19
#include <sys/types.h>
21
#ifndef CONFIG_NATIVE_WINDOWS
22
#include <sys/socket.h>
24
#endif /* CONFIG_NATIVE_WINDOWS */
27
#ifdef CONFIG_NATIVE_WINDOWS
29
#endif /* CONFIG_NATIVE_WINDOWS */
34
#ifdef CONFIG_CTRL_IFACE_UDP
35
struct sockaddr_in local;
36
struct sockaddr_in dest;
37
#else /* CONFIG_CTRL_IFACE_UDP */
38
struct sockaddr_un local;
39
struct sockaddr_un dest;
40
#endif /* CONFIG_CTRL_IFACE_UDP */
44
struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path)
46
struct wpa_ctrl *ctrl;
47
#ifndef CONFIG_CTRL_IFACE_UDP
48
static int counter = 0;
49
#endif /* CONFIG_CTRL_IFACE_UDP */
51
ctrl = malloc(sizeof(*ctrl));
54
memset(ctrl, 0, sizeof(*ctrl));
56
#ifdef CONFIG_CTRL_IFACE_UDP
57
ctrl->s = socket(PF_INET, SOCK_DGRAM, 0);
64
ctrl->local.sin_family = AF_INET;
65
ctrl->local.sin_addr.s_addr = htonl((127 << 24) | 1);
66
if (bind(ctrl->s, (struct sockaddr *) &ctrl->local,
67
sizeof(ctrl->local)) < 0) {
73
ctrl->dest.sin_family = AF_INET;
74
ctrl->dest.sin_addr.s_addr = htonl((127 << 24) | 1);
75
ctrl->dest.sin_port = htons(9877);
76
if (connect(ctrl->s, (struct sockaddr *) &ctrl->dest,
77
sizeof(ctrl->dest)) < 0) {
83
#else /* CONFIG_CTRL_IFACE_UDP */
84
ctrl->s = socket(PF_UNIX, SOCK_DGRAM, 0);
90
ctrl->local.sun_family = AF_UNIX;
91
snprintf(ctrl->local.sun_path, sizeof(ctrl->local.sun_path),
92
"/tmp/wpa_ctrl_%d-%d", getpid(), counter++);
93
if (bind(ctrl->s, (struct sockaddr *) &ctrl->local,
94
sizeof(ctrl->local.sun_family) +
95
strlen(ctrl->local.sun_path)) < 0) {
101
ctrl->dest.sun_family = AF_UNIX;
102
strncpy(ctrl->dest.sun_path, ctrl_path, sizeof(ctrl->dest.sun_path));
103
if (connect(ctrl->s, (struct sockaddr *) &ctrl->dest,
104
sizeof(ctrl->dest.sun_family) +
105
strlen(ctrl->dest.sun_path)) < 0) {
107
unlink(ctrl->local.sun_path);
111
#endif /* CONFIG_CTRL_IFACE_UDP */
117
void wpa_ctrl_close(struct wpa_ctrl *ctrl)
119
#ifndef CONFIG_CTRL_IFACE_UDP
120
unlink(ctrl->local.sun_path);
121
#endif /* CONFIG_CTRL_IFACE_UDP */
127
int wpa_ctrl_request(struct wpa_ctrl *ctrl, char *cmd, size_t cmd_len,
128
char *reply, size_t *reply_len,
129
void (*msg_cb)(char *msg, size_t len))
135
if (send(ctrl->s, cmd, cmd_len, 0) < 0)
142
FD_SET(ctrl->s, &rfds);
143
res = select(ctrl->s + 1, &rfds, NULL, NULL, &tv);
144
if (FD_ISSET(ctrl->s, &rfds)) {
145
res = recv(ctrl->s, reply, *reply_len, 0);
148
if (res > 0 && reply[0] == '<') {
149
/* This is an unsolicited message from
150
* wpa_supplicant, not the reply to the
151
* request. Use msg_cb to report this to the
154
/* Make sure the message is nul
156
if (res == *reply_len)
157
res = (*reply_len) - 1;
173
static int wpa_ctrl_attach_helper(struct wpa_ctrl *ctrl, int attach)
179
ret = wpa_ctrl_request(ctrl, attach ? "ATTACH" : "DETACH", 6,
183
if (len == 3 && memcmp(buf, "OK\n", 3) == 0)
189
int wpa_ctrl_attach(struct wpa_ctrl *ctrl)
191
return wpa_ctrl_attach_helper(ctrl, 1);
195
int wpa_ctrl_detach(struct wpa_ctrl *ctrl)
197
return wpa_ctrl_attach_helper(ctrl, 0);
201
int wpa_ctrl_recv(struct wpa_ctrl *ctrl, char *reply, size_t *reply_len)
205
res = recv(ctrl->s, reply, *reply_len, 0);
213
int wpa_ctrl_pending(struct wpa_ctrl *ctrl)
221
FD_SET(ctrl->s, &rfds);
222
res = select(ctrl->s + 1, &rfds, NULL, NULL, &tv);
223
return FD_ISSET(ctrl->s, &rfds);
227
int wpa_ctrl_get_fd(struct wpa_ctrl *ctrl)