OpenWrt – Diff between revs 2 and 3

Subversion Repositories:
Rev:
Only display areas with differencesIgnore whitespace
Rev 2 Rev 3
1 /* 1 /*
2 * Emergency Access Daemon 2 * Emergency Access Daemon
3 * Copyright (C) 2008 Felix Fietkau <nbd@nbd.name> 3 * Copyright (C) 2008 Felix Fietkau <nbd@nbd.name>
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify 5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 6 * it under the terms of the GNU General Public License version 2
7 * as published by the Free Software Foundation 7 * as published by the Free Software Foundation
8 * 8 *
9 * This program is distributed in the hope that it will be useful, 9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 */ 13 */
14   14  
15 #include <sys/types.h> 15 #include <sys/types.h>
16 #include <sys/time.h> 16 #include <sys/time.h>
17 #include <sys/select.h> 17 #include <sys/select.h>
18 #include <stdio.h> 18 #include <stdio.h>
19 #include <stddef.h> 19 #include <stddef.h>
20 #include <stdlib.h> 20 #include <stdlib.h>
21 #include <string.h> 21 #include <string.h>
22 #include <unistd.h> 22 #include <unistd.h>
23 #include <stdbool.h> 23 #include <stdbool.h>
24 #include <fcntl.h> 24 #include <fcntl.h>
25 #include <signal.h> 25 #include <signal.h>
26 #include <pcap.h> 26 #include <pcap.h>
27 #include <pcap-bpf.h> 27 #include <pcap-bpf.h>
28 #include <t_pwd.h> 28 #include <t_pwd.h>
29 #include <t_read.h> 29 #include <t_read.h>
30 #include <t_sha.h> 30 #include <t_sha.h>
31 #include <t_defines.h> 31 #include <t_defines.h>
32 #include <t_server.h> 32 #include <t_server.h>
33 #include <net/if.h> 33 #include <net/if.h>
34   34  
35 #include "list.h" 35 #include "list.h"
36 #include "ead.h" 36 #include "ead.h"
37 #include "ead-pcap.h" 37 #include "ead-pcap.h"
38 #include "ead-crypt.h" 38 #include "ead-crypt.h"
39 #include "libbridge.h" 39 #include "libbridge.h"
40   40  
41 #include "filter.c" 41 #include "filter.c"
42   42  
43 #ifdef linux 43 #ifdef linux
44 #include <linux/if_packet.h> 44 #include <linux/if_packet.h>
45 #endif 45 #endif
46   46  
47 #define PASSWD_FILE "/etc/passwd" 47 #define PASSWD_FILE "/etc/passwd"
48   48  
49 #ifndef DEFAULT_IFNAME 49 #ifndef DEFAULT_IFNAME
50 #define DEFAULT_IFNAME "eth0" 50 #define DEFAULT_IFNAME "eth0"
51 #endif 51 #endif
52   52  
53 #ifndef DEFAULT_DEVNAME 53 #ifndef DEFAULT_DEVNAME
54 #define DEFAULT_DEVNAME "Unknown" 54 #define DEFAULT_DEVNAME "Unknown"
55 #endif 55 #endif
56   56  
57 #define PCAP_MRU 1600 57 #define PCAP_MRU 1600
58 #define PCAP_TIMEOUT 200 58 #define PCAP_TIMEOUT 200
59   59  
60 #if EAD_DEBUGLEVEL >= 1 60 #if EAD_DEBUGLEVEL >= 1
61 #define DEBUG(n, format, ...) do { \ 61 #define DEBUG(n, format, ...) do { \
62 if (EAD_DEBUGLEVEL >= n) \ 62 if (EAD_DEBUGLEVEL >= n) \
63 fprintf(stderr, format, ##__VA_ARGS__); \ 63 fprintf(stderr, format, ##__VA_ARGS__); \
64 } while (0); 64 } while (0);
65   65  
66 #else 66 #else
67 #define DEBUG(n, format, ...) do {} while(0) 67 #define DEBUG(n, format, ...) do {} while(0)
68 #endif 68 #endif
69   69  
70 struct ead_instance { 70 struct ead_instance {
71 struct list_head list; 71 struct list_head list;
72 char ifname[16]; 72 char ifname[16];
73 int pid; 73 int pid;
74 char id; 74 char id;
75 char bridge[16]; 75 char bridge[16];
76 bool br_check; 76 bool br_check;
77 }; 77 };
78   78  
79 static char ethmac[6] = "\x00\x13\x37\x00\x00\x00"; /* last 3 bytes will be randomized */ 79 static char ethmac[6] = "\x00\x13\x37\x00\x00\x00"; /* last 3 bytes will be randomized */
80 static pcap_t *pcap_fp = NULL; 80 static pcap_t *pcap_fp = NULL;
81 static pcap_t *pcap_fp_rx = NULL; 81 static pcap_t *pcap_fp_rx = NULL;
82 static char pktbuf_b[PCAP_MRU]; 82 static char pktbuf_b[PCAP_MRU];
83 static struct ead_packet *pktbuf = (struct ead_packet *)pktbuf_b; 83 static struct ead_packet *pktbuf = (struct ead_packet *)pktbuf_b;
84 static u16_t nid = 0xffff; /* node id */ 84 static u16_t nid = 0xffff; /* node id */
85 static char username[32] = ""; 85 static char username[32] = "";
86 static int state = EAD_TYPE_SET_USERNAME; 86 static int state = EAD_TYPE_SET_USERNAME;
87 static const char *passwd_file = PASSWD_FILE; 87 static const char *passwd_file = PASSWD_FILE;
88 static const char password[MAXPARAMLEN]; 88 static const char password[MAXPARAMLEN];
89 static bool child_pending = false; 89 static bool child_pending = false;
90   90  
91 static unsigned char abuf[MAXPARAMLEN + 1]; 91 static unsigned char abuf[MAXPARAMLEN + 1];
92 static unsigned char pwbuf[MAXPARAMLEN]; 92 static unsigned char pwbuf[MAXPARAMLEN];
93 static unsigned char saltbuf[MAXSALTLEN]; 93 static unsigned char saltbuf[MAXSALTLEN];
94 static unsigned char pw_saltbuf[MAXSALTLEN]; 94 static unsigned char pw_saltbuf[MAXSALTLEN];
95 static struct list_head instances; 95 static struct list_head instances;
96 static const char *dev_name = DEFAULT_DEVNAME; 96 static const char *dev_name = DEFAULT_DEVNAME;
97 static bool nonfork = false; 97 static bool nonfork = false;
98 static struct ead_instance *instance = NULL; 98 static struct ead_instance *instance = NULL;
99   99  
100 static struct t_pwent tpe = { 100 static struct t_pwent tpe = {
101 .name = username, 101 .name = username,
102 .index = 1, 102 .index = 1,
103 .password.data = pwbuf, 103 .password.data = pwbuf,
104 .password.len = 0, 104 .password.len = 0,
105 .salt.data = saltbuf, 105 .salt.data = saltbuf,
106 .salt.len = 0, 106 .salt.len = 0,
107 }; 107 };
108 struct t_confent *tce = NULL; 108 struct t_confent *tce = NULL;
109 static struct t_server *ts = NULL; 109 static struct t_server *ts = NULL;
110 static struct t_num A, *B = NULL; 110 static struct t_num A, *B = NULL;
111 unsigned char *skey; 111 unsigned char *skey;
112   112  
113 static void 113 static void
114 set_recv_type(pcap_t *p, bool rx) 114 set_recv_type(pcap_t *p, bool rx)
115 { 115 {
116 #ifdef PACKET_RECV_TYPE 116 #ifdef PACKET_RECV_TYPE
117 struct sockaddr_ll sll; 117 struct sockaddr_ll sll;
118 struct ifreq ifr; 118 struct ifreq ifr;
119 int mask; 119 int mask;
120 int fd; 120 int fd;
121   121  
122 fd = pcap_get_selectable_fd(p); 122 fd = pcap_get_selectable_fd(p);
123 if (fd < 0) 123 if (fd < 0)
124 return; 124 return;
125   125  
126 if (rx) 126 if (rx)
127 mask = 1 << PACKET_BROADCAST; 127 mask = 1 << PACKET_BROADCAST;
128 else 128 else
129 mask = 0; 129 mask = 0;
130   130  
131 setsockopt(fd, SOL_PACKET, PACKET_RECV_TYPE, &mask, sizeof(mask)); 131 setsockopt(fd, SOL_PACKET, PACKET_RECV_TYPE, &mask, sizeof(mask));
132 #endif 132 #endif
133 } 133 }
134   134  
135   135  
136 static pcap_t * 136 static pcap_t *
137 ead_open_pcap(const char *ifname, char *errbuf, bool rx) 137 ead_open_pcap(const char *ifname, char *errbuf, bool rx)
138 { 138 {
139 pcap_t *p; 139 pcap_t *p;
140   140  
141 p = pcap_create(ifname, errbuf); 141 p = pcap_create(ifname, errbuf);
142 if (p == NULL) 142 if (p == NULL)
143 goto out; 143 goto out;
144   144  
145 pcap_set_snaplen(p, PCAP_MRU); 145 pcap_set_snaplen(p, PCAP_MRU);
146 pcap_set_promisc(p, rx); 146 pcap_set_promisc(p, rx);
147 pcap_set_timeout(p, PCAP_TIMEOUT); 147 pcap_set_timeout(p, PCAP_TIMEOUT);
-   148 #ifdef HAS_PROTO_EXTENSION
148 pcap_set_protocol_linux(p, (rx ? htons(ETH_P_IP) : 0)); 149 pcap_set_protocol(p, (rx ? htons(ETH_P_IP) : 0));
-   150 #endif
149 pcap_set_buffer_size(p, (rx ? 10 : 1) * PCAP_MRU); 151 pcap_set_buffer_size(p, (rx ? 10 : 1) * PCAP_MRU);
150 pcap_activate(p); 152 pcap_activate(p);
151 set_recv_type(p, rx); 153 set_recv_type(p, rx);
152 out: 154 out:
153 return p; 155 return p;
154 } 156 }
155   157  
156 static void 158 static void
157 get_random_bytes(void *ptr, int len) 159 get_random_bytes(void *ptr, int len)
158 { 160 {
159 int fd; 161 int fd;
160   162  
161 fd = open("/dev/urandom", O_RDONLY); 163 fd = open("/dev/urandom", O_RDONLY);
162 if (fd < 0) { 164 if (fd < 0) {
163 perror("open"); 165 perror("open");
164 exit(1); 166 exit(1);
165 } 167 }
166 read(fd, ptr, len); 168 read(fd, ptr, len);
167 close(fd); 169 close(fd);
168 } 170 }
169   171  
170 static bool 172 static bool
171 prepare_password(void) 173 prepare_password(void)
172 { 174 {
173 static char lbuf[1024]; 175 static char lbuf[1024];
174 unsigned char dig[SHA_DIGESTSIZE]; 176 unsigned char dig[SHA_DIGESTSIZE];
175 BigInteger x, v, n, g; 177 BigInteger x, v, n, g;
176 SHA1_CTX ctxt; 178 SHA1_CTX ctxt;
177 int ulen = strlen(username); 179 int ulen = strlen(username);
178 FILE *f; 180 FILE *f;
179   181  
180 lbuf[sizeof(lbuf) - 1] = 0; 182 lbuf[sizeof(lbuf) - 1] = 0;
181   183  
182 f = fopen(passwd_file, "r"); 184 f = fopen(passwd_file, "r");
183 if (!f) 185 if (!f)
184 return false; 186 return false;
185   187  
186 while (fgets(lbuf, sizeof(lbuf) - 1, f) != NULL) { 188 while (fgets(lbuf, sizeof(lbuf) - 1, f) != NULL) {
187 char *str, *s2; 189 char *str, *s2;
188   190  
189 if (strncmp(lbuf, username, ulen) != 0) 191 if (strncmp(lbuf, username, ulen) != 0)
190 continue; 192 continue;
191   193  
192 if (lbuf[ulen] != ':') 194 if (lbuf[ulen] != ':')
193 continue; 195 continue;
194   196  
195 str = &lbuf[ulen + 1]; 197 str = &lbuf[ulen + 1];
196   198  
197 if (strncmp(str, "$1$", 3) != 0) 199 if (strncmp(str, "$1$", 3) != 0)
198 continue; 200 continue;
199   201  
200 s2 = strchr(str + 3, '$'); 202 s2 = strchr(str + 3, '$');
201 if (!s2) 203 if (!s2)
202 continue; 204 continue;
203   205  
204 if (s2 - str >= MAXSALTLEN) 206 if (s2 - str >= MAXSALTLEN)
205 continue; 207 continue;
206   208  
207 strncpy((char *) pw_saltbuf, str, s2 - str); 209 strncpy((char *) pw_saltbuf, str, s2 - str);
208 pw_saltbuf[s2 - str] = 0; 210 pw_saltbuf[s2 - str] = 0;
209   211  
210 s2 = strchr(s2, ':'); 212 s2 = strchr(s2, ':');
211 if (!s2) 213 if (!s2)
212 continue; 214 continue;
213   215  
214 *s2 = 0; 216 *s2 = 0;
215 if (s2 - str >= MAXPARAMLEN) 217 if (s2 - str >= MAXPARAMLEN)
216 continue; 218 continue;
217   219  
218 strncpy((char *)password, str, MAXPARAMLEN); 220 strncpy((char *)password, str, MAXPARAMLEN);
219 fclose(f); 221 fclose(f);
220 goto hash_password; 222 goto hash_password;
221 } 223 }
222   224  
223 /* not found */ 225 /* not found */
224 fclose(f); 226 fclose(f);
225 return false; 227 return false;
226   228  
227 hash_password: 229 hash_password:
228 tce = gettcid(tpe.index); 230 tce = gettcid(tpe.index);
229 do { 231 do {
230 t_random(tpe.password.data, SALTLEN); 232 t_random(tpe.password.data, SALTLEN);
231 } while (memcmp(saltbuf, (char *)dig, sizeof(saltbuf)) == 0); 233 } while (memcmp(saltbuf, (char *)dig, sizeof(saltbuf)) == 0);
232 if (saltbuf[0] == 0) 234 if (saltbuf[0] == 0)
233 saltbuf[0] = 0xff; 235 saltbuf[0] = 0xff;
234   236  
235 n = BigIntegerFromBytes(tce->modulus.data, tce->modulus.len); 237 n = BigIntegerFromBytes(tce->modulus.data, tce->modulus.len);
236 g = BigIntegerFromBytes(tce->generator.data, tce->generator.len); 238 g = BigIntegerFromBytes(tce->generator.data, tce->generator.len);
237 v = BigIntegerFromInt(0); 239 v = BigIntegerFromInt(0);
238   240  
239 SHA1Init(&ctxt); 241 SHA1Init(&ctxt);
240 SHA1Update(&ctxt, (unsigned char *) username, strlen(username)); 242 SHA1Update(&ctxt, (unsigned char *) username, strlen(username));
241 SHA1Update(&ctxt, (unsigned char *) ":", 1); 243 SHA1Update(&ctxt, (unsigned char *) ":", 1);
242 SHA1Update(&ctxt, (unsigned char *) password, strlen(password)); 244 SHA1Update(&ctxt, (unsigned char *) password, strlen(password));
243 SHA1Final(dig, &ctxt); 245 SHA1Final(dig, &ctxt);
244   246  
245 SHA1Init(&ctxt); 247 SHA1Init(&ctxt);
246 SHA1Update(&ctxt, saltbuf, tpe.salt.len); 248 SHA1Update(&ctxt, saltbuf, tpe.salt.len);
247 SHA1Update(&ctxt, dig, sizeof(dig)); 249 SHA1Update(&ctxt, dig, sizeof(dig));
248 SHA1Final(dig, &ctxt); 250 SHA1Final(dig, &ctxt);
249   251  
250 /* x = H(s, H(u, ':', p)) */ 252 /* x = H(s, H(u, ':', p)) */
251 x = BigIntegerFromBytes(dig, sizeof(dig)); 253 x = BigIntegerFromBytes(dig, sizeof(dig));
252   254  
253 BigIntegerModExp(v, g, x, n); 255 BigIntegerModExp(v, g, x, n);
254 tpe.password.len = BigIntegerToBytes(v, (unsigned char *)pwbuf); 256 tpe.password.len = BigIntegerToBytes(v, (unsigned char *)pwbuf);
255   257  
256 BigIntegerFree(v); 258 BigIntegerFree(v);
257 BigIntegerFree(x); 259 BigIntegerFree(x);
258 BigIntegerFree(g); 260 BigIntegerFree(g);
259 BigIntegerFree(n); 261 BigIntegerFree(n);
260 return true; 262 return true;
261 } 263 }
262   264  
263 static u16_t 265 static u16_t
264 chksum(u16_t sum, const u8_t *data, u16_t len) 266 chksum(u16_t sum, const u8_t *data, u16_t len)
265 { 267 {
266 u16_t t; 268 u16_t t;
267 const u8_t *dataptr; 269 const u8_t *dataptr;
268 const u8_t *last_byte; 270 const u8_t *last_byte;
269   271  
270 dataptr = data; 272 dataptr = data;
271 last_byte = data + len - 1; 273 last_byte = data + len - 1;
272   274  
273 while(dataptr < last_byte) { /* At least two more bytes */ 275 while(dataptr < last_byte) { /* At least two more bytes */
274 t = (dataptr[0] << 8) + dataptr[1]; 276 t = (dataptr[0] << 8) + dataptr[1];
275 sum += t; 277 sum += t;
276 if(sum < t) { 278 if(sum < t) {
277 sum++; /* carry */ 279 sum++; /* carry */
278 } 280 }
279 dataptr += 2; 281 dataptr += 2;
280 } 282 }
281   283  
282 if(dataptr == last_byte) { 284 if(dataptr == last_byte) {
283 t = (dataptr[0] << 8) + 0; 285 t = (dataptr[0] << 8) + 0;
284 sum += t; 286 sum += t;
285 if(sum < t) { 287 if(sum < t) {
286 sum++; /* carry */ 288 sum++; /* carry */
287 } 289 }
288 } 290 }
289   291  
290 /* Return sum in host byte order. */ 292 /* Return sum in host byte order. */
291 return sum; 293 return sum;
292 } 294 }
293   295  
294 static void 296 static void
295 ead_send_packet_clone(struct ead_packet *pkt) 297 ead_send_packet_clone(struct ead_packet *pkt)
296 { 298 {
297 u16_t len, sum; 299 u16_t len, sum;
298   300  
299 memcpy(pktbuf, pkt, offsetof(struct ead_packet, msg)); 301 memcpy(pktbuf, pkt, offsetof(struct ead_packet, msg));
300 memcpy(pktbuf->eh.ether_shost, ethmac, 6); 302 memcpy(pktbuf->eh.ether_shost, ethmac, 6);
301 memcpy(pktbuf->eh.ether_dhost, pkt->eh.ether_shost, 6); 303 memcpy(pktbuf->eh.ether_dhost, pkt->eh.ether_shost, 6);
302   304  
303 /* ip header */ 305 /* ip header */
304 len = sizeof(struct ead_packet) - sizeof(struct ether_header) + ntohl(pktbuf->msg.len); 306 len = sizeof(struct ead_packet) - sizeof(struct ether_header) + ntohl(pktbuf->msg.len);
305 pktbuf->len[0] = len >> 8; 307 pktbuf->len[0] = len >> 8;
306 pktbuf->len[1] = len & 0xff; 308 pktbuf->len[1] = len & 0xff;
307 memcpy(pktbuf->srcipaddr, &pkt->msg.ip, 4); 309 memcpy(pktbuf->srcipaddr, &pkt->msg.ip, 4);
308 memcpy(pktbuf->destipaddr, pkt->srcipaddr, 4); 310 memcpy(pktbuf->destipaddr, pkt->srcipaddr, 4);
309   311  
310 /* ip checksum */ 312 /* ip checksum */
311 pktbuf->ipchksum = 0; 313 pktbuf->ipchksum = 0;
312 sum = chksum(0, (void *) &pktbuf->vhl, UIP_IPH_LEN); 314 sum = chksum(0, (void *) &pktbuf->vhl, UIP_IPH_LEN);
313 if (sum == 0) 315 if (sum == 0)
314 sum = 0xffff; 316 sum = 0xffff;
315 pktbuf->ipchksum = htons(~sum); 317 pktbuf->ipchksum = htons(~sum);
316   318  
317 /* udp header */ 319 /* udp header */
318 pktbuf->srcport = pkt->destport; 320 pktbuf->srcport = pkt->destport;
319 pktbuf->destport = pkt->srcport; 321 pktbuf->destport = pkt->srcport;
320   322  
321 /* udp checksum */ 323 /* udp checksum */
322 len -= UIP_IPH_LEN; 324 len -= UIP_IPH_LEN;
323 pktbuf->udplen = htons(len); 325 pktbuf->udplen = htons(len);
324 pktbuf->udpchksum = 0; 326 pktbuf->udpchksum = 0;
325 sum = len + UIP_PROTO_UDP; 327 sum = len + UIP_PROTO_UDP;
326 sum = chksum(sum, (void *) &pktbuf->srcipaddr[0], 8); /* src, dest ip */ 328 sum = chksum(sum, (void *) &pktbuf->srcipaddr[0], 8); /* src, dest ip */
327 sum = chksum(sum, (void *) &pktbuf->srcport, len); 329 sum = chksum(sum, (void *) &pktbuf->srcport, len);
328 if (sum == 0) 330 if (sum == 0)
329 sum = 0xffff; 331 sum = 0xffff;
330 pktbuf->udpchksum = htons(~sum); 332 pktbuf->udpchksum = htons(~sum);
331 pcap_sendpacket(pcap_fp, (void *) pktbuf, sizeof(struct ead_packet) + ntohl(pktbuf->msg.len)); 333 pcap_sendpacket(pcap_fp, (void *) pktbuf, sizeof(struct ead_packet) + ntohl(pktbuf->msg.len));
332 } 334 }
333   335  
334 static void 336 static void
335 set_state(int nstate) 337 set_state(int nstate)
336 { 338 {
337 if (state == nstate) 339 if (state == nstate)
338 return; 340 return;
339   341  
340 if (nstate < state) { 342 if (nstate < state) {
341 if ((nstate < EAD_TYPE_GET_PRIME) && 343 if ((nstate < EAD_TYPE_GET_PRIME) &&
342 (state >= EAD_TYPE_GET_PRIME)) { 344 (state >= EAD_TYPE_GET_PRIME)) {
343 t_serverclose(ts); 345 t_serverclose(ts);
344 ts = NULL; 346 ts = NULL;
345 } 347 }
346 goto done; 348 goto done;
347 } 349 }
348   350  
349 switch(state) { 351 switch(state) {
350 case EAD_TYPE_SET_USERNAME: 352 case EAD_TYPE_SET_USERNAME:
351 if (!prepare_password()) 353 if (!prepare_password())
352 goto error; 354 goto error;
353 ts = t_serveropenraw(&tpe, tce); 355 ts = t_serveropenraw(&tpe, tce);
354 if (!ts) 356 if (!ts)
355 goto error; 357 goto error;
356 break; 358 break;
357 case EAD_TYPE_GET_PRIME: 359 case EAD_TYPE_GET_PRIME:
358 B = t_servergenexp(ts); 360 B = t_servergenexp(ts);
359 break; 361 break;
360 case EAD_TYPE_SEND_A: 362 case EAD_TYPE_SEND_A:
361 skey = t_servergetkey(ts, &A); 363 skey = t_servergetkey(ts, &A);
362 if (!skey) 364 if (!skey)
363 goto error; 365 goto error;
364   366  
365 ead_set_key(skey); 367 ead_set_key(skey);
366 break; 368 break;
367 } 369 }
368 done: 370 done:
369 state = nstate; 371 state = nstate;
370 error: 372 error:
371 return; 373 return;
372 } 374 }
373   375  
374 static bool 376 static bool
375 handle_ping(struct ead_packet *pkt, int len, int *nstate) 377 handle_ping(struct ead_packet *pkt, int len, int *nstate)
376 { 378 {
377 struct ead_msg *msg = &pktbuf->msg; 379 struct ead_msg *msg = &pktbuf->msg;
378 struct ead_msg_pong *pong = EAD_DATA(msg, pong); 380 struct ead_msg_pong *pong = EAD_DATA(msg, pong);
379 int slen; 381 int slen;
380   382  
381 slen = strlen(dev_name); 383 slen = strlen(dev_name);
382 if (slen > 1024) 384 if (slen > 1024)
383 slen = 1024; 385 slen = 1024;
384   386  
385 msg->len = htonl(sizeof(struct ead_msg_pong) + slen); 387 msg->len = htonl(sizeof(struct ead_msg_pong) + slen);
386 strncpy(pong->name, dev_name, slen); 388 strncpy(pong->name, dev_name, slen);
387 pong->name[slen] = 0; 389 pong->name[slen] = 0;
388 pong->auth_type = htons(EAD_AUTH_MD5); 390 pong->auth_type = htons(EAD_AUTH_MD5);
389   391  
390 return true; 392 return true;
391 } 393 }
392   394  
393 static bool 395 static bool
394 handle_set_username(struct ead_packet *pkt, int len, int *nstate) 396 handle_set_username(struct ead_packet *pkt, int len, int *nstate)
395 { 397 {
396 struct ead_msg *msg = &pkt->msg; 398 struct ead_msg *msg = &pkt->msg;
397 struct ead_msg_user *user = EAD_DATA(msg, user); 399 struct ead_msg_user *user = EAD_DATA(msg, user);
398   400  
399 set_state(EAD_TYPE_SET_USERNAME); /* clear old state */ 401 set_state(EAD_TYPE_SET_USERNAME); /* clear old state */
400 strncpy(username, user->username, sizeof(username)); 402 strncpy(username, user->username, sizeof(username));
401 username[sizeof(username) - 1] = 0; 403 username[sizeof(username) - 1] = 0;
402   404  
403 msg = &pktbuf->msg; 405 msg = &pktbuf->msg;
404 msg->len = 0; 406 msg->len = 0;
405   407  
406 *nstate = EAD_TYPE_GET_PRIME; 408 *nstate = EAD_TYPE_GET_PRIME;
407 return true; 409 return true;
408 } 410 }
409   411  
410 static bool 412 static bool
411 handle_get_prime(struct ead_packet *pkt, int len, int *nstate) 413 handle_get_prime(struct ead_packet *pkt, int len, int *nstate)
412 { 414 {
413 struct ead_msg *msg = &pktbuf->msg; 415 struct ead_msg *msg = &pktbuf->msg;
414 struct ead_msg_salt *salt = EAD_DATA(msg, salt); 416 struct ead_msg_salt *salt = EAD_DATA(msg, salt);
415   417  
416 msg->len = htonl(sizeof(struct ead_msg_salt)); 418 msg->len = htonl(sizeof(struct ead_msg_salt));
417 salt->prime = tce->index - 1; 419 salt->prime = tce->index - 1;
418 salt->len = ts->s.len; 420 salt->len = ts->s.len;
419 memcpy(salt->salt, ts->s.data, ts->s.len); 421 memcpy(salt->salt, ts->s.data, ts->s.len);
420 memcpy(salt->ext_salt, pw_saltbuf, MAXSALTLEN); 422 memcpy(salt->ext_salt, pw_saltbuf, MAXSALTLEN);
421   423  
422 *nstate = EAD_TYPE_SEND_A; 424 *nstate = EAD_TYPE_SEND_A;
423 return true; 425 return true;
424 } 426 }
425   427  
426 static bool 428 static bool
427 handle_send_a(struct ead_packet *pkt, int len, int *nstate) 429 handle_send_a(struct ead_packet *pkt, int len, int *nstate)
428 { 430 {
429 struct ead_msg *msg = &pkt->msg; 431 struct ead_msg *msg = &pkt->msg;
430 struct ead_msg_number *number = EAD_DATA(msg, number); 432 struct ead_msg_number *number = EAD_DATA(msg, number);
431 len = ntohl(msg->len) - sizeof(struct ead_msg_number); 433 len = ntohl(msg->len) - sizeof(struct ead_msg_number);
432   434  
433 if (len > MAXPARAMLEN + 1) 435 if (len > MAXPARAMLEN + 1)
434 return false; 436 return false;
435   437  
436 A.len = len; 438 A.len = len;
437 A.data = abuf; 439 A.data = abuf;
438 memcpy(A.data, number->data, len); 440 memcpy(A.data, number->data, len);
439   441  
440 msg = &pktbuf->msg; 442 msg = &pktbuf->msg;
441 number = EAD_DATA(msg, number); 443 number = EAD_DATA(msg, number);
442 msg->len = htonl(sizeof(struct ead_msg_number) + B->len); 444 msg->len = htonl(sizeof(struct ead_msg_number) + B->len);
443 memcpy(number->data, B->data, B->len); 445 memcpy(number->data, B->data, B->len);
444   446  
445 *nstate = EAD_TYPE_SEND_AUTH; 447 *nstate = EAD_TYPE_SEND_AUTH;
446 return true; 448 return true;
447 } 449 }
448   450  
449 static bool 451 static bool
450 handle_send_auth(struct ead_packet *pkt, int len, int *nstate) 452 handle_send_auth(struct ead_packet *pkt, int len, int *nstate)
451 { 453 {
452 struct ead_msg *msg = &pkt->msg; 454 struct ead_msg *msg = &pkt->msg;
453 struct ead_msg_auth *auth = EAD_DATA(msg, auth); 455 struct ead_msg_auth *auth = EAD_DATA(msg, auth);
454   456  
455 if (t_serververify(ts, auth->data) != 0) { 457 if (t_serververify(ts, auth->data) != 0) {
456 DEBUG(2, "Client authentication failed\n"); 458 DEBUG(2, "Client authentication failed\n");
457 *nstate = EAD_TYPE_SET_USERNAME; 459 *nstate = EAD_TYPE_SET_USERNAME;
458 return false; 460 return false;
459 } 461 }
460   462  
461 msg = &pktbuf->msg; 463 msg = &pktbuf->msg;
462 auth = EAD_DATA(msg, auth); 464 auth = EAD_DATA(msg, auth);
463 msg->len = htonl(sizeof(struct ead_msg_auth)); 465 msg->len = htonl(sizeof(struct ead_msg_auth));
464   466  
465 DEBUG(2, "Client authentication successful\n"); 467 DEBUG(2, "Client authentication successful\n");
466 memcpy(auth->data, t_serverresponse(ts), sizeof(auth->data)); 468 memcpy(auth->data, t_serverresponse(ts), sizeof(auth->data));
467   469  
468 *nstate = EAD_TYPE_SEND_CMD; 470 *nstate = EAD_TYPE_SEND_CMD;
469 return true; 471 return true;
470 } 472 }
471   473  
472 static bool 474 static bool
473 handle_send_cmd(struct ead_packet *pkt, int len, int *nstate) 475 handle_send_cmd(struct ead_packet *pkt, int len, int *nstate)
474 { 476 {
475 struct ead_msg *msg = &pkt->msg; 477 struct ead_msg *msg = &pkt->msg;
476 struct ead_msg_cmd *cmd = EAD_ENC_DATA(msg, cmd); 478 struct ead_msg_cmd *cmd = EAD_ENC_DATA(msg, cmd);
477 struct ead_msg_cmd_data *cmddata; 479 struct ead_msg_cmd_data *cmddata;
478 struct timeval tv, to, tn; 480 struct timeval tv, to, tn;
479 int pfd[2], fd; 481 int pfd[2], fd;
480 fd_set fds; 482 fd_set fds;
481 pid_t pid; 483 pid_t pid;
482 bool stream = false; 484 bool stream = false;
483 int timeout; 485 int timeout;
484 int type; 486 int type;
485 int datalen; 487 int datalen;
486   488  
487 datalen = ead_decrypt_message(msg) - sizeof(struct ead_msg_cmd); 489 datalen = ead_decrypt_message(msg) - sizeof(struct ead_msg_cmd);
488 if (datalen <= 0) 490 if (datalen <= 0)
489 return false; 491 return false;
490   492  
491 type = ntohs(cmd->type); 493 type = ntohs(cmd->type);
492 timeout = ntohs(cmd->timeout); 494 timeout = ntohs(cmd->timeout);
493   495  
494 FD_ZERO(&fds); 496 FD_ZERO(&fds);
495 cmd->data[datalen] = 0; 497 cmd->data[datalen] = 0;
496 switch(type) { 498 switch(type) {
497 case EAD_CMD_NORMAL: 499 case EAD_CMD_NORMAL:
498 if (pipe(pfd) < 0) 500 if (pipe(pfd) < 0)
499 return false; 501 return false;
500   502  
501 fcntl(pfd[0], F_SETFL, O_NONBLOCK | fcntl(pfd[0], F_GETFL)); 503 fcntl(pfd[0], F_SETFL, O_NONBLOCK | fcntl(pfd[0], F_GETFL));
502 child_pending = true; 504 child_pending = true;
503 pid = fork(); 505 pid = fork();
504 if (pid == 0) { 506 if (pid == 0) {
505 close(pfd[0]); 507 close(pfd[0]);
506 fd = open("/dev/null", O_RDWR); 508 fd = open("/dev/null", O_RDWR);
507 if (fd > 0) { 509 if (fd > 0) {
508 dup2(fd, 0); 510 dup2(fd, 0);
509 dup2(pfd[1], 1); 511 dup2(pfd[1], 1);
510 dup2(pfd[1], 2); 512 dup2(pfd[1], 2);
511 } 513 }
512 system((char *)cmd->data); 514 system((char *)cmd->data);
513 exit(0); 515 exit(0);
514 } else if (pid > 0) { 516 } else if (pid > 0) {
515 close(pfd[1]); 517 close(pfd[1]);
516 if (!timeout) 518 if (!timeout)
517 timeout = EAD_CMD_TIMEOUT; 519 timeout = EAD_CMD_TIMEOUT;
518   520  
519 stream = true; 521 stream = true;
520 break; 522 break;
521 } 523 }
522 return false; 524 return false;
523 case EAD_CMD_BACKGROUND: 525 case EAD_CMD_BACKGROUND:
524 pid = fork(); 526 pid = fork();
525 if (pid == 0) { 527 if (pid == 0) {
526 /* close stdin, stdout, stderr, replace with fd to /dev/null */ 528 /* close stdin, stdout, stderr, replace with fd to /dev/null */
527 fd = open("/dev/null", O_RDWR); 529 fd = open("/dev/null", O_RDWR);
528 if (fd > 0) { 530 if (fd > 0) {
529 dup2(fd, 0); 531 dup2(fd, 0);
530 dup2(fd, 1); 532 dup2(fd, 1);
531 dup2(fd, 2); 533 dup2(fd, 2);
532 } 534 }
533 system((char *)cmd->data); 535 system((char *)cmd->data);
534 exit(0); 536 exit(0);
535 } else if (pid > 0) { 537 } else if (pid > 0) {
536 break; 538 break;
537 } 539 }
538 return false; 540 return false;
539 default: 541 default:
540 return false; 542 return false;
541 } 543 }
542   544  
543 msg = &pktbuf->msg; 545 msg = &pktbuf->msg;
544 cmddata = EAD_ENC_DATA(msg, cmd_data); 546 cmddata = EAD_ENC_DATA(msg, cmd_data);
545   547  
546 if (stream) { 548 if (stream) {
547 int nfds, bytes; 549 int nfds, bytes;
548   550  
549 /* send keepalive packets every 200 ms so that the client doesn't timeout */ 551 /* send keepalive packets every 200 ms so that the client doesn't timeout */
550 gettimeofday(&to, NULL); 552 gettimeofday(&to, NULL);
551 memcpy(&tn, &to, sizeof(tn)); 553 memcpy(&tn, &to, sizeof(tn));
552 tv.tv_usec = PCAP_TIMEOUT * 1000; 554 tv.tv_usec = PCAP_TIMEOUT * 1000;
553 tv.tv_sec = 0; 555 tv.tv_sec = 0;
554 do { 556 do {
555 cmddata->done = 0; 557 cmddata->done = 0;
556 FD_SET(pfd[0], &fds); 558 FD_SET(pfd[0], &fds);
557 nfds = select(pfd[0] + 1, &fds, NULL, NULL, &tv); 559 nfds = select(pfd[0] + 1, &fds, NULL, NULL, &tv);
558 bytes = 0; 560 bytes = 0;
559 if (nfds > 0) { 561 if (nfds > 0) {
560 bytes = read(pfd[0], cmddata->data, 1024); 562 bytes = read(pfd[0], cmddata->data, 1024);
561 if (bytes < 0) 563 if (bytes < 0)
562 bytes = 0; 564 bytes = 0;
563 } 565 }
564 if (!bytes && !child_pending) 566 if (!bytes && !child_pending)
565 break; 567 break;
566 DEBUG(3, "Sending %d bytes of console data, type=%d, timeout=%d\n", bytes, ntohl(msg->type), timeout); 568 DEBUG(3, "Sending %d bytes of console data, type=%d, timeout=%d\n", bytes, ntohl(msg->type), timeout);
567 ead_encrypt_message(msg, sizeof(struct ead_msg_cmd_data) + bytes); 569 ead_encrypt_message(msg, sizeof(struct ead_msg_cmd_data) + bytes);
568 ead_send_packet_clone(pkt); 570 ead_send_packet_clone(pkt);
569 gettimeofday(&tn, NULL); 571 gettimeofday(&tn, NULL);
570 } while (tn.tv_sec < to.tv_sec + timeout); 572 } while (tn.tv_sec < to.tv_sec + timeout);
571 if (child_pending) { 573 if (child_pending) {
572 kill(pid, SIGKILL); 574 kill(pid, SIGKILL);
573 return false; 575 return false;
574 } 576 }
575 } 577 }
576 cmddata->done = 1; 578 cmddata->done = 1;
577 ead_encrypt_message(msg, sizeof(struct ead_msg_cmd_data)); 579 ead_encrypt_message(msg, sizeof(struct ead_msg_cmd_data));
578   580  
579 return true; 581 return true;
580 } 582 }
581   583  
582   584  
583   585  
584 static void 586 static void
585 parse_message(struct ead_packet *pkt, int len) 587 parse_message(struct ead_packet *pkt, int len)
586 { 588 {
587 bool (*handler)(struct ead_packet *pkt, int len, int *nstate); 589 bool (*handler)(struct ead_packet *pkt, int len, int *nstate);
588 int min_len = sizeof(struct ead_packet); 590 int min_len = sizeof(struct ead_packet);
589 int nstate = state; 591 int nstate = state;
590 int type = ntohl(pkt->msg.type); 592 int type = ntohl(pkt->msg.type);
591   593  
592 if ((type >= EAD_TYPE_GET_PRIME) && 594 if ((type >= EAD_TYPE_GET_PRIME) &&
593 (state != type)) 595 (state != type))
594 return; 596 return;
595   597  
596 if ((type != EAD_TYPE_PING) && 598 if ((type != EAD_TYPE_PING) &&
597 ((ntohs(pkt->msg.sid) & EAD_INSTANCE_MASK) >> 599 ((ntohs(pkt->msg.sid) & EAD_INSTANCE_MASK) >>
598 EAD_INSTANCE_SHIFT) != instance->id) 600 EAD_INSTANCE_SHIFT) != instance->id)
599 return; 601 return;
600   602  
601 switch(type) { 603 switch(type) {
602 case EAD_TYPE_PING: 604 case EAD_TYPE_PING:
603 handler = handle_ping; 605 handler = handle_ping;
604 break; 606 break;
605 case EAD_TYPE_SET_USERNAME: 607 case EAD_TYPE_SET_USERNAME:
606 handler = handle_set_username; 608 handler = handle_set_username;
607 min_len += sizeof(struct ead_msg_user); 609 min_len += sizeof(struct ead_msg_user);
608 break; 610 break;
609 case EAD_TYPE_GET_PRIME: 611 case EAD_TYPE_GET_PRIME:
610 handler = handle_get_prime; 612 handler = handle_get_prime;
611 break; 613 break;
612 case EAD_TYPE_SEND_A: 614 case EAD_TYPE_SEND_A:
613 handler = handle_send_a; 615 handler = handle_send_a;
614 min_len += sizeof(struct ead_msg_number); 616 min_len += sizeof(struct ead_msg_number);
615 break; 617 break;
616 case EAD_TYPE_SEND_AUTH: 618 case EAD_TYPE_SEND_AUTH:
617 handler = handle_send_auth; 619 handler = handle_send_auth;
618 min_len += sizeof(struct ead_msg_auth); 620 min_len += sizeof(struct ead_msg_auth);
619 break; 621 break;
620 case EAD_TYPE_SEND_CMD: 622 case EAD_TYPE_SEND_CMD:
621 handler = handle_send_cmd; 623 handler = handle_send_cmd;
622 min_len += sizeof(struct ead_msg_cmd) + sizeof(struct ead_msg_encrypted); 624 min_len += sizeof(struct ead_msg_cmd) + sizeof(struct ead_msg_encrypted);
623 break; 625 break;
624 default: 626 default:
625 return; 627 return;
626 } 628 }
627   629  
628 if (len < min_len) { 630 if (len < min_len) {
629 DEBUG(2, "discarding packet: message too small\n"); 631 DEBUG(2, "discarding packet: message too small\n");
630 return; 632 return;
631 } 633 }
632   634  
633 pktbuf->msg.magic = htonl(EAD_MAGIC); 635 pktbuf->msg.magic = htonl(EAD_MAGIC);
634 pktbuf->msg.type = htonl(type + 1); 636 pktbuf->msg.type = htonl(type + 1);
635 pktbuf->msg.nid = htons(nid); 637 pktbuf->msg.nid = htons(nid);
636 pktbuf->msg.sid = pkt->msg.sid; 638 pktbuf->msg.sid = pkt->msg.sid;
637 pktbuf->msg.len = 0; 639 pktbuf->msg.len = 0;
638   640  
639 if (handler(pkt, len, &nstate)) { 641 if (handler(pkt, len, &nstate)) {
640 DEBUG(2, "sending response to packet type %d: %d\n", type + 1, ntohl(pktbuf->msg.len)); 642 DEBUG(2, "sending response to packet type %d: %d\n", type + 1, ntohl(pktbuf->msg.len));
641 /* format response packet */ 643 /* format response packet */
642 ead_send_packet_clone(pkt); 644 ead_send_packet_clone(pkt);
643 } 645 }
644 set_state(nstate); 646 set_state(nstate);
645 } 647 }
646   648  
647 static void 649 static void
648 handle_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes) 650 handle_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes)
649 { 651 {
650 struct ead_packet *pkt = (struct ead_packet *) bytes; 652 struct ead_packet *pkt = (struct ead_packet *) bytes;
651   653  
652 if (h->len < sizeof(struct ead_packet)) 654 if (h->len < sizeof(struct ead_packet))
653 return; 655 return;
654   656  
655 if (pkt->eh.ether_type != htons(ETHERTYPE_IP)) 657 if (pkt->eh.ether_type != htons(ETHERTYPE_IP))
656 return; 658 return;
657   659  
658 if (memcmp(pkt->eh.ether_dhost, "\xff\xff\xff\xff\xff\xff", 6) != 0) 660 if (memcmp(pkt->eh.ether_dhost, "\xff\xff\xff\xff\xff\xff", 6) != 0)
659 return; 661 return;
660   662  
661 if (pkt->proto != UIP_PROTO_UDP) 663 if (pkt->proto != UIP_PROTO_UDP)
662 return; 664 return;
663   665  
664 if (pkt->destport != htons(EAD_PORT)) 666 if (pkt->destport != htons(EAD_PORT))
665 return; 667 return;
666   668  
667 if (pkt->msg.magic != htonl(EAD_MAGIC)) 669 if (pkt->msg.magic != htonl(EAD_MAGIC))
668 return; 670 return;
669   671  
670 if (h->len < sizeof(struct ead_packet) + ntohl(pkt->msg.len)) 672 if (h->len < sizeof(struct ead_packet) + ntohl(pkt->msg.len))
671 return; 673 return;
672   674  
673 if ((pkt->msg.nid != 0xffff) && 675 if ((pkt->msg.nid != 0xffff) &&
674 (pkt->msg.nid != htons(nid))) 676 (pkt->msg.nid != htons(nid)))
675 return; 677 return;
676   678  
677 parse_message(pkt, h->len); 679 parse_message(pkt, h->len);
678 } 680 }
679   681  
680 static void 682 static void
681 ead_pcap_reopen(bool first) 683 ead_pcap_reopen(bool first)
682 { 684 {
683 static char errbuf[PCAP_ERRBUF_SIZE] = ""; 685 static char errbuf[PCAP_ERRBUF_SIZE] = "";
684   686  
685 if (pcap_fp_rx && (pcap_fp_rx != pcap_fp)) 687 if (pcap_fp_rx && (pcap_fp_rx != pcap_fp))
686 pcap_close(pcap_fp_rx); 688 pcap_close(pcap_fp_rx);
687   689  
688 if (pcap_fp) 690 if (pcap_fp)
689 pcap_close(pcap_fp); 691 pcap_close(pcap_fp);
690   692  
691 pcap_fp_rx = NULL; 693 pcap_fp_rx = NULL;
692 do { 694 do {
693 if (instance->bridge[0]) { 695 if (instance->bridge[0]) {
694 pcap_fp_rx = ead_open_pcap(instance->bridge, errbuf, 1); 696 pcap_fp_rx = ead_open_pcap(instance->bridge, errbuf, 1);
695 pcap_fp = ead_open_pcap(instance->ifname, errbuf, 0); 697 pcap_fp = ead_open_pcap(instance->ifname, errbuf, 0);
696 } else { 698 } else {
697 pcap_fp = ead_open_pcap(instance->ifname, errbuf, 1); 699 pcap_fp = ead_open_pcap(instance->ifname, errbuf, 1);
698 } 700 }
699   701  
700 if (!pcap_fp_rx) 702 if (!pcap_fp_rx)
701 pcap_fp_rx = pcap_fp; 703 pcap_fp_rx = pcap_fp;
702 if (first && !pcap_fp) { 704 if (first && !pcap_fp) {
703 DEBUG(1, "WARNING: unable to open interface '%s'\n", instance->ifname); 705 DEBUG(1, "WARNING: unable to open interface '%s'\n", instance->ifname);
704 first = false; 706 first = false;
705 } 707 }
706 if (!pcap_fp) 708 if (!pcap_fp)
707 sleep(1); 709 sleep(1);
708 } while (!pcap_fp); 710 } while (!pcap_fp);
709 pcap_setfilter(pcap_fp_rx, &pktfilter); 711 pcap_setfilter(pcap_fp_rx, &pktfilter);
710 } 712 }
711   713  
712   714  
713 static void 715 static void
714 ead_pktloop(void) 716 ead_pktloop(void)
715 { 717 {
716 while (1) { 718 while (1) {
717 if (pcap_dispatch(pcap_fp_rx, 1, handle_packet, NULL) < 0) { 719 if (pcap_dispatch(pcap_fp_rx, 1, handle_packet, NULL) < 0) {
718 ead_pcap_reopen(false); 720 ead_pcap_reopen(false);
719 continue; 721 continue;
720 } 722 }
721 } 723 }
722 } 724 }
723   725  
724   726  
725 static int 727 static int
726 usage(const char *prog) 728 usage(const char *prog)
727 { 729 {
728 fprintf(stderr, "Usage: %s [<options>]\n" 730 fprintf(stderr, "Usage: %s [<options>]\n"
729 "Options:\n" 731 "Options:\n"
730 "\t-B Run in background mode\n" 732 "\t-B Run in background mode\n"
731 "\t-d <device> Set the device to listen on\n" 733 "\t-d <device> Set the device to listen on\n"
732 "\t-D <name> Set the name of the device visible to clients\n" 734 "\t-D <name> Set the name of the device visible to clients\n"
733 "\t-p <file> Set the password file for authenticating\n" 735 "\t-p <file> Set the password file for authenticating\n"
734 "\t-P <file> Write a pidfile\n" 736 "\t-P <file> Write a pidfile\n"
735 "\n", prog); 737 "\n", prog);
736 return -1; 738 return -1;
737 } 739 }
738   740  
739 static void 741 static void
740 server_handle_sigchld(int sig) 742 server_handle_sigchld(int sig)
741 { 743 {
742 struct ead_instance *in; 744 struct ead_instance *in;
743 struct list_head *p; 745 struct list_head *p;
744 int pid = 0; 746 int pid = 0;
745 wait(&pid); 747 wait(&pid);
746   748  
747 list_for_each(p, &instances) { 749 list_for_each(p, &instances) {
748 in = list_entry(p, struct ead_instance, list); 750 in = list_entry(p, struct ead_instance, list);
749 if (pid != in->pid) 751 if (pid != in->pid)
750 continue; 752 continue;
751   753  
752 in->pid = 0; 754 in->pid = 0;
753 break; 755 break;
754 } 756 }
755 } 757 }
756   758  
757 static void 759 static void
758 instance_handle_sigchld(int sig) 760 instance_handle_sigchld(int sig)
759 { 761 {
760 int pid = 0; 762 int pid = 0;
761 wait(&pid); 763 wait(&pid);
762 child_pending = false; 764 child_pending = false;
763 } 765 }
764   766  
765 static void 767 static void
766 start_server(struct ead_instance *i) 768 start_server(struct ead_instance *i)
767 { 769 {
768 if (!nonfork) { 770 if (!nonfork) {
769 i->pid = fork(); 771 i->pid = fork();
770 if (i->pid != 0) { 772 if (i->pid != 0) {
771 if (i->pid < 0) 773 if (i->pid < 0)
772 i->pid = 0; 774 i->pid = 0;
773 return; 775 return;
774 } 776 }
775 } 777 }
776   778  
777 instance = i; 779 instance = i;
778 signal(SIGCHLD, instance_handle_sigchld); 780 signal(SIGCHLD, instance_handle_sigchld);
779 ead_pcap_reopen(true); 781 ead_pcap_reopen(true);
780 ead_pktloop(); 782 ead_pktloop();
781 pcap_close(pcap_fp); 783 pcap_close(pcap_fp);
782 if (pcap_fp_rx != pcap_fp) 784 if (pcap_fp_rx != pcap_fp)
783 pcap_close(pcap_fp_rx); 785 pcap_close(pcap_fp_rx);
784   786  
785 exit(0); 787 exit(0);
786 } 788 }
787   789  
788   790  
789 static void 791 static void
790 start_servers(bool restart) 792 start_servers(bool restart)
791 { 793 {
792 struct ead_instance *in; 794 struct ead_instance *in;
793 struct list_head *p; 795 struct list_head *p;
794   796  
795 list_for_each(p, &instances) { 797 list_for_each(p, &instances) {
796 in = list_entry(p, struct ead_instance, list); 798 in = list_entry(p, struct ead_instance, list);
797 if (in->pid > 0) 799 if (in->pid > 0)
798 continue; 800 continue;
799   801  
800 sleep(1); 802 sleep(1);
801 start_server(in); 803 start_server(in);
802 } 804 }
803 } 805 }
804   806  
805 static void 807 static void
806 stop_server(struct ead_instance *in, bool do_free) 808 stop_server(struct ead_instance *in, bool do_free)
807 { 809 {
808 if (in->pid > 0) 810 if (in->pid > 0)
809 kill(in->pid, SIGKILL); 811 kill(in->pid, SIGKILL);
810 in->pid = 0; 812 in->pid = 0;
811 if (do_free) { 813 if (do_free) {
812 list_del(&in->list); 814 list_del(&in->list);
813 free(in); 815 free(in);
814 } 816 }
815 } 817 }
816   818  
817 static void 819 static void
818 server_handle_sigint(int sig) 820 server_handle_sigint(int sig)
819 { 821 {
820 struct ead_instance *in; 822 struct ead_instance *in;
821 struct list_head *p, *tmp; 823 struct list_head *p, *tmp;
822   824  
823 list_for_each_safe(p, tmp, &instances) { 825 list_for_each_safe(p, tmp, &instances) {
824 in = list_entry(p, struct ead_instance, list); 826 in = list_entry(p, struct ead_instance, list);
825 stop_server(in, true); 827 stop_server(in, true);
826 } 828 }
827 exit(1); 829 exit(1);
828 } 830 }
829   831  
830 static int 832 static int
831 check_bridge_port(const char *br, const char *port, void *arg) 833 check_bridge_port(const char *br, const char *port, void *arg)
832 { 834 {
833 struct ead_instance *in; 835 struct ead_instance *in;
834 struct list_head *p; 836 struct list_head *p;
835   837  
836 list_for_each(p, &instances) { 838 list_for_each(p, &instances) {
837 in = list_entry(p, struct ead_instance, list); 839 in = list_entry(p, struct ead_instance, list);
838   840  
839 if (strcmp(in->ifname, port) != 0) 841 if (strcmp(in->ifname, port) != 0)
840 continue; 842 continue;
841   843  
842 in->br_check = true; 844 in->br_check = true;
843 if (strcmp(in->bridge, br) == 0) 845 if (strcmp(in->bridge, br) == 0)
844 break; 846 break;
845   847  
846 strncpy(in->bridge, br, sizeof(in->bridge)); 848 strncpy(in->bridge, br, sizeof(in->bridge));
847 DEBUG(2, "assigning port %s to bridge %s\n", in->ifname, in->bridge); 849 DEBUG(2, "assigning port %s to bridge %s\n", in->ifname, in->bridge);
848 stop_server(in, false); 850 stop_server(in, false);
849 } 851 }
850 return 0; 852 return 0;
851 } 853 }
852   854  
853 static int 855 static int
854 check_bridge(const char *name, void *arg) 856 check_bridge(const char *name, void *arg)
855 { 857 {
856 br_foreach_port(name, check_bridge_port, arg); 858 br_foreach_port(name, check_bridge_port, arg);
857 return 0; 859 return 0;
858 } 860 }
859   861  
860 static void 862 static void
861 check_all_interfaces(void) 863 check_all_interfaces(void)
862 { 864 {
863 struct ead_instance *in; 865 struct ead_instance *in;
864 struct list_head *p; 866 struct list_head *p;
865   867  
866 br_foreach_bridge(check_bridge, NULL); 868 br_foreach_bridge(check_bridge, NULL);
867   869  
868 /* look for interfaces that are no longer part of a bridge */ 870 /* look for interfaces that are no longer part of a bridge */
869 list_for_each(p, &instances) { 871 list_for_each(p, &instances) {
870 in = list_entry(p, struct ead_instance, list); 872 in = list_entry(p, struct ead_instance, list);
871   873  
872 if (in->br_check) { 874 if (in->br_check) {
873 in->br_check = false; 875 in->br_check = false;
874 } else if (in->bridge[0]) { 876 } else if (in->bridge[0]) {
875 DEBUG(2, "removing port %s from bridge %s\n", in->ifname, in->bridge); 877 DEBUG(2, "removing port %s from bridge %s\n", in->ifname, in->bridge);
876 in->bridge[0] = 0; 878 in->bridge[0] = 0;
877 stop_server(in, false); 879 stop_server(in, false);
878 } 880 }
879 } 881 }
880 } 882 }
881   883  
882   884  
883 int main(int argc, char **argv) 885 int main(int argc, char **argv)
884 { 886 {
885 struct ead_instance *in; 887 struct ead_instance *in;
886 struct timeval tv; 888 struct timeval tv;
887 const char *pidfile = NULL; 889 const char *pidfile = NULL;
888 bool background = false; 890 bool background = false;
889 int n_iface = 0; 891 int n_iface = 0;
890 int fd, ch; 892 int fd, ch;
891   893  
892 if (argc == 1) 894 if (argc == 1)
893 return usage(argv[0]); 895 return usage(argv[0]);
894   896  
895 INIT_LIST_HEAD(&instances); 897 INIT_LIST_HEAD(&instances);
896 while ((ch = getopt(argc, argv, "Bd:D:fhp:P:")) != -1) { 898 while ((ch = getopt(argc, argv, "Bd:D:fhp:P:")) != -1) {
897 switch(ch) { 899 switch(ch) {
898 case 'B': 900 case 'B':
899 background = true; 901 background = true;
900 break; 902 break;
901 case 'f': 903 case 'f':
902 nonfork = true; 904 nonfork = true;
903 break; 905 break;
904 case 'h': 906 case 'h':
905 return usage(argv[0]); 907 return usage(argv[0]);
906 case 'd': 908 case 'd':
907 in = malloc(sizeof(struct ead_instance)); 909 in = malloc(sizeof(struct ead_instance));
908 memset(in, 0, sizeof(struct ead_instance)); 910 memset(in, 0, sizeof(struct ead_instance));
909 INIT_LIST_HEAD(&in->list); 911 INIT_LIST_HEAD(&in->list);
910 strncpy(in->ifname, optarg, sizeof(in->ifname) - 1); 912 strncpy(in->ifname, optarg, sizeof(in->ifname) - 1);
911 list_add(&in->list, &instances); 913 list_add(&in->list, &instances);
912 in->id = n_iface++; 914 in->id = n_iface++;
913 break; 915 break;
914 case 'D': 916 case 'D':
915 dev_name = optarg; 917 dev_name = optarg;
916 break; 918 break;
917 case 'p': 919 case 'p':
918 passwd_file = optarg; 920 passwd_file = optarg;
919 break; 921 break;
920 case 'P': 922 case 'P':
921 pidfile = optarg; 923 pidfile = optarg;
922 break; 924 break;
923 } 925 }
924 } 926 }
925 signal(SIGCHLD, server_handle_sigchld); 927 signal(SIGCHLD, server_handle_sigchld);
926 signal(SIGINT, server_handle_sigint); 928 signal(SIGINT, server_handle_sigint);
927 signal(SIGTERM, server_handle_sigint); 929 signal(SIGTERM, server_handle_sigint);
928 signal(SIGKILL, server_handle_sigint); 930 signal(SIGKILL, server_handle_sigint);
929   931  
930 if (!n_iface) { 932 if (!n_iface) {
931 fprintf(stderr, "Error: ead needs at least one interface\n"); 933 fprintf(stderr, "Error: ead needs at least one interface\n");
932 return -1; 934 return -1;
933 } 935 }
934   936  
935 if (background) { 937 if (background) {
936 if (fork() > 0) 938 if (fork() > 0)
937 exit(0); 939 exit(0);
938   940  
939 fd = open("/dev/null", O_RDWR); 941 fd = open("/dev/null", O_RDWR);
940 dup2(fd, 0); 942 dup2(fd, 0);
941 dup2(fd, 1); 943 dup2(fd, 1);
942 dup2(fd, 2); 944 dup2(fd, 2);
943 } 945 }
944   946  
945 if (pidfile) { 947 if (pidfile) {
946 char pid[8]; 948 char pid[8];
947 int len; 949 int len;
948   950  
949 unlink(pidfile); 951 unlink(pidfile);
950 fd = open(pidfile, O_CREAT|O_WRONLY|O_EXCL, 0644); 952 fd = open(pidfile, O_CREAT|O_WRONLY|O_EXCL, 0644);
951 if (fd > 0) { 953 if (fd > 0) {
952 len = sprintf(pid, "%d\n", getpid()); 954 len = sprintf(pid, "%d\n", getpid());
953 write(fd, pid, len); 955 write(fd, pid, len);
954 close(fd); 956 close(fd);
955 } 957 }
956 } 958 }
957   959  
958 /* randomize the mac address */ 960 /* randomize the mac address */
959 get_random_bytes(ethmac + 3, 3); 961 get_random_bytes(ethmac + 3, 3);
960 nid = *(((u16_t *) ethmac) + 2); 962 nid = *(((u16_t *) ethmac) + 2);
961   963  
962 start_servers(false); 964 start_servers(false);
963 br_init(); 965 br_init();
964 tv.tv_sec = 1; 966 tv.tv_sec = 1;
965 tv.tv_usec = 0; 967 tv.tv_usec = 0;
966 while (1) { 968 while (1) {
967 check_all_interfaces(); 969 check_all_interfaces();
968 start_servers(true); 970 start_servers(true);
969 sleep(1); 971 sleep(1);
970 } 972 }
971 br_shutdown(); 973 br_shutdown();
972   974  
973 return 0; 975 return 0;
974 } 976 }
975   977