#include "conf/conf.h" #include "nest/locks.h" #include "nest/route.h" #include "lib/krt.h" #include "common.h" static ip_addr parse_addr(char *src) { ip_addr dst; if (!ipa_pton(src, &dst)) { printf("Invalid address %s\n", src); exit(-1); } return dst; } static uint parse_uint(const char *src) { errno = 0; uint dst = strtoul(src, NULL, 10); if (errno) { printf("Invalid number %s\n", src); exit(-1); } return dst; } 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); if (cf_mcast) { 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) { int is_recv = !is_send; 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; cf_mcast = cf_bcast = cf_bind = cf_count = counter = 0; /* Create socket */ sock *s = sk_new(&root_pool); 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 'c': cf_count = parse_uint(optarg); break; case 'm': cf_mcast = 1; if (is_recv) s->daddr = parse_addr(optarg); break; case 'b': cf_bcast = 1; break; case 'i': s->iface = if_get_by_name(optarg); s->iface->index = if_nametoindex(optarg); break; case 'B': 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': port = parse_uint(optarg); break; case 'v': cf_value = parse_uint(optarg); break; case 't': cf_ttl = parse_uint(optarg); break; default: goto usage; } if (is_recv && s->type == SK_UDP) /* XXX: Weird */ s->sport = port; else s->dport = port; if (optind + is_send != argc) goto usage; if (is_send) s->daddr = parse_addr(argv[optind]); return s; usage: 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(); }