Commit b4c639d9 authored by Pavel Tvrdík's avatar Pavel Tvrdík
Browse files

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
parent 9d4042a1
Loading
Loading
Loading
Loading

socktest/common.c

0 → 100644
+143 −0
Original line number Diff line number Diff line
#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();
}

socktest/common.h

0 → 100644
+59 −0
Original line number Diff line number Diff line
#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);

socktest/rcv.c

0 → 100644
+59 −0
Original line number Diff line number Diff line
#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);
  }
}

socktest/snd.c

0 → 100644
+45 −0
Original line number Diff line number Diff line
#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);
  }
}
+1 −1
Original line number Diff line number Diff line
@@ -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:
Loading