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

1.2     ! misho       1: #include "global.h"
        !             2: #include "dwds.h"
        !             3: 
        !             4: 
        !             5: sl_config cfg;
        !             6: int Verbose, Kill, nif;
        !             7: char **ifs, szConfig[MAXPATHLEN] = DWDS_CONFIG;
        !             8: extern char compiled[], compiledby[], compilehost[];
        !             9: 
        !            10: 
        !            11: static void
        !            12: Usage()
        !            13: {
        !            14:        printf( "-= dWDS =- WiFi dynamic WDS service managment for VAP\n"
        !            15:                "=== %s === %s@%s ===\n\n"
        !            16:                "  Syntax: dwds [options] <interface|any> [interface [ath0, ...]]\n"
        !            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: 
        !            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
        !            56: RtMsg(struct dwds_if **wds, struct rt_msghdr *msg, size_t len)
        !            57: {
        !            58:        struct if_announcemsghdr *ifan;
        !            59:        const u_char *v;
        !            60:        struct ether_addr bssid;
        !            61:        char szStr[STRSIZ] = { 0 }, szCmd[MAXPATHLEN] = { 0 }, szIdent[STRSIZ] = { 0 }, 
        !            62:             szName[IFNAMSIZ] = { 0 };
        !            63:        int f, stat;
        !            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:
        !            98:                                        if (!wifi_chkIface(ifan->ifan_name, ifs, nif))
        !            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));
        !           102:                                        if (!wifi_leaveWDS(bssid, wds, szName, IFNAMSIZ)) {
        !           103:                                                cfg_LoadAttribute(&cfg, CFG("dwds"), CFG("name"), 
        !           104:                                                                CFG(szIdent), STRSIZ, DWDS_NAME);
        !           105:                                                /* delete state file ... */
        !           106:                                                v = cfg_GetAttribute(&cfg, CFG("dwds"), CFG("state_dir"));
        !           107:                                                if (v) {
        !           108:                                                        memset(szCmd, 0, STRSIZ);
        !           109:                                                        snprintf(szCmd, MAXPATHLEN, "%s/%s-%s-%s", (char*) v, 
        !           110:                                                                        szName, ether_ntoa(&bssid), szIdent);
        !           111:                                                        unlink(szCmd);
        !           112:                                                        VERB(2) syslog(LOG_DEBUG, "Debug:: delete session name %s\n", szCmd);
        !           113:                                                }
        !           114: 
        !           115:                                                /* Launch script ... */
        !           116:                                                cfg_LoadAttribute(&cfg, CFG("dwds"), CFG("disassoc_event"), 
        !           117:                                                                CFG(szStr), STRSIZ, NULL);
        !           118:                                                if (*szStr) {
        !           119:                                                        cfg_LoadAttribute(&cfg, CFG("dwds"), CFG("name"), 
        !           120:                                                                        CFG(szIdent), STRSIZ, DWDS_NAME);
        !           121:                                                        memset(szCmd, 0, MAXPATHLEN);
        !           122:                                                        snprintf(szCmd, MAXPATHLEN, "%s %s %s %s", szStr, 
        !           123:                                                                        szName, ether_ntoa(&bssid), szIdent);
        !           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:                                        }
        !           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:
        !           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));
        !           144:                                        if (!wifi_chkIface(ifan->ifan_name, ifs, nif))
        !           145:                                                break;
        !           146:                                        if (!wifi_createWDS(ifan->ifan_name, bssid, wds)) {
        !           147:                                                cfg_LoadAttribute(&cfg, CFG("dwds"), CFG("name"), 
        !           148:                                                                CFG(szIdent), STRSIZ, DWDS_NAME);
        !           149:                                                /* create state file ... */
        !           150:                                                v = cfg_GetAttribute(&cfg, CFG("dwds"), CFG("state_dir"));
        !           151:                                                if (v) {
        !           152:                                                        memset(szCmd, 0, MAXPATHLEN);
        !           153:                                                        snprintf(szCmd, MAXPATHLEN, "%s/%s-%s-%s", (char*) v, 
        !           154:                                                                        (*wds)->if_name, ether_ntoa(&bssid), szIdent);
        !           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: 
        !           161:                                                /* Launch script ... */
        !           162:                                                cfg_LoadAttribute(&cfg, CFG("dwds"), CFG("assoc_event"), 
        !           163:                                                                CFG(szStr), STRSIZ, NULL);
        !           164:                                                if (*szStr) {
        !           165:                                                        memset(szCmd, 0, MAXPATHLEN);
        !           166:                                                        snprintf(szCmd, MAXPATHLEN, "%s %s %s %s", szStr, 
        !           167:                                                                        (*wds)->if_name, ether_ntoa(&bssid), szIdent);
        !           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:                                        }
        !           175:                                        break;
        !           176:                        }
        !           177: #undef V
        !           178:                        break;
        !           179:        }
        !           180: 
        !           181:        return 0;
        !           182: }
        !           183: 
        !           184: // ---------------------------------------------------------------
        !           185: 
        !           186: int
        !           187: main(int argc, char **argv)
        !           188: {
        !           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;
        !           194:        struct dwds_if *wds = NULL;
        !           195: 
        !           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;
        !           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: 
        !           227:        if (!fg)
        !           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: 
        !           260:        if (!(wds = wifi_buildWDS(s, ifs, nif))) {
        !           261:                syslog(LOG_ERR, "Error:: Go to dead ...\n");
        !           262:                goto end;
        !           263:        }
        !           264: 
        !           265:        while (!Kill) {
        !           266:                len = read(s, (void*) msg, sizeof msg);
        !           267:                if (len == -1) {
        !           268:                        VERB(5) syslog(LOG_ERR, "Error:: read() #%d - %s\n", errno, strerror(errno));
        !           269:                        Kill++;
        !           270:                } else
        !           271:                        RtMsg(&wds, (struct rt_msghdr*) msg, len);
        !           272:        }
        !           273: 
        !           274:        close(s);
        !           275: end:
        !           276:        closelog();
        !           277:        UnloadConfig(&cfg);
        !           278:        return 0;
        !           279: }

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