Annotation of embedtools/src/dwds.c, revision 1.1.2.9
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.3 misho 16: " Syntax: dwds [options] <interface|any> [interface [...]]\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.9 ! misho 61: char szStr[STRSIZ] = { 0 }, szCmd[MAXPATHLEN] = { 0 };
! 62: int stat;
1.1.2.8 misho 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:
1.1.2.9 ! misho 97: if (wifi_chkIface(ifan->ifan_name, ifs, nif) < 0)
! 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: /* Launch script ... */
! 103: cfg_LoadAttribute(&cfg, CFG("dwds"), CFG("disassoc_event"),
! 104: CFG(szStr), STRSIZ, NULL);
! 105: if (*szStr) {
! 106: snprintf(szCmd, MAXPATHLEN, "%s %s %s", szStr,
! 107: ifan->ifan_name, ether_ntoa(&bssid));
! 108: VERB(3) syslog(LOG_DEBUG, "Debug:: Command line: %s\n", szCmd);
! 109:
! 110: if ((stat = system(szCmd)))
! 111: syslog(LOG_ERR, "VAP down script %s exited "
! 112: "with status %d\n", szStr, stat);
! 113: }
! 114: }
1.1.2.8 misho 115: break;
116:
117: case RTM_IEEE80211_JOIN:
118: case RTM_IEEE80211_REJOIN:
119: case RTM_IEEE80211_ASSOC:
120: case RTM_IEEE80211_REASSOC:
121: v = cfg_GetAttribute(&cfg, CFG("dwds"), CFG("discover_on_join"));
122: if (!v || !strtol((char*) v, NULL, 0))
123: break;
124: /* fall thru ... */
125: case RTM_IEEE80211_WDS:
1.1.2.9 ! misho 126: memcpy(&bssid, V(ieee80211_leave_event)->iev_addr, ETHER_ADDR_LEN);
! 127: VERB(1) syslog(LOG_INFO, "BSSID:%s WDS discovery\n", ether_ntoa(&bssid));
! 128: if (wifi_chkIface(ifan->ifan_name, ifs, nif) < 0)
! 129: break;
! 130: if (!wifi_createWDS(ifan->ifan_name, bssid, wds)) {
! 131: /* Launch script ... */
! 132: cfg_LoadAttribute(&cfg, CFG("dwds"), CFG("assoc_event"),
! 133: CFG(szStr), STRSIZ, NULL);
! 134: if (*szStr) {
! 135: snprintf(szCmd, MAXPATHLEN, "%s %s %s", szStr,
! 136: ifan->ifan_name, ether_ntoa(&bssid));
! 137: VERB(3) syslog(LOG_DEBUG, "Debug:: Command line: %s\n", szCmd);
! 138:
! 139: if ((stat = system(szCmd)))
! 140: syslog(LOG_ERR, "VAP up script %s exited "
! 141: "with status %d\n", szStr, stat);
! 142: }
! 143: }
1.1.2.8 misho 144: break;
145: }
146: #undef V
147: break;
148: }
149:
1.1.2.4 misho 150: return 0;
151: }
152:
1.1.2.2 misho 153: // ---------------------------------------------------------------
154:
1.1.2.1 misho 155: int
156: main(int argc, char **argv)
157: {
1.1.2.4 misho 158: char ch, szStr[STRSIZ], fg = 0;
159: const u_char *v, msg[2048];
160: int s;
161: struct sigaction sa;
162: size_t len;
1.1.2.6 misho 163: struct dwds_if *wds = NULL;
1.1.2.2 misho 164:
1.1.2.3 misho 165: while ((ch = getopt(argc, argv, "hvfc:")) != -1)
166: switch (ch) {
167: case 'v':
168: Verbose++;
169: break;
170: case 'f':
171: fg = 1;
172: break;
173: case 'c':
174: strlcpy(szConfig, optarg, MAXPATHLEN);
175: break;
176: case 'h':
177: default:
178: Usage();
179: return 1;
180: }
181: argc -= optind;
182: argv += optind;
183: if (!argc) {
184: printf("Error:: not specified interface for use ...\n");
185: Usage();
186: return 1;
1.1.2.4 misho 187: } else {
188: nif = argc;
189: ifs = argv;
190: }
191: if (LoadConfig(szConfig, &cfg)) {
192: printf("Error:: can`t load config %s ...\n", szConfig);
193: return 1;
194: }
195:
1.1.2.7 misho 196: if (!fg)
1.1.2.4 misho 197: switch (fork()) {
198: case -1:
199: printf("Error:: when fork() #%d - %s\n", errno, strerror(errno));
200: UnloadConfig(&cfg);
201: return 2;
202: case 0 :
203: VERB(1) printf("Going to shadow land ...\n");
204:
205: setsid();
206:
207: memset(&sa, 0, sizeof sa);
208: sa.sa_handler = sigHandler;
209: sigemptyset(&sa.sa_mask);
210: sigaction(SIGHUP, &sa, NULL);
211: sigaction(SIGTERM, &sa, NULL);
212: sigaction(SIGCHLD, &sa, NULL);
213: break;
214: default:
215: goto end;
216: }
217:
218: cfg_LoadAttribute(&cfg, CFG("dwds"), CFG("name"), CFG(szStr), STRSIZ, DWDS_NAME);
219: openlog(szStr, LOG_PID | LOG_CONS, LOG_DAEMON);
220: v = cfg_GetAttribute(&cfg, CFG("dwds"), CFG("syslog_upto"));
221: setlogmask(v ? strtol((char*) v, NULL, 0) : 0);
222:
223: s = socket(PF_ROUTE, SOCK_RAW, 0);
224: if (s == -1) {
225: syslog(LOG_ERR, "Error:: socket() #%d - %s\n", errno, strerror(errno));
226: goto end;
227: }
228:
1.1.2.7 misho 229: if (!(wds = wifi_buildWDS(s, ifs, nif))) {
230: syslog(LOG_ERR, "Error:: Go to dead ...\n");
1.1.2.6 misho 231: goto end;
1.1.2.7 misho 232: }
1.1.2.6 misho 233:
1.1.2.4 misho 234: while (!Kill) {
235: len = read(s, (void*) msg, sizeof msg);
236: if (len == -1) {
237: syslog(LOG_ERR, "Error:: read() #%d - %s\n", errno, strerror(errno));
238: Kill++;
239: } else
1.1.2.8 misho 240: RtMsg(&wds, (struct rt_msghdr*) msg, len);
1.1.2.3 misho 241: }
242:
1.1.2.4 misho 243: close(s);
244: end:
245: closelog();
246: UnloadConfig(&cfg);
1.1.2.1 misho 247: return 0;
248: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>