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