From 2ce85897534df5004b0e15b57abad4992b732a6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Tvrd=C3=ADk?= Date: Fri, 1 Apr 2016 09:38:14 +0200 Subject: [PATCH] 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) --- socktest/common.c | 90 +++++++++++++++++++++++++++++++---------------- socktest/common.h | 8 +++-- socktest/rcv.c | 28 +++++++++------ socktest/snd.c | 10 +++--- 4 files changed, 90 insertions(+), 46 deletions(-) diff --git a/socktest/common.c b/socktest/common.c index bc29fe46..854fda40 100644 --- a/socktest/common.c +++ b/socktest/common.c @@ -5,26 +5,29 @@ #include "common.h" -static void -parse_addr(char *src, ip_addr *dst) +static ip_addr +parse_addr(char *src) { - if (!ipa_pton(src, dst)) + ip_addr dst; + if (!ipa_pton(src, &dst)) { printf("Invalid address %s\n", src); exit(-1); } + return dst; } -static void -parse_int(const char *src, int *dst) +static uint +parse_uint(const char *src) { errno = 0; - *dst = strtol(src, NULL, 10); + uint dst = strtoul(src, NULL, 10); if (errno) { printf("Invalid number %s\n", src); exit(-1); } + return dst; } void @@ -46,31 +49,34 @@ skt_open(sock *s) if (sk_open(s) < 0) SKT_ERR(s->err); - sk_set_ttl(s, cf_ttl); - 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) sk_setup_broadcast(s); } 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; - 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; + /* Set defaults */ + uint port = PKT_PORT; cf_value = PKT_VALUE; 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); - - /* Raw socket is default type */ s->type = SK_IP; - s->err_hook = err_hook; while ((c = getopt(argc, argv, opt_list)) >= 0) @@ -79,43 +85,45 @@ skt_parse_args(int argc, char **argv, int is_send) case 'u': s->type = SK_UDP; break; + case 'c': + cf_count = parse_uint(optarg); + break; case 'm': cf_mcast = 1; if (is_recv) - parse_addr(optarg, &s->daddr); + s->daddr = parse_addr(optarg); break; case 'b': cf_bcast = 1; break; - case 'R': - cf_route = 1; - break; case 'i': s->iface = if_get_by_name(optarg); - break; - case 'l': - parse_addr(optarg, &s->saddr); /* FIXME: Cannot set local address and bind address together */ + s->iface->index = if_nametoindex(optarg); break; case 'B': - parse_addr(optarg, &s->saddr); /* FIXME: Cannot set local address and bind address together */ - s->flags |= SKF_BIND; 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; case 'p': - parse_int(optarg, &port); + port = parse_uint(optarg); break; case 'v': - parse_int(optarg, &cf_value); + cf_value = parse_uint(optarg); break; case 't': - parse_int(optarg, &cf_ttl); + cf_ttl = parse_uint(optarg); break; default: goto usage; } - if (is_recv && s->type == SK_UDP) + if (is_recv && s->type == SK_UDP) /* XXX: Weird */ s->sport = port; else s->dport = port; @@ -124,20 +132,42 @@ skt_parse_args(int argc, char **argv, int is_send) goto usage; if (is_send) - parse_addr(argv[optind], &s->daddr); + s->daddr = parse_addr(argv[optind]); return s; 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" : ""); 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 bird_init(void) { resource_init(); io_init(); if_init(); + scan_infaces(); } diff --git a/socktest/common.h b/socktest/common.h index ea181093..ff92908f 100644 --- a/socktest/common.h +++ b/socktest/common.h @@ -44,8 +44,12 @@ struct my_packet u32 count; }; -int cf_mcast, cf_bcast, cf_bind, cf_route; -uint cf_value; +int cf_mcast; /* Set up multicast */ +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; #define SKT_ERR(x) do { perror(x); exit(-1); } while(0) diff --git a/socktest/rcv.c b/socktest/rcv.c index e4d01a96..c0c04d63 100644 --- a/socktest/rcv.c +++ b/socktest/rcv.c @@ -4,6 +4,12 @@ int rcv_hook(sock *sk, int size) { 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) raw = (void *) sk_rx_buffer(sk, &size); else @@ -11,7 +17,7 @@ rcv_hook(sock *sk, int size) 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; } @@ -21,25 +27,27 @@ rcv_hook(sock *sk, int size) .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); - 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 - 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); - return 1; /* clear buffer */ + /* Clear receive buffer */ + return 1; } int -main(int argc, char **argv) +main(int argc, char *argv[]) { bird_init(); diff --git a/socktest/snd.c b/socktest/snd.c index 6b3845bb..3d866849 100644 --- a/socktest/snd.c +++ b/socktest/snd.c @@ -5,19 +5,22 @@ do_sendmsg(sock *s, void *pkt, size_t len) { memcpy(s->ttx, pkt, len); s->tpos = s->ttx + len; + + if (cf_count && ++counter > cf_count) + exit(0); + return sk_write(s); } void connected_hook(sock *s) { - printf("Iface %s \n", s->iface->name, s->iface->addr); printf("Start sending...\n"); s->tx_hook = NULL; } int -main(int argc, char **argv) +main(int argc, char *argv[]) { bird_init(); @@ -36,9 +39,8 @@ main(int argc, char **argv) int count = 0; while (1) { - pkt.count = htonl(count); + pkt.count = htonl(++count); do_sendmsg(s, &pkt, sizeof(pkt)); - count++; usleep(200000); }