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