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>