File:  [ELWIX - Embedded LightWeight unIX -] / embedtools / src / dwds.c
Revision 1.1.2.11: download - view: text, annotated - select for diffs - revision graph
Tue Nov 2 01:54:58 2010 UTC (13 years, 8 months ago) by misho
Branches: tools1_0
added new scripts and many other things and corrects

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

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