0
0
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:
Pavel Tvrdík 2016-04-01 09:38:14 +02:00
parent 8de4cfbe13
commit 2ce8589753
4 changed files with 90 additions and 46 deletions

View File

@ -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();
} }

View File

@ -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)

View File

@ -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();

View File

@ -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);
} }