Annotation of embedtools/src/dwds.c, revision 1.1.2.13

1.1.2.1   misho       1: #include "global.h"
                      2: #include "dwds.h"
                      3: 
                      4: 
1.1.2.4   misho       5: sl_config cfg;
                      6: int Verbose, Kill, nif;
                      7: char **ifs, szConfig[MAXPATHLEN] = DWDS_CONFIG;
1.1.2.2   misho       8: extern char compiled[], compiledby[], compilehost[];
                      9: 
                     10: 
                     11: static void
                     12: Usage()
                     13: {
1.1.2.3   misho      14:        printf( "-= dWDS =- WiFi dynamic WDS service managment for VAP\n"
1.1.2.2   misho      15:                "=== %s === %s@%s ===\n\n"
1.1.2.11  misho      16:                "  Syntax: dwds [options] <interface|any> [interface [ath0, ...]]\n"
1.1.2.2   misho      17:                "\n"
                     18:                "\t-v\t\tVerbose ...\n"
                     19:                "\t-f\t\tForeground, not demonize process ...\n"
                     20:                "\t-c <config>\tConfig file [default=/etc/dwds.conf]\n"
                     21:                "\n", compiled, compiledby, compilehost);
                     22: }
                     23: 
1.1.2.4   misho      24: static void
                     25: sigHandler(int sig)
                     26: {
                     27:        int stat;
                     28:        const u_char *v;
                     29:        char szStr[STRSIZ];
                     30: 
                     31:        switch (sig) {
                     32:                case SIGHUP:
                     33:                        UnloadConfig(&cfg);
                     34:                        if (LoadConfig(szConfig, &cfg)) {
                     35:                                printf("Error:: can`t load config %s ...\n", szConfig);
                     36:                                Kill++;
                     37:                        } else {
                     38:                                closelog();
                     39: 
                     40:                                cfg_LoadAttribute(&cfg, CFG("dwds"), CFG("name"), CFG(szStr), STRSIZ, DWDS_NAME);
                     41:                                openlog(szStr, LOG_PID | LOG_CONS, LOG_DAEMON);
                     42:                                v = cfg_GetAttribute(&cfg, CFG("dwds"), CFG("syslog_upto"));
                     43:                                setlogmask(v ? strtol((char*) v, NULL, 0) : 0);
                     44:                        }
                     45:                        break;
                     46:                case SIGTERM:
                     47:                        Kill++;
                     48:                        break;
                     49:                case SIGCHLD:
                     50:                        while (waitpid(-1, &stat, WNOHANG) > 0);
                     51:                        break;
                     52:        }
                     53: }
                     54: 
                     55: static int
1.1.2.8   misho      56: RtMsg(struct dwds_if **wds, struct rt_msghdr *msg, size_t len)
1.1.2.4   misho      57: {
1.1.2.8   misho      58:        struct if_announcemsghdr *ifan;
                     59:        const u_char *v;
                     60:        struct ether_addr bssid;
1.1.2.12  misho      61:        char szStr[STRSIZ] = { 0 }, szCmd[MAXPATHLEN] = { 0 }, szIdent[STRSIZ] = { 0 }, 
                     62:             szName[IFNAMSIZ] = { 0 };
1.1.2.10  misho      63:        int f, stat;
1.1.2.8   misho      64: 
                     65:        assert(wds);
                     66:        assert(msg);
                     67: 
                     68:        if (msg->rtm_version != RTM_VERSION) {
                     69:                syslog(LOG_ERR, "Error:: routing message version %d not understood!\n", msg->rtm_version);
                     70:                return -1;
                     71:        }
                     72: 
                     73:        switch (msg->rtm_type) {
                     74:                case RTM_IFANNOUNCE:
                     75:                        ifan = (struct if_announcemsghdr*) msg;
                     76:                        switch (ifan->ifan_what) {
                     77:                                case IFAN_ARRIVAL:
                     78:                                        VERB(1) syslog(LOG_INFO, "RTM_IFANNOUNCE: if# %d, what: arrival\n", 
                     79:                                                        ifan->ifan_index);
                     80:                                        break;
                     81:                                case IFAN_DEPARTURE:
                     82:                                        VERB(1) syslog(LOG_INFO, "RTM_IFANNOUNCE: if# %d, what: departure\n", 
                     83:                                                        ifan->ifan_index);
                     84:                                        wifi_destroyWDS(ifan->ifan_name, wds);
                     85:                                        break;
                     86:                        }
                     87:                        break;
                     88:                case RTM_IEEE80211:
                     89: #define        V(type) ((struct type *)(&ifan[1]))
                     90:                        ifan = (struct if_announcemsghdr*) msg;
                     91:                        switch (ifan->ifan_what) {
                     92:                                case RTM_IEEE80211_DISASSOC:
                     93:                                        v = cfg_GetAttribute(&cfg, CFG("dwds"), CFG("discover_on_join"));
                     94:                                        if (!v || !strtol((char*) v, NULL, 0))
                     95:                                                break;
                     96:                                        /* fall thru ... */
                     97:                                case RTM_IEEE80211_LEAVE:
1.1.2.11  misho      98:                                        if (!wifi_chkIface(ifan->ifan_name, ifs, nif))
1.1.2.9   misho      99:                                                break;
                    100:                                        memcpy(&bssid, V(ieee80211_leave_event)->iev_addr, ETHER_ADDR_LEN);
                    101:                                        VERB(1) syslog(LOG_INFO, "BSSID:%s Station leave\n", ether_ntoa(&bssid));
1.1.2.12  misho     102:                                        if (!wifi_leaveWDS(bssid, wds, szName, IFNAMSIZ)) {
1.1.2.11  misho     103:                                                cfg_LoadAttribute(&cfg, CFG("dwds"), CFG("name"), 
                    104:                                                                CFG(szIdent), STRSIZ, DWDS_NAME);
1.1.2.10  misho     105:                                                /* delete state file ... */
                    106:                                                v = cfg_GetAttribute(&cfg, CFG("dwds"), CFG("state_dir"));
1.1.2.13! misho     107:                                                if (v) {
1.1.2.10  misho     108:                                                        memset(szCmd, 0, STRSIZ);
1.1.2.11  misho     109:                                                        snprintf(szCmd, MAXPATHLEN, "%s/%s-%s-%s", (char*) v, 
1.1.2.12  misho     110:                                                                        szName, ether_ntoa(&bssid), szIdent);
1.1.2.10  misho     111:                                                        unlink(szCmd);
                    112:                                                        VERB(2) syslog(LOG_DEBUG, "Debug:: delete session name %s\n", szCmd);
                    113:                                                }
                    114: 
1.1.2.9   misho     115:                                                /* Launch script ... */
                    116:                                                cfg_LoadAttribute(&cfg, CFG("dwds"), CFG("disassoc_event"), 
                    117:                                                                CFG(szStr), STRSIZ, NULL);
                    118:                                                if (*szStr) {
1.1.2.11  misho     119:                                                        cfg_LoadAttribute(&cfg, CFG("dwds"), CFG("name"), 
                    120:                                                                        CFG(szIdent), STRSIZ, DWDS_NAME);
1.1.2.10  misho     121:                                                        memset(szCmd, 0, MAXPATHLEN);
1.1.2.11  misho     122:                                                        snprintf(szCmd, MAXPATHLEN, "%s %s %s %s", szStr, 
1.1.2.12  misho     123:                                                                        szName, ether_ntoa(&bssid), szIdent);
1.1.2.9   misho     124:                                                        VERB(3) syslog(LOG_DEBUG, "Debug:: Command line: %s\n", szCmd);
                    125: 
                    126:                                                        if ((stat = system(szCmd)))
                    127:                                                                syslog(LOG_ERR, "VAP down script %s exited "
                    128:                                                                                "with status %d\n", szStr, stat);
                    129:                                                }
                    130:                                        }
1.1.2.8   misho     131:                                        break;
                    132: 
                    133:                                case RTM_IEEE80211_JOIN:
                    134:                                case RTM_IEEE80211_REJOIN:
                    135:                                case RTM_IEEE80211_ASSOC:
                    136:                                case RTM_IEEE80211_REASSOC:
                    137:                                        v = cfg_GetAttribute(&cfg, CFG("dwds"), CFG("discover_on_join"));
                    138:                                        if (!v || !strtol((char*) v, NULL, 0))
                    139:                                                break;
                    140:                                        /* fall thru ... */
                    141:                                case RTM_IEEE80211_WDS:
1.1.2.9   misho     142:                                        memcpy(&bssid, V(ieee80211_leave_event)->iev_addr, ETHER_ADDR_LEN);
                    143:                                        VERB(1) syslog(LOG_INFO, "BSSID:%s WDS discovery\n", ether_ntoa(&bssid));
1.1.2.11  misho     144:                                        if (!wifi_chkIface(ifan->ifan_name, ifs, nif))
1.1.2.9   misho     145:                                                break;
                    146:                                        if (!wifi_createWDS(ifan->ifan_name, bssid, wds)) {
1.1.2.11  misho     147:                                                cfg_LoadAttribute(&cfg, CFG("dwds"), CFG("name"), 
                    148:                                                                CFG(szIdent), STRSIZ, DWDS_NAME);
1.1.2.10  misho     149:                                                /* create state file ... */
                    150:                                                v = cfg_GetAttribute(&cfg, CFG("dwds"), CFG("state_dir"));
1.1.2.13! misho     151:                                                if (v) {
1.1.2.10  misho     152:                                                        memset(szCmd, 0, MAXPATHLEN);
1.1.2.11  misho     153:                                                        snprintf(szCmd, MAXPATHLEN, "%s/%s-%s-%s", (char*) v, 
                    154:                                                                        (*wds)->if_name, ether_ntoa(&bssid), szIdent);
1.1.2.10  misho     155:                                                        f = open(szCmd, O_WRONLY | O_CREAT, 0644);
                    156:                                                        if (f != -1)
                    157:                                                                close(f);
                    158:                                                        VERB(2) syslog(LOG_DEBUG, "Debug:: create session name %s\n", szCmd);
                    159:                                                }
                    160: 
1.1.2.9   misho     161:                                                /* Launch script ... */
                    162:                                                cfg_LoadAttribute(&cfg, CFG("dwds"), CFG("assoc_event"), 
                    163:                                                                CFG(szStr), STRSIZ, NULL);
                    164:                                                if (*szStr) {
1.1.2.10  misho     165:                                                        memset(szCmd, 0, MAXPATHLEN);
1.1.2.11  misho     166:                                                        snprintf(szCmd, MAXPATHLEN, "%s %s %s %s", szStr, 
                    167:                                                                        (*wds)->if_name, ether_ntoa(&bssid), szIdent);
1.1.2.9   misho     168:                                                        VERB(3) syslog(LOG_DEBUG, "Debug:: Command line: %s\n", szCmd);
                    169: 
                    170:                                                        if ((stat = system(szCmd)))
                    171:                                                                syslog(LOG_ERR, "VAP up script %s exited "
                    172:                                                                                "with status %d\n", szStr, stat);
                    173:                                                }
                    174:                                        }
1.1.2.8   misho     175:                                        break;
                    176:                        }
                    177: #undef V
                    178:                        break;
                    179:        }
                    180: 
1.1.2.4   misho     181:        return 0;
                    182: }
                    183: 
1.1.2.2   misho     184: // ---------------------------------------------------------------
                    185: 
1.1.2.1   misho     186: int
                    187: main(int argc, char **argv)
                    188: {
1.1.2.4   misho     189:        char ch, szStr[STRSIZ], fg = 0;
                    190:        const u_char *v, msg[2048];
                    191:        int s;
                    192:        struct sigaction sa;
                    193:        size_t len;
1.1.2.6   misho     194:        struct dwds_if *wds = NULL;
1.1.2.2   misho     195: 
1.1.2.3   misho     196:        while ((ch = getopt(argc, argv, "hvfc:")) != -1)
                    197:                switch (ch) {
                    198:                        case 'v':
                    199:                                Verbose++;
                    200:                                break;
                    201:                        case 'f':
                    202:                                fg = 1;
                    203:                                break;
                    204:                        case 'c':
                    205:                                strlcpy(szConfig, optarg, MAXPATHLEN);
                    206:                                break;
                    207:                        case 'h':
                    208:                        default:
                    209:                                Usage();
                    210:                                return 1;
                    211:                }
                    212:        argc -= optind;
                    213:        argv += optind;
                    214:        if (!argc) {
                    215:                printf("Error:: not specified interface for use ...\n");
                    216:                Usage();
                    217:                return 1;
1.1.2.4   misho     218:        } else {
                    219:                nif = argc;
                    220:                ifs = argv;
                    221:        }
                    222:        if (LoadConfig(szConfig, &cfg)) {
                    223:                printf("Error:: can`t load config %s ...\n", szConfig);
                    224:                return 1;
                    225:        }
                    226: 
1.1.2.7   misho     227:        if (!fg)
1.1.2.4   misho     228:                switch (fork()) {
                    229:                        case -1:
                    230:                                printf("Error:: when fork() #%d - %s\n", errno, strerror(errno));
                    231:                                UnloadConfig(&cfg);
                    232:                                return 2;
                    233:                        case 0 :
                    234:                                VERB(1) printf("Going to shadow land ...\n");
                    235: 
                    236:                                setsid();
                    237: 
                    238:                                memset(&sa, 0, sizeof sa);
                    239:                                sa.sa_handler = sigHandler;
                    240:                                sigemptyset(&sa.sa_mask);
                    241:                                sigaction(SIGHUP, &sa, NULL);
                    242:                                sigaction(SIGTERM, &sa, NULL);
                    243:                                sigaction(SIGCHLD, &sa, NULL);
                    244:                                break;
                    245:                        default:
                    246:                                goto end;
                    247:                }
                    248: 
                    249:        cfg_LoadAttribute(&cfg, CFG("dwds"), CFG("name"), CFG(szStr), STRSIZ, DWDS_NAME);
                    250:        openlog(szStr, LOG_PID | LOG_CONS, LOG_DAEMON);
                    251:        v = cfg_GetAttribute(&cfg, CFG("dwds"), CFG("syslog_upto"));
                    252:        setlogmask(v ? strtol((char*) v, NULL, 0) : 0);
                    253: 
                    254:        s = socket(PF_ROUTE, SOCK_RAW, 0);
                    255:        if (s == -1) {
                    256:                syslog(LOG_ERR, "Error:: socket() #%d - %s\n", errno, strerror(errno));
                    257:                goto end;
                    258:        }
                    259: 
1.1.2.7   misho     260:        if (!(wds = wifi_buildWDS(s, ifs, nif))) {
                    261:                syslog(LOG_ERR, "Error:: Go to dead ...\n");
1.1.2.6   misho     262:                goto end;
1.1.2.7   misho     263:        }
1.1.2.6   misho     264: 
1.1.2.4   misho     265:        while (!Kill) {
                    266:                len = read(s, (void*) msg, sizeof msg);
                    267:                if (len == -1) {
1.1.2.11  misho     268:                        VERB(5) syslog(LOG_ERR, "Error:: read() #%d - %s\n", errno, strerror(errno));
1.1.2.4   misho     269:                        Kill++;
                    270:                } else
1.1.2.8   misho     271:                        RtMsg(&wds, (struct rt_msghdr*) msg, len);
1.1.2.3   misho     272:        }
                    273: 
1.1.2.4   misho     274:        close(s);
                    275: end:
                    276:        closelog();
                    277:        UnloadConfig(&cfg);
1.1.2.1   misho     278:        return 0;
                    279: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>