summaryrefslogtreecommitdiff
path: root/usr.sbin/hostapd/hostapd.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/hostapd/hostapd.c')
-rw-r--r--usr.sbin/hostapd/hostapd.c150
1 files changed, 147 insertions, 3 deletions
diff --git a/usr.sbin/hostapd/hostapd.c b/usr.sbin/hostapd/hostapd.c
index ca4f4661b37..e7dabf43f51 100644
--- a/usr.sbin/hostapd/hostapd.c
+++ b/usr.sbin/hostapd/hostapd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: hostapd.c,v 1.10 2005/05/21 19:18:51 msf Exp $ */
+/* $OpenBSD: hostapd.c,v 1.11 2005/06/17 19:13:35 reyk Exp $ */
/*
* Copyright (c) 2004, 2005 Reyk Floeter <reyk@vantronix.net>
@@ -54,6 +54,7 @@ void hostapd_sig_handler(int);
struct hostapd_config hostapd_cfg;
extern char *__progname;
+char printbuf[BUFSIZ];
void
hostapd_usage(void)
@@ -81,6 +82,31 @@ hostapd_log(u_int level, const char *fmt, ...)
}
void
+hostapd_printf(const char *fmt, ...)
+{
+ char newfmt[BUFSIZ];
+ va_list ap;
+ size_t n;
+
+ if (fmt == NULL) {
+ flush:
+ hostapd_log(HOSTAPD_LOG, "%s", printbuf);
+ bzero(printbuf, sizeof(printbuf));
+ return;
+ }
+
+ va_start(ap, fmt);
+ bzero(newfmt, sizeof(newfmt));
+ if ((n = strlcpy(newfmt, printbuf, sizeof(newfmt))) >= sizeof(newfmt))
+ goto flush;
+ if (strlcpy(newfmt + n, fmt, sizeof(newfmt) - n) >= sizeof(newfmt) - n)
+ goto flush;
+ if (vsnprintf(printbuf, sizeof(printbuf), newfmt, ap) == -1)
+ goto flush;
+ va_end(ap);
+}
+
+void
hostapd_fatal(const char *fmt, ...)
{
va_list ap;
@@ -258,7 +284,7 @@ void
hostapd_sig_handler(int sig)
{
struct timeval tv;
-
+
tv.tv_sec = 0;
tv.tv_usec = 0;
@@ -274,7 +300,10 @@ hostapd_sig_handler(int sig)
void
hostapd_cleanup(struct hostapd_config *cfg)
{
+ int i;
struct ip_mreq mreq;
+ struct hostapd_table *table;
+ struct hostapd_entry *entry;
if (cfg->c_flags & HOSTAPD_CFG_F_PRIV &&
(cfg->c_flags & HOSTAPD_CFG_F_BRDCAST) == 0 &&
@@ -304,6 +333,24 @@ hostapd_cleanup(struct hostapd_config *cfg)
hostapd_iapp_term(&hostapd_cfg);
}
+ /* Cleanup tables */
+ while ((table = TAILQ_FIRST(&cfg->c_tables)) != NULL) {
+ for (i = 0; i < HOSTAPD_TABLE_HASHSIZE; i++) {
+ while ((entry =
+ TAILQ_FIRST(&table->t_head[i])) != NULL) {
+ TAILQ_REMOVE(&table->t_head[i], entry,
+ e_entries);
+ free(entry);
+ }
+ }
+ while ((entry = TAILQ_FIRST(&table->t_mask_head)) != NULL) {
+ TAILQ_REMOVE(&table->t_mask_head, entry, e_entries);
+ free(entry);
+ }
+ TAILQ_REMOVE(&cfg->c_tables, table, t_entries);
+ free(table);
+ }
+
hostapd_log(HOSTAPD_LOG_VERBOSE, "bye!\n");
}
@@ -371,7 +418,8 @@ main(int argc, char *argv[])
hostapd_fatal("need root privileges\n");
/* Parse the configuration file */
- hostapd_parse_file(cfg);
+ if (hostapd_parse_file(cfg) != 0)
+ hostapd_fatal("invalid configuration\n");
if ((cfg->c_flags & HOSTAPD_CFG_F_IAPP) == 0)
hostapd_usage();
@@ -379,6 +427,9 @@ main(int argc, char *argv[])
if ((cfg->c_flags & HOSTAPD_CFG_F_APME) == 0)
strlcpy(cfg->c_apme_iface, "<none>", sizeof(cfg->c_apme_iface));
+ if (cfg->c_apme_dlt == 0)
+ cfg->c_apme_dlt = HOSTAPD_DLT;
+
/*
* Setup the hostapd handlers
*/
@@ -442,3 +493,96 @@ main(int argc, char *argv[])
hostapd_cleanup(cfg);
return (EXIT_SUCCESS);
}
+
+struct hostapd_table *
+hostapd_table_add(struct hostapd_config *cfg, const char *name)
+{
+ int i;
+ struct hostapd_table *table;
+
+ if (hostapd_table_lookup(cfg, name) != NULL)
+ return (NULL);
+ if ((table = (struct hostapd_table *)
+ calloc(1, sizeof(struct hostapd_table))) == NULL)
+ return (NULL);
+
+ strlcpy(table->t_name, name, sizeof(table->t_name));
+ for (i = 0; i < HOSTAPD_TABLE_HASHSIZE; i++)
+ TAILQ_INIT(&table->t_head[i]);
+ TAILQ_INIT(&table->t_mask_head);
+ TAILQ_INSERT_TAIL(&cfg->c_tables, table, t_entries);
+
+ return (table);
+}
+
+struct hostapd_table *
+hostapd_table_lookup(struct hostapd_config *cfg, const char *name)
+{
+ struct hostapd_table *table;
+
+ TAILQ_FOREACH(table, &cfg->c_tables, t_entries) {
+ if (strcmp(name, table->t_name) == 0)
+ return (table);
+ }
+
+ return (NULL);
+}
+
+struct hostapd_entry *
+hostapd_entry_add(struct hostapd_table *table, u_int8_t *lladdr)
+{
+ u_int hash;
+ struct hostapd_entry *entry;
+
+ if (hostapd_entry_lookup(table, lladdr) != NULL)
+ return (NULL);
+
+ if ((entry = (struct hostapd_entry *)
+ calloc(1, sizeof(struct hostapd_entry))) == NULL)
+ return (NULL);
+
+ bcopy(lladdr, entry->e_lladdr, IEEE80211_ADDR_LEN);
+ hash = HOSTAPD_TABLE_HASH(lladdr);
+ TAILQ_INSERT_TAIL(&table->t_head[hash], entry, e_entries);
+
+ return (entry);
+}
+
+struct hostapd_entry *
+hostapd_entry_lookup(struct hostapd_table *table, u_int8_t *lladdr)
+{
+ u_int hash;
+ struct hostapd_entry *entry;
+
+ hash = HOSTAPD_TABLE_HASH(lladdr);
+ TAILQ_FOREACH(entry, &table->t_head[hash], e_entries) {
+ if (bcmp(lladdr, entry->e_lladdr, IEEE80211_ADDR_LEN) == 0)
+ return (entry);
+ }
+
+ /* Masked entries can't be handled by the hash table */
+ TAILQ_FOREACH(entry, &table->t_mask_head, e_entries) {
+ if (HOSTAPD_ENTRY_MASK_MATCH(entry, lladdr))
+ return (entry);
+ }
+
+ return (NULL);
+}
+
+void
+hostapd_entry_update(struct hostapd_table *table, struct hostapd_entry *entry)
+{
+ u_int hash;
+
+ hash = HOSTAPD_TABLE_HASH(entry->e_lladdr);
+ TAILQ_REMOVE(&table->t_head[hash], entry, e_entries);
+
+ /* Apply mask to entry */
+ if (entry->e_flags & HOSTAPD_ENTRY_F_MASK) {
+ HOSTAPD_ENTRY_MASK_ADD(entry->e_lladdr, entry->e_mask);
+ TAILQ_INSERT_TAIL(&table->t_mask_head, entry, e_entries);
+ } else {
+ hash = HOSTAPD_TABLE_HASH(entry->e_lladdr);
+ TAILQ_INSERT_TAIL(&table->t_head[hash], entry, e_entries);
+ }
+}