summaryrefslogtreecommitdiff
path: root/src/libwpactrl
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2017-08-04 22:46:45 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2017-08-04 22:46:45 +0000
commitbabf43abf301d072192bda1f72a47440c354b072 (patch)
treed917d33ebb97d2b783e163f299b360be4f5b3a0a /src/libwpactrl
parent69099d84949a8044fdfc74e9d7ff6b9e57fc0bcd (diff)
downloadbcnm-babf43abf301d072192bda1f72a47440c354b072.tar.xz
Add the higher layer of libwpactrl
Diffstat (limited to 'src/libwpactrl')
-rw-r--r--src/libwpactrl/deps-lib/wpactrl9
-rw-r--r--src/libwpactrl/wpactrl_addnetwork.c15
-rw-r--r--src/libwpactrl/wpactrl_associate.c34
-rw-r--r--src/libwpactrl/wpactrl_bssid_scan.c29
-rw-r--r--src/libwpactrl/wpactrl_command.c5
-rw-r--r--src/libwpactrl/wpactrl_findnetwork.c26
-rw-r--r--src/libwpactrl/wpactrl_flags_scan.c30
-rw-r--r--src/libwpactrl/wpactrl_networks_parse.c68
-rw-r--r--src/libwpactrl/wpactrl_query.c5
-rw-r--r--src/libwpactrl/wpactrl_querysa.c4
-rw-r--r--src/libwpactrl/wpactrl_removenetwork.c11
-rw-r--r--src/libwpactrl/wpactrl_scan_parse.c59
-rw-r--r--src/libwpactrl/wpactrl_selectnetwork.c11
-rw-r--r--src/libwpactrl/wpactrl_setnetworkoption.c21
-rw-r--r--src/libwpactrl/wpactrl_xchg_init.c3
15 files changed, 274 insertions, 56 deletions
diff --git a/src/libwpactrl/deps-lib/wpactrl b/src/libwpactrl/deps-lib/wpactrl
index 1943682..74d579a 100644
--- a/src/libwpactrl/deps-lib/wpactrl
+++ b/src/libwpactrl/deps-lib/wpactrl
@@ -1,4 +1,7 @@
wpactrl_ackmsg.o
+wpactrl_addnetwork.o
+wpactrl_associate.o
+wpactrl_bssid_scan.o
wpactrl_command.o
wpactrl_end.o
wpactrl_env_parse.o
@@ -8,10 +11,16 @@ wpactrl_filter_add.o
wpactrl_filter_exact_search.o
wpactrl_filter_match.o
wpactrl_filter_remove.o
+wpactrl_findnetwork.o
+wpactrl_flags_scan.o
wpactrl_msg.o
+wpactrl_networks_parse.o
wpactrl_query.o
wpactrl_querysa.o
+wpactrl_removenetwork.o
wpactrl_scan_parse.o
+wpactrl_selectnetwork.o
+wpactrl_setnetworkoption.o
wpactrl_start.o
wpactrl_update.o
wpactrl_xchg_computedeadline.o
diff --git a/src/libwpactrl/wpactrl_addnetwork.c b/src/libwpactrl/wpactrl_addnetwork.c
new file mode 100644
index 0000000..65e5963
--- /dev/null
+++ b/src/libwpactrl/wpactrl_addnetwork.c
@@ -0,0 +1,15 @@
+/* ISC license. */
+
+#include <string.h>
+#include <errno.h>
+#include <skalibs/uint32.h>
+#include <skalibs/error.h>
+#include <bcnm/wpactrl.h>
+
+int wpactrl_addnetwork (wpactrl_t *a, uint32_t *id, tain_t *stamp)
+{
+ char buf[UINT32_FMT] ;
+ if (wpactrl_query(a, "ADD_NETWORK", buf, UINT32_FMT, stamp) < 0) return 0 ;
+ if (uint32_scan(buf, id)) return 1 ;
+ return (errno = EPROTO, 0) ;
+}
diff --git a/src/libwpactrl/wpactrl_associate.c b/src/libwpactrl/wpactrl_associate.c
new file mode 100644
index 0000000..59900d6
--- /dev/null
+++ b/src/libwpactrl/wpactrl_associate.c
@@ -0,0 +1,34 @@
+/* ISC license. */
+
+#include <stdint.h>
+#include <errno.h>
+#include <bcnm/wpactrl.h>
+
+int wpactrl_associate (wpactrl_t *a, char const *ssid, char const *psk, tain_t *stamp)
+{
+ uint32_t id ;
+ int r = wpactrl_findnetwork(a, ssid, &id, stamp) ;
+ if (r < 0) return 0 ;
+ if (!r)
+ {
+ if (!wpactrl_addnetwork(a, &id, stamp)) goto err ;
+ }
+
+ if (psk)
+ {
+ if (wpactrl_setnetworkoption(a, id, "key_mgmt", "WPA-PSK WPA-PSK-SHA256", stamp) != WPA_OK
+ || wpactrl_setnetworkoption(a, id, "mem_only_psk", "1", stamp) != WPA_OK
+ || wpactrl_setnetworkoption(a, id, "psk", psk, stamp) != WPA_OK) goto err ;
+ }
+ else
+ {
+ if (wpactrl_setnetworkoption(a, id, "key_mgmt", "NONE", stamp) != WPA_OK)
+ goto err ;
+ }
+
+ if (wpactrl_selectnetwork(a, id, stamp) != WPA_OK) goto err ;
+ return 1 ;
+
+ err:
+ return (errno = EIO, 0) ;
+}
diff --git a/src/libwpactrl/wpactrl_bssid_scan.c b/src/libwpactrl/wpactrl_bssid_scan.c
new file mode 100644
index 0000000..ad4196c
--- /dev/null
+++ b/src/libwpactrl/wpactrl_bssid_scan.c
@@ -0,0 +1,29 @@
+/* ISC license. */
+
+#include <string.h>
+#include <errno.h>
+#include <skalibs/error.h>
+#include <skalibs/fmtscan.h>
+#include <bcnm/wpactrl.h>
+
+size_t wpactrl_bssid_scan (char const *s, char *bssid)
+{
+ unsigned int i = 0 ;
+ if (!strncmp(s, "any", 3))
+ {
+ memset(bssid, 0, 6) ;
+ return 3 ;
+ }
+ for (; i < 5 ; i++)
+ {
+ if (!ucharn_scan(s, bssid + i, 1)) goto eproto ;
+ if (s[2] != ':') goto eproto ;
+ s += 3 ;
+ }
+ if (!ucharn_scan(s, bssid + 5, 1)) goto eproto ;
+ return 17 ;
+
+ eproto:
+ return (errno = EPROTO, 0) ;
+}
+
diff --git a/src/libwpactrl/wpactrl_command.c b/src/libwpactrl/wpactrl_command.c
index 34e31c2..f7912ab 100644
--- a/src/libwpactrl/wpactrl_command.c
+++ b/src/libwpactrl/wpactrl_command.c
@@ -1,6 +1,5 @@
/* ISC license. */
-#include <string.h>
#include <errno.h>
#include <bcnm/wpactrl.h>
@@ -12,7 +11,7 @@ struct wparesponse_map_s
wparesponse_t r ;
} ;
-wparesponse_t wpactrl_command (wpactrl_t *a, char const *s, size_t len, tain_t *stamp)
+wparesponse_t wpactrl_command (wpactrl_t *a, char const *s, tain_t *stamp)
{
static struct wparesponse_map_s const wparesponses[] =
{
@@ -34,7 +33,7 @@ wparesponse_t wpactrl_command (wpactrl_t *a, char const *s, size_t len, tain_t *
{ 0, WPA_UNKNOWNRESPONSE }
} ;
char buf[WPARESPONSE_MAXLEN] ;
- ssize_t r = wpactrl_query(a, s, len, buf, WPARESPONSE_MAXLEN, stamp) ;
+ ssize_t r = wpactrl_query(a, s, buf, WPARESPONSE_MAXLEN, stamp) ;
if (r < 0) return WPA_ERROR ;
if (!r) return (errno = EPIPE, WPA_ERROR) ;
{
diff --git a/src/libwpactrl/wpactrl_findnetwork.c b/src/libwpactrl/wpactrl_findnetwork.c
new file mode 100644
index 0000000..e5851d0
--- /dev/null
+++ b/src/libwpactrl/wpactrl_findnetwork.c
@@ -0,0 +1,26 @@
+/* ISC license. */
+
+#include <skalibs/stralloc.h>
+#include <skalibs/genalloc.h>
+#include <bcnm/wpactrl.h>
+#include "wpactrl-internal.h"
+
+int wpactrl_findnetwork (wpactrl_t *a, char const *ssid, uint32_t *id, tain_t *stamp)
+{
+ char buf[WPACTRL_PACKET_MAX] ;
+ stralloc sa = STRALLOC_ZERO ;
+ genalloc ga = GENALLOC_ZERO ; /* wpactrl_networks_t */
+ size_t i = 0 ;
+ wpactrl_networks_t *p ;
+ size_t n ;
+ ssize_t r = wpactrl_query(a, "LIST_NETWORKS", buf, WPACTRL_PACKET_MAX, stamp) ;
+ if (r < 0) return -1 ;
+ if (!wpactrl_networks_parse(buf, r, &ga, &sa)) return -1 ;
+ n = genalloc_len(wpactrl_networks_t, &ga) ;
+ p = genalloc_s(wpactrl_networks_t, &ga) ;
+ for (; i < n ; i++) if (!strcmp(ssid, sa.s + p[i].ssid_start)) break ;
+ if (i < n) *id = p[i].id ;
+ genalloc_free(wpactrl_networks_t, &ga) ;
+ stralloc_free(&sa) ;
+ return i < n ;
+}
diff --git a/src/libwpactrl/wpactrl_flags_scan.c b/src/libwpactrl/wpactrl_flags_scan.c
new file mode 100644
index 0000000..e8eecf5
--- /dev/null
+++ b/src/libwpactrl/wpactrl_flags_scan.c
@@ -0,0 +1,30 @@
+/* ISC license. */
+
+#include <errno.h>
+#include <skalibs/bytestr.h>
+#include <skalibs/error.h>
+#include <skalibs/stralloc.h>
+#include <bcnm/wpactrl.h>
+
+size_t wpactrl_flags_scan (char const *t, stralloc *sa)
+{
+ size_t sabase = sa->len ;
+ int wasnull = !sa->s ;
+ char const *s = t ;
+ while (*s == '[')
+ {
+ size_t pos ;
+ pos = str_chr(s, ']') ;
+ if (!s[pos]) goto eproto ;
+ if (!stralloc_catb(sa, s, pos) || !stralloc_0(sa)) goto err ;
+ s += pos + 1 ;
+ }
+ return s - t ;
+
+ eproto:
+ errno = EPROTO ;
+ err:
+ if (wasnull) stralloc_free(sa) ;
+ else sa->len = sabase ;
+ return 0 ;
+}
diff --git a/src/libwpactrl/wpactrl_networks_parse.c b/src/libwpactrl/wpactrl_networks_parse.c
new file mode 100644
index 0000000..444941a
--- /dev/null
+++ b/src/libwpactrl/wpactrl_networks_parse.c
@@ -0,0 +1,68 @@
+/* ISC license. */
+
+#include <string.h>
+#include <stdint.h>
+#include <errno.h>
+#include <skalibs/uint32.h>
+#include <skalibs/bytestr.h>
+#include <skalibs/error.h>
+#include <skalibs/fmtscan.h>
+#include <skalibs/stralloc.h>
+#include <skalibs/genalloc.h>
+#include <bcnm/wpactrl.h>
+
+static int wpactrl_networks_parse_one (char const *s, size_t len, wpactrl_networks_t *thing, stralloc *sa)
+{
+ wpactrl_networks_t sr ;
+ size_t pos = byte_chr(s, len, '\t') ;
+ if (pos >= len) goto eproto ;
+ if (uint32_scan(s, &sr.id) != pos) goto eproto ;
+ s += pos + 1 ; len -= pos + 1 ;
+
+ pos = byte_rchr(s, len, '\t') ;
+ if (!pos || pos >= len) goto eproto ;
+ sr.flags_start = sa->len ;
+ if (wpactrl_flags_scan(s + pos + 1, sa) != pos) goto eproto ;
+ sr.flags_len = sa->len - sr.flags_start ;
+ len = pos ;
+
+ pos = byte_rchr(s, len - 1, '\t') ;
+ if (!pos || pos >= len - 1) goto eproto ;
+ if (wpactrl_bssid_scan(s + pos + 1, sr.bssid) != len - 1) goto eproto ;
+ len = pos ;
+
+ sr.ssid_start = sa->len ;
+ sr.ssid_len = len - 1 ;
+ if (!stralloc_catb(sa, s, len - 1) || !stralloc_0(sa)) return 0 ;
+ *thing = sr ;
+ return 1 ;
+
+ eproto:
+ return (errno = EPROTO, 0) ;
+}
+
+int wpactrl_networks_parse (char const *s, size_t len, genalloc *ga, stralloc *sa)
+{
+ int sawasnull = !sa->s ;
+ int gawasnull = !genalloc_s(wpactrl_networks_t, ga) ;
+ size_t sabase = sa->len ;
+ size_t gabase = genalloc_len(wpactrl_networks_t, ga) ;
+ size_t start = byte_chr(s, len, '\n') ;
+ if (start++ >= len) return (errno = EPROTO, 0) ;
+ while (start < len)
+ {
+ size_t pos = byte_chr(s + start, len - start, '\n') ;
+ wpactrl_networks_t thing ;
+ if (!wpactrl_networks_parse_one(s + start, pos, &thing, sa)) goto err ;
+ if (!genalloc_append(wpactrl_networks_t, ga, &thing)) goto err ;
+ start += pos + 1 ;
+ }
+ return 1 ;
+
+ err:
+ if (gawasnull) genalloc_free(wpactrl_networks_t, ga) ;
+ else genalloc_setlen(wpactrl_networks_t, ga, gabase) ;
+ if (sawasnull) stralloc_free(sa) ;
+ else sa->len = sabase ;
+ return 0 ;
+}
diff --git a/src/libwpactrl/wpactrl_query.c b/src/libwpactrl/wpactrl_query.c
index b03899f..b8b42df 100644
--- a/src/libwpactrl/wpactrl_query.c
+++ b/src/libwpactrl/wpactrl_query.c
@@ -1,13 +1,14 @@
/* ISC license. */
+#include <string.h>
#include <skalibs/unix-timed.h>
#include <bcnm/wpactrl.h>
#include "wpactrl-internal.h"
-ssize_t wpactrl_query (wpactrl_t *a, char const *q, size_t qlen, char *ans, size_t ansmax, tain_t *stamp)
+ssize_t wpactrl_query (wpactrl_t *a, char const *q, char *ans, size_t ansmax, tain_t *stamp)
{
tain_t deadline ;
tain_add(&deadline, stamp, &a->tto) ;
- if (!ipc_timed_send(a->fds, q, qlen, &deadline, stamp)) return WPA_ERROR ;
+ if (!ipc_timed_send(a->fds, q, strlen(q), &deadline, stamp)) return WPA_ERROR ;
return wpactrl_fd_timed_recv(a->fds, ans, ansmax, &deadline, stamp) ;
}
diff --git a/src/libwpactrl/wpactrl_querysa.c b/src/libwpactrl/wpactrl_querysa.c
index 887941f..8afaa92 100644
--- a/src/libwpactrl/wpactrl_querysa.c
+++ b/src/libwpactrl/wpactrl_querysa.c
@@ -5,10 +5,10 @@
#include <bcnm/wpactrl.h>
#include "wpactrl-internal.h"
-int wpactrl_querysa (wpactrl_t *a, char const *s, size_t len, stralloc *sa, tain_t *stamp)
+int wpactrl_querysa (wpactrl_t *a, char const *s, stralloc *sa, tain_t *stamp)
{
char buf[WPACTRL_PACKET_MAX] ;
- ssize_t r = wpactrl_query(a, s, len, buf, WPACTRL_PACKET_MAX, stamp) ;
+ ssize_t r = wpactrl_query(a, s, buf, WPACTRL_PACKET_MAX, stamp) ;
if (r < 0) return 0 ;
if (!r) return (errno = EPIPE, 0) ;
return stralloc_catb(sa, buf, r) ;
diff --git a/src/libwpactrl/wpactrl_removenetwork.c b/src/libwpactrl/wpactrl_removenetwork.c
new file mode 100644
index 0000000..f943b72
--- /dev/null
+++ b/src/libwpactrl/wpactrl_removenetwork.c
@@ -0,0 +1,11 @@
+/* ISC license. */
+
+#include <skalibs/uint32.h>
+#include <bcnm/wpactrl.h>
+
+wparesponse_t wpactrl_removenetwork (wpactrl_t *a, uint32_t id, tain_t *stamp)
+{
+ char buf[15 + UINT32_FMT] = "REMOVE_NETWORK " ;
+ buf[15 + uint32_fmt(buf + 15, id)] = 0 ;
+ return wpactrl_command(a, buf, stamp) ;
+}
diff --git a/src/libwpactrl/wpactrl_scan_parse.c b/src/libwpactrl/wpactrl_scan_parse.c
index ab4a9fe..e75072d 100644
--- a/src/libwpactrl/wpactrl_scan_parse.c
+++ b/src/libwpactrl/wpactrl_scan_parse.c
@@ -3,7 +3,7 @@
#include <string.h>
#include <stdint.h>
#include <errno.h>
-#include <skalibs/uint16.h>
+#include <skalibs/uint32.h>
#include <skalibs/bytestr.h>
#include <skalibs/error.h>
#include <skalibs/fmtscan.h>
@@ -11,56 +11,25 @@
#include <skalibs/genalloc.h>
#include <bcnm/wpactrl.h>
-static size_t bssid_scan (char const *s, char *bssid)
-{
- unsigned int i = 0 ;
- char sep[6] = ":::::\t" ;
- for (; i < 6 ; i++)
- {
- if (!ucharn_scan(s, bssid + i, 1)) goto eproto ;
- if (s[2] != sep[i]) goto eproto ;
- s += 3 ;
- }
- return 18 ;
-
- eproto:
- return (errno = EPROTO, 0) ;
-}
-
-static int flags_scan (char const *s, size_t len, stralloc *sa)
-{
- while (len)
- {
- size_t pos ;
- if (*s++ != '[') goto eproto ;
- len-- ;
- pos = byte_chr(s, len, ']') ;
- if (pos >= len || !pos) goto eproto ;
- if (!stralloc_catb(sa, s, pos) || !stralloc_0(sa)) return 0 ;
- s += pos + 1 ; len -= pos + 1 ;
- }
- return 1 ;
-
- eproto:
- return (errno = EPROTO, 0) ;
-}
-
static int wpactrl_scan_parse_one (char const *s, size_t len, wpactrl_scanres_t *thing, stralloc *sa)
{
wpactrl_scanres_t sr ;
size_t pos = byte_chr(s, len, '\t') ;
if (pos >= len) goto eproto ;
- if (pos != 18) goto eproto ;
- if (bssid_scan(s, sr.bssid) != pos) goto eproto ;
+ if (wpactrl_bssid_scan(s, sr.bssid) != pos) goto eproto ;
s += pos + 1 ; len -= pos + 1 ;
pos = byte_chr(s, len, '\t') ;
if (pos >= len) goto eproto ;
- if (uint16_scan(s, &sr.frequency) != pos) goto eproto ;
+ if (uint32_scan(s, &sr.frequency) != pos) goto eproto ;
+ s += pos + 1 ; len -= pos + 1 ;
+ pos = byte_chr(s, len, '\t') ;
+ if (pos >= len) goto eproto ;
+ if (uint32_scan(s, &sr.signal_level) != pos) goto eproto ;
s += pos + 1 ; len -= pos + 1 ;
pos = byte_chr(s, len, '\t') ;
if (pos >= len) goto eproto ;
sr.flags_start = sa->len ;
- if (!flags_scan(s, pos, sa)) goto eproto ;
+ if (wpactrl_flags_scan(s, sa) != pos) goto eproto ;
s += pos + 1 ; len -= pos + 1 ;
sr.flags_len = sa->len - sr.flags_start ;
sr.ssid_start = sa->len ;
@@ -92,13 +61,9 @@ int wpactrl_scan_parse (char const *s, size_t len, genalloc *ga, stralloc *sa)
return 1 ;
err:
- {
- int e = errno ;
- if (gawasnull) genalloc_free(wpactrl_scanres_t, ga) ;
- else genalloc_setlen(wpactrl_scanres_t, ga, gabase) ;
- if (sawasnull) stralloc_free(sa) ;
- else sa->len = sabase ;
- errno = e ;
- }
+ if (gawasnull) genalloc_free(wpactrl_scanres_t, ga) ;
+ else genalloc_setlen(wpactrl_scanres_t, ga, gabase) ;
+ if (sawasnull) stralloc_free(sa) ;
+ else sa->len = sabase ;
return 0 ;
}
diff --git a/src/libwpactrl/wpactrl_selectnetwork.c b/src/libwpactrl/wpactrl_selectnetwork.c
new file mode 100644
index 0000000..25842e4
--- /dev/null
+++ b/src/libwpactrl/wpactrl_selectnetwork.c
@@ -0,0 +1,11 @@
+/* ISC license. */
+
+#include <skalibs/uint32.h>
+#include <bcnm/wpactrl.h>
+
+wparesponse_t wpactrl_selectnetwork (wpactrl_t *a, uint32_t id, tain_t *stamp)
+{
+ char buf[15 + UINT32_FMT] = "SELECT_NETWORK " ;
+ buf[15 + uint32_fmt(buf + 15, id)] = 0 ;
+ return wpactrl_command(a, buf, stamp) ;
+}
diff --git a/src/libwpactrl/wpactrl_setnetworkoption.c b/src/libwpactrl/wpactrl_setnetworkoption.c
new file mode 100644
index 0000000..5b2fdca
--- /dev/null
+++ b/src/libwpactrl/wpactrl_setnetworkoption.c
@@ -0,0 +1,21 @@
+/* ISC license. */
+
+#include <string.h>
+#include <skalibs/uint32.h>
+#include <bcnm/wpactrl.h>
+
+wparesponse_t wpactrl_setnetworkoption (wpactrl_t *a, uint32_t id, char const *var, char const *val, tain_t *stamp)
+{
+ size_t varlen = strlen(var) ;
+ size_t vallen = strlen(val) ;
+ size_t idlen ;
+ char buf[15 + UINT32_FMT + varlen + vallen] ;
+ memcpy(buf, "SET_NETWORK ", 12) ;
+ idlen = uint32_fmt(buf + 12, id) ;
+ buf[12 + idlen] = ' ' ;
+ memcpy(buf + 13 + idlen, var, varlen) ;
+ buf[13 + idlen + varlen] = ' ' ;
+ memcpy(buf + 14 + idlen + varlen, val, vallen) ;
+ buf[14 + idlen + varlen + vallen] = 0 ;
+ return wpactrl_command(a, buf, stamp) ;
+}
diff --git a/src/libwpactrl/wpactrl_xchg_init.c b/src/libwpactrl/wpactrl_xchg_init.c
index 37006dd..2e2f391 100644
--- a/src/libwpactrl/wpactrl_xchg_init.c
+++ b/src/libwpactrl/wpactrl_xchg_init.c
@@ -4,7 +4,7 @@
#include <skalibs/stralloc.h>
#include <bcnm/wpactrl.h>
-int wpactrl_xchg_init (wpactrl_xchg_t *dt, wpactrl_xchgitem_t const *tab, unsigned int n, tain_t const *limit, void *aux)
+void wpactrl_xchg_init (wpactrl_xchg_t *dt, wpactrl_xchgitem_t const *tab, unsigned int n, tain_t const *limit, void *aux)
{
dt->sa.len = 0 ;
dt->tab = tab ;
@@ -13,5 +13,4 @@ int wpactrl_xchg_init (wpactrl_xchg_t *dt, wpactrl_xchgitem_t const *tab, unsign
dt->deadline = *limit ;
dt->status = ECONNABORTED ;
dt->aux = aux ;
- return 1 ;
}