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

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)
parent 8de4cfbe
Loading
Loading
Loading
Loading
+60 −30
Original line number Diff line number Diff line
@@ -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();
}
+6 −2
Original line number Diff line number Diff line
@@ -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)
+18 −10
Original line number Diff line number Diff line
@@ -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";

  char buf[1024];
  if (!if_indextoname(sk->lifindex, ifa_name))
  {
    perror("if_indextoname");
    snprintf(ifa_name, sizeof(ifa_name), "???");
  }

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

+6 −4
Original line number Diff line number Diff line
@@ -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);
  }