| version 1.1.2.12, 2010/11/02 02:12:49 | version 1.3.4.1, 2014/01/30 01:03:23 | 
| Line 1 | Line 1 | 
 |  | /************************************************************************* | 
 |  | * (C) 2010 AITNET - Sofia/Bulgaria - <office@aitbg.com> | 
 |  | *  by Michael Pounov <misho@aitbg.com> | 
 |  | * | 
 |  | * $Author$ | 
 |  | * $Id$ | 
 |  | * | 
 |  | ************************************************************************* | 
 |  | The ELWIX and AITNET software is distributed under the following | 
 |  | terms: | 
 |  |  | 
 |  | All of the documentation and software included in the ELWIX and AITNET | 
 |  | Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org> | 
 |  |  | 
 |  | Copyright 2004 - 2014 | 
 |  | by Michael Pounov <misho@elwix.org>.  All rights reserved. | 
 |  |  | 
 |  | Redistribution and use in source and binary forms, with or without | 
 |  | modification, are permitted provided that the following conditions | 
 |  | are met: | 
 |  | 1. Redistributions of source code must retain the above copyright | 
 |  | notice, this list of conditions and the following disclaimer. | 
 |  | 2. Redistributions in binary form must reproduce the above copyright | 
 |  | notice, this list of conditions and the following disclaimer in the | 
 |  | documentation and/or other materials provided with the distribution. | 
 |  | 3. All advertising materials mentioning features or use of this software | 
 |  | must display the following acknowledgement: | 
 |  | This product includes software developed by Michael Pounov <misho@elwix.org> | 
 |  | ELWIX - Embedded LightWeight unIX and its contributors. | 
 |  | 4. Neither the name of AITNET nor the names of its contributors | 
 |  | may be used to endorse or promote products derived from this software | 
 |  | without specific prior written permission. | 
 |  |  | 
 |  | THIS SOFTWARE IS PROVIDED BY AITNET AND CONTRIBUTORS ``AS IS'' AND | 
 |  | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 
 |  | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 
 |  | ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 
 |  | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 
 |  | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 
 |  | OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 
 |  | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 
 |  | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 
 |  | OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 
 |  | SUCH DAMAGE. | 
 |  | */ | 
 | #include "global.h" | #include "global.h" | 
 | #include "dwds.h" | #include "dwds.h" | 
 |  |  | 
 |  |  | 
| sl_config cfg; | cfg_root_t cfg; | 
 | int Verbose, Kill, nif; | int Verbose, Kill, nif; | 
 | char **ifs, szConfig[MAXPATHLEN] = DWDS_CONFIG; | char **ifs, szConfig[MAXPATHLEN] = DWDS_CONFIG; | 
 | extern char compiled[], compiledby[], compilehost[]; | extern char compiled[], compiledby[], compilehost[]; | 
| Line 25  static void | Line 70  static void | 
 | sigHandler(int sig) | sigHandler(int sig) | 
 | { | { | 
 | int stat; | int stat; | 
| const u_char *v; | ait_val_t name; | 
| char szStr[STRSIZ]; | const char *v; | 
 |  |  | 
 | switch (sig) { | switch (sig) { | 
 | case SIGHUP: | case SIGHUP: | 
| UnloadConfig(&cfg); | cfgUnloadConfig(&cfg); | 
| if (LoadConfig(szConfig, &cfg)) { | if (cfgLoadConfig(szConfig, &cfg)) { | 
 | printf("Error:: can`t load config %s ...\n", szConfig); | printf("Error:: can`t load config %s ...\n", szConfig); | 
 | Kill++; | Kill++; | 
 | } else { | } else { | 
 | closelog(); | closelog(); | 
 |  |  | 
| cfg_LoadAttribute(&cfg, CFG("dwds"), CFG("name"), CFG(szStr), STRSIZ, DWDS_NAME); | cfg_loadAttribute(&cfg, "dwds", "name", &name, DWDS_NAME); | 
| openlog(szStr, LOG_PID | LOG_CONS, LOG_DAEMON); | openlog(AIT_GET_STR(&name), LOG_PID | LOG_CONS, LOG_DAEMON); | 
| v = cfg_GetAttribute(&cfg, CFG("dwds"), CFG("syslog_upto")); | AIT_FREE_VAL(&name); | 
| setlogmask(v ? strtol((char*) v, NULL, 0) : 0); | v = cfg_getAttribute(&cfg, "dwds", "syslog_upto"); | 
|  | setlogmask(v ? strtol(v, NULL, 0) : 0); | 
 | } | } | 
 | break; | break; | 
 | case SIGTERM: | case SIGTERM: | 
| Line 56  static int | Line 102  static int | 
 | RtMsg(struct dwds_if **wds, struct rt_msghdr *msg, size_t len) | RtMsg(struct dwds_if **wds, struct rt_msghdr *msg, size_t len) | 
 | { | { | 
 | struct if_announcemsghdr *ifan; | struct if_announcemsghdr *ifan; | 
| const u_char *v; | const char *v; | 
 | struct ether_addr bssid; | struct ether_addr bssid; | 
| char szStr[STRSIZ] = { 0 }, szCmd[MAXPATHLEN] = { 0 }, szIdent[STRSIZ] = { 0 }, | ait_val_t Str, Ident; | 
| szName[IFNAMSIZ] = { 0 }; | char szCmd[MAXPATHLEN] = { 0 }, szName[IFNAMSIZ] = { 0 }; | 
 | int f, stat; | int f, stat; | 
 |  |  | 
 | assert(wds); | assert(wds); | 
| Line 90  RtMsg(struct dwds_if **wds, struct rt_msghdr *msg, siz | Line 136  RtMsg(struct dwds_if **wds, struct rt_msghdr *msg, siz | 
 | ifan = (struct if_announcemsghdr*) msg; | ifan = (struct if_announcemsghdr*) msg; | 
 | switch (ifan->ifan_what) { | switch (ifan->ifan_what) { | 
 | case RTM_IEEE80211_DISASSOC: | case RTM_IEEE80211_DISASSOC: | 
| v = cfg_GetAttribute(&cfg, CFG("dwds"), CFG("discover_on_join")); | v = cfg_getAttribute(&cfg, "dwds", "discover_on_join"); | 
| if (!v || !strtol((char*) v, NULL, 0)) | if (!v || !strtol(v, NULL, 0)) | 
 | break; | break; | 
 | /* fall thru ... */ | /* fall thru ... */ | 
 | case RTM_IEEE80211_LEAVE: | case RTM_IEEE80211_LEAVE: | 
| Line 100  RtMsg(struct dwds_if **wds, struct rt_msghdr *msg, siz | Line 146  RtMsg(struct dwds_if **wds, struct rt_msghdr *msg, siz | 
 | memcpy(&bssid, V(ieee80211_leave_event)->iev_addr, ETHER_ADDR_LEN); | memcpy(&bssid, V(ieee80211_leave_event)->iev_addr, ETHER_ADDR_LEN); | 
 | VERB(1) syslog(LOG_INFO, "BSSID:%s Station leave\n", ether_ntoa(&bssid)); | VERB(1) syslog(LOG_INFO, "BSSID:%s Station leave\n", ether_ntoa(&bssid)); | 
 | if (!wifi_leaveWDS(bssid, wds, szName, IFNAMSIZ)) { | if (!wifi_leaveWDS(bssid, wds, szName, IFNAMSIZ)) { | 
| cfg_LoadAttribute(&cfg, CFG("dwds"), CFG("name"), | cfg_loadAttribute(&cfg, "dwds", "name", &Ident, DWDS_NAME); | 
| CFG(szIdent), STRSIZ, DWDS_NAME); |  | 
 | /* delete state file ... */ | /* delete state file ... */ | 
| v = cfg_GetAttribute(&cfg, CFG("dwds"), CFG("state_dir")); | v = cfg_getAttribute(&cfg, "dwds", "state_dir"); | 
| if (v && strtol((char*) v, NULL, 0)) { | if (v) { | 
 | memset(szCmd, 0, STRSIZ); | memset(szCmd, 0, STRSIZ); | 
| snprintf(szCmd, MAXPATHLEN, "%s/%s-%s-%s", (char*) v, | snprintf(szCmd, MAXPATHLEN, "%s/%s-%s-%s", v, szName, | 
| szName, ether_ntoa(&bssid), szIdent); | ether_ntoa(&bssid), AIT_GET_STR(&Ident)); | 
 | unlink(szCmd); | unlink(szCmd); | 
 | VERB(2) syslog(LOG_DEBUG, "Debug:: delete session name %s\n", szCmd); | VERB(2) syslog(LOG_DEBUG, "Debug:: delete session name %s\n", szCmd); | 
 | } | } | 
 |  |  | 
 | /* Launch script ... */ | /* Launch script ... */ | 
| cfg_LoadAttribute(&cfg, CFG("dwds"), CFG("disassoc_event"), | cfg_loadAttribute(&cfg, "dwds", "disassoc_event", &Str, NULL); | 
| CFG(szStr), STRSIZ, NULL); | if (!AIT_ISEMPTY(&Str)) { | 
| if (*szStr) { |  | 
| cfg_LoadAttribute(&cfg, CFG("dwds"), CFG("name"), |  | 
| CFG(szIdent), STRSIZ, DWDS_NAME); |  | 
 | memset(szCmd, 0, MAXPATHLEN); | memset(szCmd, 0, MAXPATHLEN); | 
| snprintf(szCmd, MAXPATHLEN, "%s %s %s %s", szStr, | snprintf(szCmd, MAXPATHLEN, "%s %s %s %s", AIT_GET_STR(&Str), | 
| szName, ether_ntoa(&bssid), szIdent); | szName, ether_ntoa(&bssid), AIT_GET_STR(&Ident)); | 
 | VERB(3) syslog(LOG_DEBUG, "Debug:: Command line: %s\n", szCmd); | VERB(3) syslog(LOG_DEBUG, "Debug:: Command line: %s\n", szCmd); | 
 |  |  | 
 | if ((stat = system(szCmd))) | if ((stat = system(szCmd))) | 
 | syslog(LOG_ERR, "VAP down script %s exited " | syslog(LOG_ERR, "VAP down script %s exited " | 
| "with status %d\n", szStr, stat); | "with status %d\n", | 
|  | AIT_GET_STR(&Str), stat); | 
|  | AIT_FREE_VAL(&Str); | 
 | } | } | 
 |  | AIT_FREE_VAL(&Ident); | 
 | } | } | 
 | break; | break; | 
 |  |  | 
| Line 134  RtMsg(struct dwds_if **wds, struct rt_msghdr *msg, siz | Line 179  RtMsg(struct dwds_if **wds, struct rt_msghdr *msg, siz | 
 | case RTM_IEEE80211_REJOIN: | case RTM_IEEE80211_REJOIN: | 
 | case RTM_IEEE80211_ASSOC: | case RTM_IEEE80211_ASSOC: | 
 | case RTM_IEEE80211_REASSOC: | case RTM_IEEE80211_REASSOC: | 
| v = cfg_GetAttribute(&cfg, CFG("dwds"), CFG("discover_on_join")); | v = cfg_getAttribute(&cfg, "dwds", "discover_on_join"); | 
| if (!v || !strtol((char*) v, NULL, 0)) | if (!v || !strtol(v, NULL, 0)) | 
 | break; | break; | 
 | /* fall thru ... */ | /* fall thru ... */ | 
 | case RTM_IEEE80211_WDS: | case RTM_IEEE80211_WDS: | 
| Line 144  RtMsg(struct dwds_if **wds, struct rt_msghdr *msg, siz | Line 189  RtMsg(struct dwds_if **wds, struct rt_msghdr *msg, siz | 
 | if (!wifi_chkIface(ifan->ifan_name, ifs, nif)) | if (!wifi_chkIface(ifan->ifan_name, ifs, nif)) | 
 | break; | break; | 
 | if (!wifi_createWDS(ifan->ifan_name, bssid, wds)) { | if (!wifi_createWDS(ifan->ifan_name, bssid, wds)) { | 
| cfg_LoadAttribute(&cfg, CFG("dwds"), CFG("name"), | cfg_loadAttribute(&cfg, "dwds", "name", &Ident, DWDS_NAME); | 
| CFG(szIdent), STRSIZ, DWDS_NAME); |  | 
 | /* create state file ... */ | /* create state file ... */ | 
| v = cfg_GetAttribute(&cfg, CFG("dwds"), CFG("state_dir")); | v = cfg_getAttribute(&cfg, "dwds", "state_dir"); | 
| if (v && strtol((char*) v, NULL, 0)) { | if (v) { | 
 | memset(szCmd, 0, MAXPATHLEN); | memset(szCmd, 0, MAXPATHLEN); | 
 | snprintf(szCmd, MAXPATHLEN, "%s/%s-%s-%s", (char*) v, | snprintf(szCmd, MAXPATHLEN, "%s/%s-%s-%s", (char*) v, | 
| (*wds)->if_name, ether_ntoa(&bssid), szIdent); | (*wds)->if_name, ether_ntoa(&bssid), | 
|  | AIT_GET_STR(&Ident)); | 
 | f = open(szCmd, O_WRONLY | O_CREAT, 0644); | f = open(szCmd, O_WRONLY | O_CREAT, 0644); | 
 | if (f != -1) | if (f != -1) | 
 | close(f); | close(f); | 
| Line 159  RtMsg(struct dwds_if **wds, struct rt_msghdr *msg, siz | Line 204  RtMsg(struct dwds_if **wds, struct rt_msghdr *msg, siz | 
 | } | } | 
 |  |  | 
 | /* Launch script ... */ | /* Launch script ... */ | 
| cfg_LoadAttribute(&cfg, CFG("dwds"), CFG("assoc_event"), | cfg_loadAttribute(&cfg, "dwds", "assoc_event", &Str, NULL); | 
| CFG(szStr), STRSIZ, NULL); | if (!AIT_ISEMPTY(&Str)) { | 
| if (*szStr) { |  | 
 | memset(szCmd, 0, MAXPATHLEN); | memset(szCmd, 0, MAXPATHLEN); | 
| snprintf(szCmd, MAXPATHLEN, "%s %s %s %s", szStr, | snprintf(szCmd, MAXPATHLEN, "%s %s %s %s", AIT_GET_STR(&Str), | 
| (*wds)->if_name, ether_ntoa(&bssid), szIdent); | (*wds)->if_name, ether_ntoa(&bssid), | 
|  | AIT_GET_STR(&Ident)); | 
 | VERB(3) syslog(LOG_DEBUG, "Debug:: Command line: %s\n", szCmd); | VERB(3) syslog(LOG_DEBUG, "Debug:: Command line: %s\n", szCmd); | 
 |  |  | 
 | if ((stat = system(szCmd))) | if ((stat = system(szCmd))) | 
 | syslog(LOG_ERR, "VAP up script %s exited " | syslog(LOG_ERR, "VAP up script %s exited " | 
| "with status %d\n", szStr, stat); | "with status %d\n", | 
|  | AIT_GET_STR(&Str), stat); | 
|  | AIT_FREE_VAL(&Str); | 
 | } | } | 
 |  | AIT_FREE_VAL(&Ident); | 
 | } | } | 
 | break; | break; | 
 | } | } | 
| Line 181  RtMsg(struct dwds_if **wds, struct rt_msghdr *msg, siz | Line 229  RtMsg(struct dwds_if **wds, struct rt_msghdr *msg, siz | 
 | return 0; | return 0; | 
 | } | } | 
 |  |  | 
 | // --------------------------------------------------------------- |  | 
 |  |  | 
 | int | int | 
 | main(int argc, char **argv) | main(int argc, char **argv) | 
 | { | { | 
| char ch, szStr[STRSIZ], fg = 0; | char ch, fg = 0; | 
| const u_char *v, msg[2048]; | ait_val_t Ident; | 
|  | const char *v, msg[2048]; | 
 | int s; | int s; | 
 | struct sigaction sa; | struct sigaction sa; | 
 | size_t len; | size_t len; | 
| Line 219  main(int argc, char **argv) | Line 267  main(int argc, char **argv) | 
 | nif = argc; | nif = argc; | 
 | ifs = argv; | ifs = argv; | 
 | } | } | 
| if (LoadConfig(szConfig, &cfg)) { | if (cfgLoadConfig(szConfig, &cfg)) { | 
 | printf("Error:: can`t load config %s ...\n", szConfig); | printf("Error:: can`t load config %s ...\n", szConfig); | 
 | return 1; | return 1; | 
 | } | } | 
| Line 228  main(int argc, char **argv) | Line 276  main(int argc, char **argv) | 
 | switch (fork()) { | switch (fork()) { | 
 | case -1: | case -1: | 
 | printf("Error:: when fork() #%d - %s\n", errno, strerror(errno)); | printf("Error:: when fork() #%d - %s\n", errno, strerror(errno)); | 
| UnloadConfig(&cfg); | cfgUnloadConfig(&cfg); | 
 | return 2; | return 2; | 
 | case 0 : | case 0 : | 
 | VERB(1) printf("Going to shadow land ...\n"); | VERB(1) printf("Going to shadow land ...\n"); | 
| Line 246  main(int argc, char **argv) | Line 294  main(int argc, char **argv) | 
 | goto end; | goto end; | 
 | } | } | 
 |  |  | 
| cfg_LoadAttribute(&cfg, CFG("dwds"), CFG("name"), CFG(szStr), STRSIZ, DWDS_NAME); | cfg_loadAttribute(&cfg, "dwds", "name", &Ident, DWDS_NAME); | 
| openlog(szStr, LOG_PID | LOG_CONS, LOG_DAEMON); | openlog(AIT_GET_STR(&Ident), LOG_PID | LOG_CONS, LOG_DAEMON); | 
| v = cfg_GetAttribute(&cfg, CFG("dwds"), CFG("syslog_upto")); | AIT_FREE_VAL(&Ident); | 
| setlogmask(v ? strtol((char*) v, NULL, 0) : 0); | v = cfg_getAttribute(&cfg, "dwds", "syslog_upto"); | 
|  | setlogmask(v ? strtol(v, NULL, 0) : 0); | 
 |  |  | 
 | s = socket(PF_ROUTE, SOCK_RAW, 0); | s = socket(PF_ROUTE, SOCK_RAW, 0); | 
 | if (s == -1) { | if (s == -1) { | 
| Line 274  main(int argc, char **argv) | Line 323  main(int argc, char **argv) | 
 | close(s); | close(s); | 
 | end: | end: | 
 | closelog(); | closelog(); | 
| UnloadConfig(&cfg); | cfgUnloadConfig(&cfg); | 
 | return 0; | return 0; | 
 | } | } |