mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2025-01-05 16:41:53 +00:00
Socktest: Fixing bugs
Changes: - Remove -R command line option (it's automatic, system dependent) - Fix mixing of broadcast and binding - Add -c command line option for count of packet - Fix receiving broadcast - Scan all interfaces via device protocol (unfortunately it is ugly)
This commit is contained in:
parent
8de4cfbe13
commit
2ce8589753
@ -5,26 +5,29 @@
|
|||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
static void
|
static ip_addr
|
||||||
parse_addr(char *src, ip_addr *dst)
|
parse_addr(char *src)
|
||||||
{
|
{
|
||||||
if (!ipa_pton(src, dst))
|
ip_addr dst;
|
||||||
|
if (!ipa_pton(src, &dst))
|
||||||
{
|
{
|
||||||
printf("Invalid address %s\n", src);
|
printf("Invalid address %s\n", src);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static uint
|
||||||
parse_int(const char *src, int *dst)
|
parse_uint(const char *src)
|
||||||
{
|
{
|
||||||
errno = 0;
|
errno = 0;
|
||||||
*dst = strtol(src, NULL, 10);
|
uint dst = strtoul(src, NULL, 10);
|
||||||
if (errno)
|
if (errno)
|
||||||
{
|
{
|
||||||
printf("Invalid number %s\n", src);
|
printf("Invalid number %s\n", src);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -46,31 +49,34 @@ skt_open(sock *s)
|
|||||||
if (sk_open(s) < 0)
|
if (sk_open(s) < 0)
|
||||||
SKT_ERR(s->err);
|
SKT_ERR(s->err);
|
||||||
|
|
||||||
sk_set_ttl(s, cf_ttl);
|
|
||||||
|
|
||||||
if (cf_mcast)
|
if (cf_mcast)
|
||||||
sk_setup_multicast(s);
|
{
|
||||||
|
sk_setup_multicast(s); /* transmission */
|
||||||
|
sk_join_group(s, s->daddr); /* reception */
|
||||||
|
}
|
||||||
|
|
||||||
|
sk_set_ttl(s, cf_ttl);
|
||||||
|
|
||||||
if (cf_bcast)
|
if (cf_bcast)
|
||||||
sk_setup_broadcast(s);
|
sk_setup_broadcast(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
sock *
|
sock *
|
||||||
skt_parse_args(int argc, char **argv, int is_send)
|
skt_parse_args(int argc, char *argv[], int is_send)
|
||||||
{
|
{
|
||||||
int is_recv = !is_send;
|
int is_recv = !is_send;
|
||||||
const char *opt_list = is_send ? "umbRi:l:B:p:v:t:" : "um:bRi:l:B:p:v:t:";
|
const char *opt_list = is_send ? "buBmi:l:p:v:t:c:" : "buBm:i:l:p:v:t:c:";
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
|
/* Set defaults */
|
||||||
|
uint port = PKT_PORT;
|
||||||
cf_value = PKT_VALUE;
|
cf_value = PKT_VALUE;
|
||||||
cf_ttl = 1;
|
cf_ttl = 1;
|
||||||
uint port = PKT_PORT;
|
cf_mcast = cf_bcast = cf_bind = cf_count = counter = 0;
|
||||||
|
|
||||||
|
/* Create socket */
|
||||||
sock *s = sk_new(&root_pool);
|
sock *s = sk_new(&root_pool);
|
||||||
|
|
||||||
/* Raw socket is default type */
|
|
||||||
s->type = SK_IP;
|
s->type = SK_IP;
|
||||||
|
|
||||||
s->err_hook = err_hook;
|
s->err_hook = err_hook;
|
||||||
|
|
||||||
while ((c = getopt(argc, argv, opt_list)) >= 0)
|
while ((c = getopt(argc, argv, opt_list)) >= 0)
|
||||||
@ -79,43 +85,45 @@ skt_parse_args(int argc, char **argv, int is_send)
|
|||||||
case 'u':
|
case 'u':
|
||||||
s->type = SK_UDP;
|
s->type = SK_UDP;
|
||||||
break;
|
break;
|
||||||
|
case 'c':
|
||||||
|
cf_count = parse_uint(optarg);
|
||||||
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
cf_mcast = 1;
|
cf_mcast = 1;
|
||||||
if (is_recv)
|
if (is_recv)
|
||||||
parse_addr(optarg, &s->daddr);
|
s->daddr = parse_addr(optarg);
|
||||||
break;
|
break;
|
||||||
case 'b':
|
case 'b':
|
||||||
cf_bcast = 1;
|
cf_bcast = 1;
|
||||||
break;
|
break;
|
||||||
case 'R':
|
|
||||||
cf_route = 1;
|
|
||||||
break;
|
|
||||||
case 'i':
|
case 'i':
|
||||||
s->iface = if_get_by_name(optarg);
|
s->iface = if_get_by_name(optarg);
|
||||||
break;
|
s->iface->index = if_nametoindex(optarg);
|
||||||
case 'l':
|
|
||||||
parse_addr(optarg, &s->saddr); /* FIXME: Cannot set local address and bind address together */
|
|
||||||
break;
|
break;
|
||||||
case 'B':
|
case 'B':
|
||||||
parse_addr(optarg, &s->saddr); /* FIXME: Cannot set local address and bind address together */
|
|
||||||
s->flags |= SKF_BIND;
|
|
||||||
cf_bind = 1;
|
cf_bind = 1;
|
||||||
|
s->flags |= SKF_BIND;
|
||||||
|
/* fall through */
|
||||||
|
case 'l':
|
||||||
|
if (ipa_nonzero(s->saddr))
|
||||||
|
printf("Redefine source address, don't use -l and -B together \n");
|
||||||
|
s->saddr = parse_addr(optarg);
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
parse_int(optarg, &port);
|
port = parse_uint(optarg);
|
||||||
break;
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
parse_int(optarg, &cf_value);
|
cf_value = parse_uint(optarg);
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
parse_int(optarg, &cf_ttl);
|
cf_ttl = parse_uint(optarg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
goto usage;
|
goto usage;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_recv && s->type == SK_UDP)
|
if (is_recv && s->type == SK_UDP) /* XXX: Weird */
|
||||||
s->sport = port;
|
s->sport = port;
|
||||||
else
|
else
|
||||||
s->dport = port;
|
s->dport = port;
|
||||||
@ -124,20 +132,42 @@ skt_parse_args(int argc, char **argv, int is_send)
|
|||||||
goto usage;
|
goto usage;
|
||||||
|
|
||||||
if (is_send)
|
if (is_send)
|
||||||
parse_addr(argv[optind], &s->daddr);
|
s->daddr = parse_addr(argv[optind]);
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
|
|
||||||
usage:
|
usage:
|
||||||
printf("Usage: %s [-u] [-m%s|-b] [-B baddr] [-R] [-i iface] [-l addr] [-p port] [-v value] [-t ttl]%s\n",
|
printf("Usage: %s [-u] [-c count] [-m%s|-b] [-B bind_addr] [-i iface] [-l fake_local_addr] [-p port] [-v value] [-t ttl]%s\n",
|
||||||
argv[0], is_recv ? " maddr" : "", is_send ? " daddr" : "");
|
argv[0], is_recv ? " maddr" : "", is_send ? " daddr" : "");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
scan_infaces(void)
|
||||||
|
{
|
||||||
|
/* create mockup config */
|
||||||
|
struct config *c = config_alloc("mockup");
|
||||||
|
init_list(&c->protos);
|
||||||
|
cfg_mem = c->mem;
|
||||||
|
new_config = c;
|
||||||
|
new_config->master_rtc = mb_allocz(&root_pool, sizeof(struct rtable_config));
|
||||||
|
|
||||||
|
/* create mockup device protocol */
|
||||||
|
protos_build();
|
||||||
|
proto_build(&proto_unix_iface);
|
||||||
|
struct proto_config *kif_config = kif_init_config(SYM_PROTO);
|
||||||
|
kif_config->table = new_config->master_rtc;
|
||||||
|
struct proto *krt = proto_unix_iface.init(kif_config);
|
||||||
|
|
||||||
|
/* scan interfaces */
|
||||||
|
proto_unix_iface.start(krt);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
bird_init(void)
|
bird_init(void)
|
||||||
{
|
{
|
||||||
resource_init();
|
resource_init();
|
||||||
io_init();
|
io_init();
|
||||||
if_init();
|
if_init();
|
||||||
|
scan_infaces();
|
||||||
}
|
}
|
||||||
|
@ -44,8 +44,12 @@ struct my_packet
|
|||||||
u32 count;
|
u32 count;
|
||||||
};
|
};
|
||||||
|
|
||||||
int cf_mcast, cf_bcast, cf_bind, cf_route;
|
int cf_mcast; /* Set up multicast */
|
||||||
uint cf_value;
|
int cf_bcast; /* Enable broadcast */
|
||||||
|
int cf_bind; /* Bind by address */
|
||||||
|
uint cf_count; /* How many packets send */
|
||||||
|
uint counter; /* global counter of send/recv packets */
|
||||||
|
uint cf_value; /* a value in packet */
|
||||||
uint cf_ttl;
|
uint cf_ttl;
|
||||||
|
|
||||||
#define SKT_ERR(x) do { perror(x); exit(-1); } while(0)
|
#define SKT_ERR(x) do { perror(x); exit(-1); } while(0)
|
||||||
|
@ -4,6 +4,12 @@ int
|
|||||||
rcv_hook(sock *sk, int size)
|
rcv_hook(sock *sk, int size)
|
||||||
{
|
{
|
||||||
struct my_packet *raw;
|
struct my_packet *raw;
|
||||||
|
char ifa_name[IF_NAMESIZE];
|
||||||
|
char buf[1024];
|
||||||
|
|
||||||
|
if (cf_count && ++counter > cf_count)
|
||||||
|
exit(0);
|
||||||
|
|
||||||
if (sk->type == SK_IP)
|
if (sk->type == SK_IP)
|
||||||
raw = (void *) sk_rx_buffer(sk, &size);
|
raw = (void *) sk_rx_buffer(sk, &size);
|
||||||
else
|
else
|
||||||
@ -11,7 +17,7 @@ rcv_hook(sock *sk, int size)
|
|||||||
|
|
||||||
if (size != sizeof(struct my_packet))
|
if (size != sizeof(struct my_packet))
|
||||||
{
|
{
|
||||||
printf("Bad size of rcv packet %d \n", size);
|
printf("Received a packet with unexpected length of %d bytes \n", size);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -21,25 +27,27 @@ rcv_hook(sock *sk, int size)
|
|||||||
.count = ntohl(raw->count),
|
.count = ntohl(raw->count),
|
||||||
};
|
};
|
||||||
|
|
||||||
char *ifa_name = if_find_by_index(sk->lifindex) ? if_find_by_index(sk->lifindex)->name : "UNKNOWN";
|
if (!if_indextoname(sk->lifindex, ifa_name))
|
||||||
|
{
|
||||||
|
perror("if_indextoname");
|
||||||
|
snprintf(ifa_name, sizeof(ifa_name), "???");
|
||||||
|
}
|
||||||
|
|
||||||
char buf[1024];
|
bsnprintf(buf, sizeof(buf), "%I:%u -> %I ifa(%u) %s: ", sk->faddr, sk->fport, sk->laddr, sk->lifindex, ifa_name);
|
||||||
|
|
||||||
bsnprintf(buf, sizeof(buf), "%I:%u -> %I ifa%u %s: ", sk->faddr, sk->fport, sk->laddr, sk->lifindex, ifa_name);
|
|
||||||
char *pos = buf + strlen(buf);
|
char *pos = buf + strlen(buf);
|
||||||
|
|
||||||
if (pkt.magic == (u32)PKT_MAGIC)
|
if (pkt.magic == (u32)PKT_MAGIC)
|
||||||
bsnprintf(pos, pos-buf, "pkt %d/%d, ttl %d", pkt.value, pkt.count, sk->ttl);
|
bsnprintf(pos, pos-buf, "pkt %d/%d, ttl %d", pkt.value, pkt.count, sk->rcv_ttl);
|
||||||
else
|
else
|
||||||
bsnprintf(pos, pos-buf, "recv foreign of len %d", size);
|
bsnprintf(pos, pos-buf, "magic value does not pass: recv %u, expected %u", pkt.magic, (u32)PKT_MAGIC);
|
||||||
|
|
||||||
printf("%s\n", buf);
|
printf("%s\n", buf);
|
||||||
|
|
||||||
return 1; /* clear buffer */
|
/* Clear receive buffer */
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
bird_init();
|
bird_init();
|
||||||
|
|
||||||
|
@ -5,19 +5,22 @@ do_sendmsg(sock *s, void *pkt, size_t len)
|
|||||||
{
|
{
|
||||||
memcpy(s->ttx, pkt, len);
|
memcpy(s->ttx, pkt, len);
|
||||||
s->tpos = s->ttx + len;
|
s->tpos = s->ttx + len;
|
||||||
|
|
||||||
|
if (cf_count && ++counter > cf_count)
|
||||||
|
exit(0);
|
||||||
|
|
||||||
return sk_write(s);
|
return sk_write(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
connected_hook(sock *s)
|
connected_hook(sock *s)
|
||||||
{
|
{
|
||||||
printf("Iface %s \n", s->iface->name, s->iface->addr);
|
|
||||||
printf("Start sending...\n");
|
printf("Start sending...\n");
|
||||||
s->tx_hook = NULL;
|
s->tx_hook = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
bird_init();
|
bird_init();
|
||||||
|
|
||||||
@ -36,9 +39,8 @@ main(int argc, char **argv)
|
|||||||
int count = 0;
|
int count = 0;
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
pkt.count = htonl(count);
|
pkt.count = htonl(++count);
|
||||||
do_sendmsg(s, &pkt, sizeof(pkt));
|
do_sendmsg(s, &pkt, sizeof(pkt));
|
||||||
count++;
|
|
||||||
|
|
||||||
usleep(200000);
|
usleep(200000);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user