ead: add support for instance ids to prevent interference from packet reception on multiple interfaces
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@13905 3c298f89-4303-0410-b956-a3cf2f4a3e73master
parent
42e5c4f00e
commit
5dc56e36d7
|
@ -62,6 +62,7 @@ static struct t_num *A, B;
|
||||||
static struct t_preconf *tcp;
|
static struct t_preconf *tcp;
|
||||||
static int auth_type = EAD_AUTH_DEFAULT;
|
static int auth_type = EAD_AUTH_DEFAULT;
|
||||||
static int timeout = EAD_TIMEOUT;
|
static int timeout = EAD_TIMEOUT;
|
||||||
|
static uint16_t sid = 0;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_nonblock(int enable)
|
set_nonblock(int enable)
|
||||||
|
@ -157,6 +158,7 @@ handle_pong(void)
|
||||||
auth_type = ntohs(pong->auth_type);
|
auth_type = ntohs(pong->auth_type);
|
||||||
if (nid == 0xffff)
|
if (nid == 0xffff)
|
||||||
printf("%04x: %s\n", ntohs(msg->nid), pong->name);
|
printf("%04x: %s\n", ntohs(msg->nid), pong->name);
|
||||||
|
sid = msg->sid;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,7 +322,7 @@ int main(int argc, char **argv)
|
||||||
int ch;
|
int ch;
|
||||||
|
|
||||||
msg->magic = htonl(EAD_MAGIC);
|
msg->magic = htonl(EAD_MAGIC);
|
||||||
msg->tid = 0;
|
msg->sid = 0;
|
||||||
|
|
||||||
memset(&local, 0, sizeof(local));
|
memset(&local, 0, sizeof(local));
|
||||||
memset(&remote, 0, sizeof(remote));
|
memset(&remote, 0, sizeof(remote));
|
||||||
|
|
|
@ -65,10 +65,20 @@
|
||||||
#define DEBUG(n, format, ...) do {} while(0)
|
#define DEBUG(n, format, ...) do {} while(0)
|
||||||
#endif
|
#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 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 = NULL;
|
||||||
static pcap_t *pcap_fp_rx = NULL;
|
static pcap_t *pcap_fp_rx = NULL;
|
||||||
static const char *ifname = DEFAULT_IFNAME;
|
|
||||||
static char pktbuf_b[PCAP_MRU];
|
static char pktbuf_b[PCAP_MRU];
|
||||||
static struct ead_packet *pktbuf = (struct ead_packet *)pktbuf_b;
|
static struct ead_packet *pktbuf = (struct ead_packet *)pktbuf_b;
|
||||||
static u16_t nid = 0xffff; /* node id */
|
static u16_t nid = 0xffff; /* node id */
|
||||||
|
@ -85,20 +95,7 @@ static unsigned char pw_saltbuf[MAXSALTLEN];
|
||||||
static struct list_head instances;
|
static struct list_head instances;
|
||||||
static const char *dev_name = DEFAULT_DEVNAME;
|
static const char *dev_name = DEFAULT_DEVNAME;
|
||||||
static bool nonfork = false;
|
static bool nonfork = false;
|
||||||
|
static struct ead_instance *instance = NULL;
|
||||||
#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 t_pwent tpe = {
|
static struct t_pwent tpe = {
|
||||||
.name = username,
|
.name = username,
|
||||||
|
@ -113,6 +110,20 @@ static struct t_server *ts = NULL;
|
||||||
static struct t_num A, *B = NULL;
|
static struct t_num A, *B = NULL;
|
||||||
unsigned char *skey;
|
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
|
static bool
|
||||||
prepare_password(void)
|
prepare_password(void)
|
||||||
{
|
{
|
||||||
|
@ -539,6 +550,11 @@ parse_message(struct ead_packet *pkt, int len)
|
||||||
(state != type))
|
(state != type))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if ((type != EAD_TYPE_PING) &&
|
||||||
|
((ntohs(pkt->msg.sid) & EAD_INSTANCE_MASK) >>
|
||||||
|
EAD_INSTANCE_SHIFT) != instance->id)
|
||||||
|
return;
|
||||||
|
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case EAD_TYPE_PING:
|
case EAD_TYPE_PING:
|
||||||
handler = handle_ping;
|
handler = handle_ping;
|
||||||
|
@ -574,6 +590,7 @@ parse_message(struct ead_packet *pkt, int len)
|
||||||
pktbuf->msg.magic = htonl(EAD_MAGIC);
|
pktbuf->msg.magic = htonl(EAD_MAGIC);
|
||||||
pktbuf->msg.type = htonl(type + 1);
|
pktbuf->msg.type = htonl(type + 1);
|
||||||
pktbuf->msg.nid = htons(nid);
|
pktbuf->msg.nid = htons(nid);
|
||||||
|
pktbuf->msg.sid = pkt->msg.sid;
|
||||||
pktbuf->msg.len = 0;
|
pktbuf->msg.len = 0;
|
||||||
|
|
||||||
if (handler(pkt, len, &nstate)) {
|
if (handler(pkt, len, &nstate)) {
|
||||||
|
@ -630,16 +647,16 @@ ead_pcap_reopen(bool first)
|
||||||
|
|
||||||
pcap_fp_rx = NULL;
|
pcap_fp_rx = NULL;
|
||||||
do {
|
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
|
#ifdef linux
|
||||||
if (brname)
|
if (instance->bridge[0])
|
||||||
pcap_fp_rx = pcap_open_live(brname, PCAP_MRU, 1, PCAP_TIMEOUT, errbuf);
|
pcap_fp_rx = pcap_open_live(instance->bridge, PCAP_MRU, 1, PCAP_TIMEOUT, errbuf);
|
||||||
#endif
|
#endif
|
||||||
if (!pcap_fp_rx)
|
if (!pcap_fp_rx)
|
||||||
pcap_fp_rx = pcap_fp;
|
pcap_fp_rx = pcap_fp;
|
||||||
pcap_setfilter(pcap_fp_rx, &pktfilter);
|
pcap_setfilter(pcap_fp_rx, &pktfilter);
|
||||||
if (first && !pcap_fp) {
|
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;
|
first = false;
|
||||||
}
|
}
|
||||||
if (!pcap_fp)
|
if (!pcap_fp)
|
||||||
|
@ -712,12 +729,8 @@ start_server(struct ead_instance *i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
instance = i;
|
||||||
signal(SIGCHLD, instance_handle_sigchld);
|
signal(SIGCHLD, instance_handle_sigchld);
|
||||||
ifname = i->name;
|
|
||||||
#ifdef linux
|
|
||||||
if (i->bridge[0])
|
|
||||||
brname = i->bridge;
|
|
||||||
#endif
|
|
||||||
ead_pcap_reopen(true);
|
ead_pcap_reopen(true);
|
||||||
ead_pktloop();
|
ead_pktloop();
|
||||||
pcap_close(pcap_fp);
|
pcap_close(pcap_fp);
|
||||||
|
@ -779,7 +792,7 @@ check_bridge_port(const char *br, const char *port, void *arg)
|
||||||
list_for_each(p, &instances) {
|
list_for_each(p, &instances) {
|
||||||
in = list_entry(p, struct ead_instance, list);
|
in = list_entry(p, struct ead_instance, list);
|
||||||
|
|
||||||
if (strcmp(in->name, port) != 0)
|
if (strcmp(in->ifname, port) != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
in->br_check = true;
|
in->br_check = true;
|
||||||
|
@ -787,7 +800,7 @@ check_bridge_port(const char *br, const char *port, void *arg)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
strncpy(in->bridge, br, sizeof(in->bridge));
|
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);
|
stop_server(in, false);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -817,7 +830,7 @@ check_all_interfaces(void)
|
||||||
if (in->br_check) {
|
if (in->br_check) {
|
||||||
in->br_check = false;
|
in->br_check = false;
|
||||||
} else if (in->bridge[0]) {
|
} 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;
|
in->bridge[0] = 0;
|
||||||
stop_server(in, false);
|
stop_server(in, false);
|
||||||
}
|
}
|
||||||
|
@ -830,10 +843,10 @@ int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
struct ead_instance *in;
|
struct ead_instance *in;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
int fd, ch;
|
|
||||||
const char *pidfile = NULL;
|
const char *pidfile = NULL;
|
||||||
bool background = false;
|
bool background = false;
|
||||||
int n_iface = 0;
|
int n_iface = 0;
|
||||||
|
int fd, ch;
|
||||||
|
|
||||||
if (argc == 1)
|
if (argc == 1)
|
||||||
return usage(argv[0]);
|
return usage(argv[0]);
|
||||||
|
@ -853,9 +866,9 @@ int main(int argc, char **argv)
|
||||||
in = malloc(sizeof(struct ead_instance));
|
in = malloc(sizeof(struct ead_instance));
|
||||||
memset(in, 0, sizeof(struct ead_instance));
|
memset(in, 0, sizeof(struct ead_instance));
|
||||||
INIT_LIST_HEAD(&in->list);
|
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);
|
list_add(&in->list, &instances);
|
||||||
n_iface++;
|
in->id = n_iface++;
|
||||||
break;
|
break;
|
||||||
case 'D':
|
case 'D':
|
||||||
dev_name = optarg;
|
dev_name = optarg;
|
||||||
|
@ -902,13 +915,7 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* randomize the mac address */
|
/* randomize the mac address */
|
||||||
fd = open("/dev/urandom", O_RDONLY);
|
get_random_bytes(ethmac + 3, 3);
|
||||||
if (fd < 0) {
|
|
||||||
perror("open");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
read(fd, ethmac + 3, 3);
|
|
||||||
close(fd);
|
|
||||||
nid = *(((u16_t *) ethmac) + 2);
|
nid = *(((u16_t *) ethmac) + 2);
|
||||||
|
|
||||||
start_servers(false);
|
start_servers(false);
|
||||||
|
|
|
@ -114,12 +114,16 @@ struct ead_msg_encrypted {
|
||||||
#define EAD_DATA(_msg, _type) (&((_msg)->data[0]._type))
|
#define EAD_DATA(_msg, _type) (&((_msg)->data[0]._type))
|
||||||
#define EAD_ENC_DATA(_msg, _type) (&((_msg)->data[0].enc.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 {
|
struct ead_msg {
|
||||||
uint32_t magic;
|
uint32_t magic;
|
||||||
uint32_t len;
|
uint32_t len;
|
||||||
uint32_t type;
|
uint32_t type;
|
||||||
uint16_t nid; /* node id */
|
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 */
|
uint32_t ip; /* source ip for responses from the server */
|
||||||
union {
|
union {
|
||||||
struct ead_msg_pong pong;
|
struct ead_msg_pong pong;
|
||||||
|
|
Loading…
Reference in New Issue