]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Socktest: initial commit
authorPavel Tvrdík <pawel.tvrdik@gmail.com>
Tue, 29 Mar 2016 06:24:54 +0000 (08:24 +0200)
committerPavel Tvrdík <pawel.tvrdik@gmail.com>
Wed, 30 Mar 2016 15:16:12 +0000 (17:16 +0200)
Using `make sockettest` generetes `snd` and `rcv` binaries. It can be
used for testing BIRD's sockets.

Based on code by Ondrej Zajicek

socktest/common.c [new file with mode: 0644]
socktest/common.h [new file with mode: 0644]
socktest/rcv.c [new file with mode: 0644]
socktest/snd.c [new file with mode: 0644]
tools/Makefile-top.in
tools/Makefile.in
tools/Rules.in

diff --git a/socktest/common.c b/socktest/common.c
new file mode 100644 (file)
index 0000000..bc29fe4
--- /dev/null
@@ -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();
+}
diff --git a/socktest/common.h b/socktest/common.h
new file mode 100644 (file)
index 0000000..ea18109
--- /dev/null
@@ -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);
diff --git a/socktest/rcv.c b/socktest/rcv.c
new file mode 100644 (file)
index 0000000..e4d01a9
--- /dev/null
@@ -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);
+  }
+}
+
diff --git a/socktest/snd.c b/socktest/snd.c
new file mode 100644 (file)
index 0000000..6b3845b
--- /dev/null
@@ -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);
+  }
+}
index d37931e711a637be452b9144e09988c2d95e84dc..8d6fb9841f69c0cf1b7093ac3ed54abc0ea52477 100644 (file)
@@ -3,7 +3,7 @@
 
 objdir=@objdir@
 
-all depend tags install install-docs tests:
+all depend tags install install-docs tests sockettest:
        $(MAKE) -C $(objdir) $@
 
 docs userdocs progdocs:
index 46c7d11265e6f469d5beff05c72888e932aeb8f4..fe6fc480090744a553d898e6c0fa2b2d9fed8fe9 100644 (file)
@@ -5,7 +5,7 @@ root-rel=./
 
 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@
 
@@ -29,6 +29,8 @@ birdc: $(exedir)/birdc
 
 birdcl: $(exedir)/birdcl
 
+sockettest: $(exedir)/snd $(exedir)/rcv
+
 bird-dep := $(addsuffix /all.o, $(static-dirs)) conf/all.o lib/birdlib.a
 
 $(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
 
+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@
 
 depend: sysdep/paths.h .dir-stamp
        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
        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
        $(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
@@ -63,8 +69,16 @@ $(exedir)/birdcl: $(birdcl-dep)
        @echo LD $(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
-       mkdir -p $(static-dirs) $(client-dirs) $(doc-dirs)
+       mkdir -p $(static-dirs) $(client-dirs) $(doc-dirs)  $(socktest-dirs)
        touch .dir-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
 
 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) -d $(DESTDIR)/$(sbindir) $(DESTDIR)/$(sysconfdir) $(DESTDIR)/@runtimedir@
index f2d2dd0bb7c0f8f5951179cfa67ce4269400d1a8..23646a73449808427fdd2678e16c93b561c063b8 100644 (file)
@@ -15,8 +15,10 @@ client-dirs := client
 client-dir-paths := $(client-dirs)
 doc-dirs := doc
 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
 
 CPPFLAGS=-I$(root-rel) -I$(srcdir) @CPPFLAGS@