aboutsummaryrefslogtreecommitdiffstats
path: root/package/ead
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2009-01-06 22:19:55 +0000
committerFelix Fietkau <nbd@openwrt.org>2009-01-06 22:19:55 +0000
commit4129203d75fc53adf9cf03c8bf09c3c8ceb85b62 (patch)
tree5e029cd54dff6700ebaced239a2c622d51f46872 /package/ead
parent341c1dbdf5107b6cd5f357d8d991a573d7f54d9e (diff)
downloadupstream-4129203d75fc53adf9cf03c8bf09c3c8ceb85b62.tar.gz
upstream-4129203d75fc53adf9cf03c8bf09c3c8ceb85b62.tar.bz2
upstream-4129203d75fc53adf9cf03c8bf09c3c8ceb85b62.zip
ead: add support for instance ids to prevent interference from packet reception on multiple interfaces
SVN-Revision: 13905
Diffstat (limited to 'package/ead')
-rw-r--r--package/ead/src/ead-client.c4
-rw-r--r--package/ead/src/ead.c81
-rw-r--r--package/ead/src/ead.h6
3 files changed, 52 insertions, 39 deletions
diff --git a/package/ead/src/ead-client.c b/package/ead/src/ead-client.c
index 2592c8f15e..7f462c180a 100644
--- a/package/ead/src/ead-client.c
+++ b/package/ead/src/ead-client.c
@@ -62,6 +62,7 @@ static struct t_num *A, B;
static struct t_preconf *tcp;
static int auth_type = EAD_AUTH_DEFAULT;
static int timeout = EAD_TIMEOUT;
+static uint16_t sid = 0;
static void
set_nonblock(int enable)
@@ -157,6 +158,7 @@ handle_pong(void)
auth_type = ntohs(pong->auth_type);
if (nid == 0xffff)
printf("%04x: %s\n", ntohs(msg->nid), pong->name);
+ sid = msg->sid;
return true;
}
@@ -320,7 +322,7 @@ int main(int argc, char **argv)
int ch;
msg->magic = htonl(EAD_MAGIC);
- msg->tid = 0;
+ msg->sid = 0;
memset(&local, 0, sizeof(local));
memset(&remote, 0, sizeof(remote));
diff --git a/package/ead/src/ead.c b/package/ead/src/ead.c
index 6a01ea42dd..9ce6f56911 100644
--- a/package/ead/src/ead.c
+++ b/package/ead/src/ead.c
@@ -65,10 +65,20 @@
#define DEBUG(n, format, ...) do {} while(0)
#endif
+struct ead_instance {
+ struct list_head list;
+ char ifname[16];
+ int pid;
+ char id;
+#ifdef linux
+ char bridge[16];
+ bool br_check;
+#endif
+};
+
static char ethmac[6] = "\x00\x13\x37\x00\x00\x00"; /* last 3 bytes will be randomized */
static pcap_t *pcap_fp = NULL;
static pcap_t *pcap_fp_rx = NULL;
-static const char *ifname = DEFAULT_IFNAME;
static char pktbuf_b[PCAP_MRU];
static struct ead_packet *pktbuf = (struct ead_packet *)pktbuf_b;
static u16_t nid = 0xffff; /* node id */
@@ -85,20 +95,7 @@ static unsigned char pw_saltbuf[MAXSALTLEN];
static struct list_head instances;
static const char *dev_name = DEFAULT_DEVNAME;
static bool nonfork = false;
-
-#ifdef linux
-static const char *brname = NULL;
-#endif
-
-struct ead_instance {
- struct list_head list;
- char name[16];
- int pid;
-#ifdef linux
- char bridge[16];
- bool br_check;
-#endif
-};
+static struct ead_instance *instance = NULL;
static struct t_pwent tpe = {
.name = username,
@@ -113,6 +110,20 @@ static struct t_server *ts = NULL;
static struct t_num A, *B = NULL;
unsigned char *skey;
+static void
+get_random_bytes(void *ptr, int len)
+{
+ int fd;
+
+ fd = open("/dev/urandom", O_RDONLY);
+ if (fd < 0) {
+ perror("open");
+ exit(1);
+ }
+ read(fd, ptr, len);
+ close(fd);
+}
+
static bool
prepare_password(void)
{
@@ -539,6 +550,11 @@ parse_message(struct ead_packet *pkt, int len)
(state != type))
return;
+ if ((type != EAD_TYPE_PING) &&
+ ((ntohs(pkt->msg.sid) & EAD_INSTANCE_MASK) >>
+ EAD_INSTANCE_SHIFT) != instance->id)
+ return;
+
switch(type) {
case EAD_TYPE_PING:
handler = handle_ping;
@@ -574,6 +590,7 @@ parse_message(struct ead_packet *pkt, int len)
pktbuf->msg.magic = htonl(EAD_MAGIC);
pktbuf->msg.type = htonl(type + 1);
pktbuf->msg.nid = htons(nid);
+ pktbuf->msg.sid = pkt->msg.sid;
pktbuf->msg.len = 0;
if (handler(pkt, len, &nstate)) {
@@ -630,16 +647,16 @@ ead_pcap_reopen(bool first)
pcap_fp_rx = NULL;
do {
- pcap_fp = pcap_open_live(ifname, PCAP_MRU, 1, PCAP_TIMEOUT, errbuf);
+ pcap_fp = pcap_open_live(instance->ifname, PCAP_MRU, 1, PCAP_TIMEOUT, errbuf);
#ifdef linux
- if (brname)
- pcap_fp_rx = pcap_open_live(brname, PCAP_MRU, 1, PCAP_TIMEOUT, errbuf);
+ if (instance->bridge[0])
+ pcap_fp_rx = pcap_open_live(instance->bridge, PCAP_MRU, 1, PCAP_TIMEOUT, errbuf);
#endif
if (!pcap_fp_rx)
pcap_fp_rx = pcap_fp;
pcap_setfilter(pcap_fp_rx, &pktfilter);
if (first && !pcap_fp) {
- DEBUG(1, "WARNING: unable to open interface '%s'\n", ifname);
+ DEBUG(1, "WARNING: unable to open interface '%s'\n", instance->ifname);
first = false;
}
if (!pcap_fp)
@@ -712,12 +729,8 @@ start_server(struct ead_instance *i)
}
}
+ instance = i;
signal(SIGCHLD, instance_handle_sigchld);
- ifname = i->name;
-#ifdef linux
- if (i->bridge[0])
- brname = i->bridge;
-#endif
ead_pcap_reopen(true);
ead_pktloop();
pcap_close(pcap_fp);
@@ -779,7 +792,7 @@ check_bridge_port(const char *br, const char *port, void *arg)
list_for_each(p, &instances) {
in = list_entry(p, struct ead_instance, list);
- if (strcmp(in->name, port) != 0)
+ if (strcmp(in->ifname, port) != 0)
continue;
in->br_check = true;
@@ -787,7 +800,7 @@ check_bridge_port(const char *br, const char *port, void *arg)
break;
strncpy(in->bridge, br, sizeof(in->bridge));
- DEBUG(2, "assigning port %s to bridge %s\n", in->name, in->bridge);
+ DEBUG(2, "assigning port %s to bridge %s\n", in->ifname, in->bridge);
stop_server(in, false);
}
return 0;
@@ -817,7 +830,7 @@ check_all_interfaces(void)
if (in->br_check) {
in->br_check = false;
} else if (in->bridge[0]) {
- DEBUG(2, "removing port %s from bridge %s\n", in->name, in->bridge);
+ DEBUG(2, "removing port %s from bridge %s\n", in->ifname, in->bridge);
in->bridge[0] = 0;
stop_server(in, false);
}
@@ -830,10 +843,10 @@ int main(int argc, char **argv)
{
struct ead_instance *in;
struct timeval tv;
- int fd, ch;
const char *pidfile = NULL;
bool background = false;
int n_iface = 0;
+ int fd, ch;
if (argc == 1)
return usage(argv[0]);
@@ -853,9 +866,9 @@ int main(int argc, char **argv)
in = malloc(sizeof(struct ead_instance));
memset(in, 0, sizeof(struct ead_instance));
INIT_LIST_HEAD(&in->list);
- strncpy(in->name, optarg, sizeof(in->name) - 1);
+ strncpy(in->ifname, optarg, sizeof(in->ifname) - 1);
list_add(&in->list, &instances);
- n_iface++;
+ in->id = n_iface++;
break;
case 'D':
dev_name = optarg;
@@ -902,13 +915,7 @@ int main(int argc, char **argv)
}
/* randomize the mac address */
- fd = open("/dev/urandom", O_RDONLY);
- if (fd < 0) {
- perror("open");
- exit(1);
- }
- read(fd, ethmac + 3, 3);
- close(fd);
+ get_random_bytes(ethmac + 3, 3);
nid = *(((u16_t *) ethmac) + 2);
start_servers(false);
diff --git a/package/ead/src/ead.h b/package/ead/src/ead.h
index 36db0f5529..54505ce28c 100644
--- a/package/ead/src/ead.h
+++ b/package/ead/src/ead.h
@@ -114,12 +114,16 @@ struct ead_msg_encrypted {
#define EAD_DATA(_msg, _type) (&((_msg)->data[0]._type))
#define EAD_ENC_DATA(_msg, _type) (&((_msg)->data[0].enc.data[0]._type))
+/* for ead_msg::sid */
+#define EAD_INSTANCE_MASK 0xf000
+#define EAD_INSTANCE_SHIFT 12
+
struct ead_msg {
uint32_t magic;
uint32_t len;
uint32_t type;
uint16_t nid; /* node id */
- uint16_t tid; /* transaction id */
+ uint16_t sid; /* session id */
uint32_t ip; /* source ip for responses from the server */
union {
struct ead_msg_pong pong;