mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 17:51:53 +00:00
Socktest: initial commit
Using `make sockettest` generetes `snd` and `rcv` binaries. It can be used for testing BIRD's sockets. Based on code by Ondrej Zajicek
This commit is contained in:
parent
9d4042a171
commit
b4c639d9ae
143
socktest/common.c
Normal file
143
socktest/common.c
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
#include "conf/conf.h"
|
||||||
|
#include "nest/locks.h"
|
||||||
|
#include "nest/route.h"
|
||||||
|
#include "lib/krt.h"
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
static void
|
||||||
|
parse_addr(char *src, ip_addr *dst)
|
||||||
|
{
|
||||||
|
if (!ipa_pton(src, dst))
|
||||||
|
{
|
||||||
|
printf("Invalid address %s\n", src);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
parse_int(const char *src, int *dst)
|
||||||
|
{
|
||||||
|
errno = 0;
|
||||||
|
*dst = strtol(src, NULL, 10);
|
||||||
|
if (errno)
|
||||||
|
{
|
||||||
|
printf("Invalid number %s\n", src);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
err_hook(sock *s, int err)
|
||||||
|
{
|
||||||
|
if (!err)
|
||||||
|
{
|
||||||
|
printf("Sock EOF \n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Err(%d): %s \n", err, s->err);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
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);
|
||||||
|
|
||||||
|
if (cf_bcast)
|
||||||
|
sk_setup_broadcast(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
sock *
|
||||||
|
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:";
|
||||||
|
int c;
|
||||||
|
|
||||||
|
cf_value = PKT_VALUE;
|
||||||
|
cf_ttl = 1;
|
||||||
|
uint port = PKT_PORT;
|
||||||
|
|
||||||
|
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)
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case 'u':
|
||||||
|
s->type = SK_UDP;
|
||||||
|
break;
|
||||||
|
case 'm':
|
||||||
|
cf_mcast = 1;
|
||||||
|
if (is_recv)
|
||||||
|
parse_addr(optarg, &s->daddr);
|
||||||
|
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 */
|
||||||
|
break;
|
||||||
|
case 'B':
|
||||||
|
parse_addr(optarg, &s->saddr); /* FIXME: Cannot set local address and bind address together */
|
||||||
|
s->flags |= SKF_BIND;
|
||||||
|
cf_bind = 1;
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
parse_int(optarg, &port);
|
||||||
|
break;
|
||||||
|
case 'v':
|
||||||
|
parse_int(optarg, &cf_value);
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
parse_int(optarg, &cf_ttl);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
goto usage;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_recv && s->type == SK_UDP)
|
||||||
|
s->sport = port;
|
||||||
|
else
|
||||||
|
s->dport = port;
|
||||||
|
|
||||||
|
if (optind + is_send != argc)
|
||||||
|
goto usage;
|
||||||
|
|
||||||
|
if (is_send)
|
||||||
|
parse_addr(argv[optind], &s->daddr);
|
||||||
|
|
||||||
|
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",
|
||||||
|
argv[0], is_recv ? " maddr" : "", is_send ? " daddr" : "");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
bird_init(void)
|
||||||
|
{
|
||||||
|
resource_init();
|
||||||
|
io_init();
|
||||||
|
if_init();
|
||||||
|
}
|
59
socktest/common.h
Normal file
59
socktest/common.h
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
#define _GNU_SOURCE 1
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/uio.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <netinet/tcp.h>
|
||||||
|
#include <netinet/udp.h>
|
||||||
|
#include <netinet/icmp6.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "nest/bird.h"
|
||||||
|
#include "lib/lists.h"
|
||||||
|
#include "lib/resource.h"
|
||||||
|
#include "lib/timer.h"
|
||||||
|
#include "lib/socket.h"
|
||||||
|
#include "lib/event.h"
|
||||||
|
#include "lib/string.h"
|
||||||
|
#include "nest/iface.h"
|
||||||
|
#include "lib/string.h"
|
||||||
|
|
||||||
|
#include "lib/unix.h"
|
||||||
|
|
||||||
|
|
||||||
|
//#define PKT_MAGIC 0x12345678
|
||||||
|
#define PKT_MAGIC 42
|
||||||
|
|
||||||
|
#define PKT_PORT 100
|
||||||
|
#define PKT_VALUE 0
|
||||||
|
|
||||||
|
struct my_packet
|
||||||
|
{
|
||||||
|
u32 magic;
|
||||||
|
u32 value;
|
||||||
|
u32 count;
|
||||||
|
};
|
||||||
|
|
||||||
|
int cf_mcast, cf_bcast, cf_bind, cf_route;
|
||||||
|
uint cf_value;
|
||||||
|
uint cf_ttl;
|
||||||
|
|
||||||
|
#define SKT_ERR(x) do { perror(x); exit(-1); } while(0)
|
||||||
|
|
||||||
|
sock *skt_parse_args(int argc, char **argv, int is_send);
|
||||||
|
void bird_init(void);
|
||||||
|
void skt_open(sock *s);
|
||||||
|
|
||||||
|
/* implementation in io.c */
|
||||||
|
int sk_write(sock *s);
|
||||||
|
int sk_read(sock *s);
|
59
socktest/rcv.c
Normal file
59
socktest/rcv.c
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
rcv_hook(sock *sk, int size)
|
||||||
|
{
|
||||||
|
struct my_packet *raw;
|
||||||
|
if (sk->type == SK_IP)
|
||||||
|
raw = (void *) sk_rx_buffer(sk, &size);
|
||||||
|
else
|
||||||
|
raw = (void *) sk->rbuf;
|
||||||
|
|
||||||
|
if (size != sizeof(struct my_packet))
|
||||||
|
{
|
||||||
|
printf("Bad size of rcv packet %d \n", size);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct my_packet pkt = {
|
||||||
|
.magic = ntohl(raw->magic),
|
||||||
|
.value = ntohl(raw->value),
|
||||||
|
.count = ntohl(raw->count),
|
||||||
|
};
|
||||||
|
|
||||||
|
char *ifa_name = if_find_by_index(sk->lifindex) ? if_find_by_index(sk->lifindex)->name : "UNKNOWN";
|
||||||
|
|
||||||
|
char buf[1024];
|
||||||
|
|
||||||
|
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);
|
||||||
|
else
|
||||||
|
bsnprintf(pos, pos-buf, "recv foreign of len %d", size);
|
||||||
|
|
||||||
|
printf("%s\n", buf);
|
||||||
|
|
||||||
|
return 1; /* clear buffer */
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
bird_init();
|
||||||
|
|
||||||
|
sock *s = skt_parse_args(argc, argv, 0);
|
||||||
|
s->rx_hook = rcv_hook;
|
||||||
|
s->rbsize = 1500;
|
||||||
|
s->flags |= SKF_LADDR_RX | SKF_TTL_RX | SKF_PKTINFO;
|
||||||
|
|
||||||
|
skt_open(s);
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
sk_read(s);
|
||||||
|
usleep(20000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
45
socktest/snd.c
Normal file
45
socktest/snd.c
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
do_sendmsg(sock *s, void *pkt, size_t len)
|
||||||
|
{
|
||||||
|
memcpy(s->ttx, pkt, len);
|
||||||
|
s->tpos = s->ttx + len;
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
bird_init();
|
||||||
|
|
||||||
|
sock *s = skt_parse_args(argc, argv, 1);
|
||||||
|
s->tx_hook = connected_hook;
|
||||||
|
s->tbsize = 1500;
|
||||||
|
s->tos = IP_PREC_INTERNET_CONTROL;
|
||||||
|
|
||||||
|
skt_open(s);
|
||||||
|
|
||||||
|
struct my_packet pkt = {
|
||||||
|
.magic = htonl(PKT_MAGIC),
|
||||||
|
.value = htonl(cf_value),
|
||||||
|
};
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
pkt.count = htonl(count);
|
||||||
|
do_sendmsg(s, &pkt, sizeof(pkt));
|
||||||
|
count++;
|
||||||
|
|
||||||
|
usleep(200000);
|
||||||
|
}
|
||||||
|
}
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
objdir=@objdir@
|
objdir=@objdir@
|
||||||
|
|
||||||
all depend tags install install-docs tests:
|
all depend tags install install-docs tests sockettest:
|
||||||
$(MAKE) -C $(objdir) $@
|
$(MAKE) -C $(objdir) $@
|
||||||
|
|
||||||
docs userdocs progdocs:
|
docs userdocs progdocs:
|
||||||
|
@ -5,7 +5,7 @@ root-rel=./
|
|||||||
|
|
||||||
include Rules
|
include Rules
|
||||||
|
|
||||||
.PHONY: all daemon birdc birdcl subdir depend clean distclean tags docs userdocs progdocs
|
.PHONY: all daemon birdc birdcl subdir depend clean distclean tags docs userdocs progdocs sockettest
|
||||||
|
|
||||||
all: sysdep/paths.h .dep-stamp subdir lib/main.o daemon birdcl @CLIENT@
|
all: sysdep/paths.h .dep-stamp subdir lib/main.o daemon birdcl @CLIENT@
|
||||||
|
|
||||||
@ -29,6 +29,8 @@ birdc: $(exedir)/birdc
|
|||||||
|
|
||||||
birdcl: $(exedir)/birdcl
|
birdcl: $(exedir)/birdcl
|
||||||
|
|
||||||
|
sockettest: $(exedir)/snd $(exedir)/rcv
|
||||||
|
|
||||||
bird-dep := $(addsuffix /all.o, $(static-dirs)) conf/all.o lib/birdlib.a
|
bird-dep := $(addsuffix /all.o, $(static-dirs)) conf/all.o lib/birdlib.a
|
||||||
|
|
||||||
$(bird-dep): sysdep/paths.h .dep-stamp subdir
|
$(bird-dep): sysdep/paths.h .dep-stamp subdir
|
||||||
@ -41,16 +43,20 @@ birdcl-dep := client/birdcl.o client/all.o lib/birdlib.a
|
|||||||
|
|
||||||
$(birdcl-dep): sysdep/paths.h .dep-stamp subdir
|
$(birdcl-dep): sysdep/paths.h .dep-stamp subdir
|
||||||
|
|
||||||
|
socktest-dep := socktest/common.o $(addsuffix /all.o, $(static-dirs)) conf/all.o lib/birdlib.a
|
||||||
|
|
||||||
|
$(socktest-dep): sysdep/paths.h .dep-stamp
|
||||||
|
|
||||||
|
|
||||||
export client := @CLIENT@
|
export client := @CLIENT@
|
||||||
|
|
||||||
depend: sysdep/paths.h .dir-stamp
|
depend: sysdep/paths.h .dir-stamp
|
||||||
set -e ; for a in $(dynamic-dirs) ; do $(MAKE) -C $$a $@ ; done
|
set -e ; for a in $(dynamic-dirs) ; do $(MAKE) -C $$a $@ ; done
|
||||||
set -e ; for a in $(static-dirs) $(client-dirs) ; do $(MAKE) -C $$a -f $(srcdir_abs)/$$a/Makefile $@ ; done
|
set -e ; for a in $(static-dirs) $(client-dirs) $(socktest-dirs) ; do $(MAKE) -C $$a -f $(srcdir_abs)/$$a/Makefile $@ ; done
|
||||||
|
|
||||||
subdir: sysdep/paths.h .dir-stamp .dep-stamp
|
subdir: sysdep/paths.h .dir-stamp .dep-stamp
|
||||||
set -e ; for a in $(dynamic-dirs) ; do $(MAKE) -C $$a $@ ; done
|
set -e ; for a in $(dynamic-dirs) ; do $(MAKE) -C $$a $@ ; done
|
||||||
set -e ; for a in $(static-dirs) $(client-dirs) ; do $(MAKE) -C $$a -f $(srcdir_abs)/$$a/Makefile $@ ; done
|
set -e ; for a in $(static-dirs) $(client-dirs) $(socktest-dirs) ; do $(MAKE) -C $$a -f $(srcdir_abs)/$$a/Makefile $@ ; done
|
||||||
|
|
||||||
$(exedir)/bird: $(bird-dep) lib/main.o
|
$(exedir)/bird: $(bird-dep) lib/main.o
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
|
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||||
@ -63,8 +69,16 @@ $(exedir)/birdcl: $(birdcl-dep)
|
|||||||
@echo LD $(LDFLAGS) -o $@ $^ $(LIBS)
|
@echo LD $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||||
@$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
|
@$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||||
|
|
||||||
|
$(exedir)/snd: $(socktest-dep) socktest/snd.o
|
||||||
|
@echo LD $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||||
|
@$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||||
|
|
||||||
|
$(exedir)/rcv: $(socktest-dep) socktest/rcv.o
|
||||||
|
@echo LD $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||||
|
@$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||||
|
|
||||||
.dir-stamp: sysdep/paths.h
|
.dir-stamp: sysdep/paths.h
|
||||||
mkdir -p $(static-dirs) $(client-dirs) $(doc-dirs)
|
mkdir -p $(static-dirs) $(client-dirs) $(doc-dirs) $(socktest-dirs)
|
||||||
touch .dir-stamp
|
touch .dir-stamp
|
||||||
|
|
||||||
.dep-stamp:
|
.dep-stamp:
|
||||||
@ -83,7 +97,7 @@ sysdep/paths.h:
|
|||||||
if test -n "@iproutedir@" ; then echo >>sysdep/paths.h "#define PATH_IPROUTE_DIR \"@iproutedir@\"" ; fi
|
if test -n "@iproutedir@" ; then echo >>sysdep/paths.h "#define PATH_IPROUTE_DIR \"@iproutedir@\"" ; fi
|
||||||
|
|
||||||
tags:
|
tags:
|
||||||
cd $(srcdir) ; etags -lc `find $(static-dirs) $(addprefix $(objdir)/,$(dynamic-dirs)) $(client-dirs) -name *.[chY]`
|
cd $(srcdir) ; etags -lc `find $(static-dirs) $(addprefix $(objdir)/,$(dynamic-dirs)) $(client-dirs) $(socktest-dirs) -name *.[chY]`
|
||||||
|
|
||||||
install: all
|
install: all
|
||||||
$(INSTALL) -d $(DESTDIR)/$(sbindir) $(DESTDIR)/$(sysconfdir) $(DESTDIR)/@runtimedir@
|
$(INSTALL) -d $(DESTDIR)/$(sbindir) $(DESTDIR)/$(sysconfdir) $(DESTDIR)/@runtimedir@
|
||||||
|
@ -15,8 +15,10 @@ client-dirs := client
|
|||||||
client-dir-paths := $(client-dirs)
|
client-dir-paths := $(client-dirs)
|
||||||
doc-dirs := doc
|
doc-dirs := doc
|
||||||
doc-dir-paths := $(doc-dirs)
|
doc-dir-paths := $(doc-dirs)
|
||||||
|
socktest-dirs := socktest
|
||||||
|
socktest-dir-paths := $(socktest-dirs)
|
||||||
|
|
||||||
all-dirs:=$(static-dirs) $(dynamic-dirs) $(client-dirs) $(doc-dirs)
|
all-dirs:=$(static-dirs) $(dynamic-dirs) $(client-dirs) $(doc-dirs) $(socktest-dirs)
|
||||||
clean-dirs:=$(all-dirs) proto sysdep
|
clean-dirs:=$(all-dirs) proto sysdep
|
||||||
|
|
||||||
CPPFLAGS=-I$(root-rel) -I$(srcdir) @CPPFLAGS@
|
CPPFLAGS=-I$(root-rel) -I$(srcdir) @CPPFLAGS@
|
||||||
|
Loading…
Reference in New Issue
Block a user