Ejemplo n.º 1
0
int do_ipl2tp(int argc, char **argv)
{
	if (genl_family < 0) {
		if (rtnl_open_byproto(&genl_rth, 0, NETLINK_GENERIC) < 0) {
			fprintf(stderr, "Cannot open generic netlink socket\n");
			exit(1);
		}

		genl_family = genl_resolve_family(&genl_rth, L2TP_GENL_NAME);
		if (genl_family < 0)
			exit(1);
	}

	if (argc < 1)
		usage();

	if (matches(*argv, "add") == 0)
		return do_add(argc-1, argv+1);
	if (matches(*argv, "delete") == 0)
		return do_del(argc-1, argv+1);
	if (matches(*argv, "show") == 0 ||
	    matches(*argv, "lst") == 0 ||
	    matches(*argv, "list") == 0)
		return do_show(argc-1, argv+1);
	if (matches(*argv, "help") == 0)
		usage();

	fprintf(stderr, "Command \"%s\" is unknown, try \"ip l2tp help\".\n", *argv);
	exit(-1);
}
Ejemplo n.º 2
0
int genl_init_handle(struct rtnl_handle *grth, const char *family,
		     int *genl_family)
{
	if (*genl_family >= 0)
		return 0;

	if (rtnl_open_byproto(grth, 0, NETLINK_GENERIC) < 0) {
		fprintf(stderr, "Cannot open generic netlink socket\n");
		return -1;
	}

	*genl_family = genl_resolve_family(grth, family);
	if (*genl_family < 0)
		return -1;

	return 0;
}
Ejemplo n.º 3
0
static int tcpm_do_cmd(int cmd, int argc, char **argv)
{
	TCPM_REQUEST(req, 1024, TCP_METRICS_CMD_GET, NLM_F_REQUEST);
	int atype = -1;
	int ack;

	memset(&f, 0, sizeof(f));
	f.addr.bitlen = -1;
	f.addr.family = preferred_family;

	switch (preferred_family) {
	case AF_UNSPEC:
	case AF_INET:
	case AF_INET6:
		break;
	default:
		fprintf(stderr, "Unsupported protocol family: %d\n", preferred_family);
		return -1;
	}

	for (; argc > 0; argc--, argv++) {
		char *who = "address";

		if (strcmp(*argv, "addr") == 0 ||
		    strcmp(*argv, "address") == 0) {
			who = *argv;
			NEXT_ARG();
		}
		if (matches(*argv, "help") == 0)
			usage();
		if (f.addr.bitlen >= 0)
			duparg2(who, *argv);

		get_prefix(&f.addr, *argv, preferred_family);
		if (f.addr.bytelen && f.addr.bytelen * 8 == f.addr.bitlen) {
			if (f.addr.family == AF_INET)
				atype = TCP_METRICS_ATTR_ADDR_IPV4;
			else if (f.addr.family == AF_INET6)
				atype = TCP_METRICS_ATTR_ADDR_IPV6;
		}
		if ((CMD_DEL & cmd) && atype < 0) {
			fprintf(stderr, "Error: a specific IP address is expected rather than \"%s\"\n",
				*argv);
			return -1;
		}

		argc--; argv++;
	}

	if (cmd == CMD_DEL && atype < 0)
		missarg("address");

	/* flush for exact address ? Single del */
	if (cmd == CMD_FLUSH && atype >= 0)
		cmd = CMD_DEL;

	/* flush for all addresses ? Single del without address */
	if (cmd == CMD_FLUSH && f.addr.bitlen <= 0 &&
	    preferred_family == AF_UNSPEC) {
		cmd = CMD_DEL;
		req.g.cmd = TCP_METRICS_CMD_DEL;
		ack = 1;
	} else if (cmd == CMD_DEL) {
		req.g.cmd = TCP_METRICS_CMD_DEL;
		ack = 1;
	} else {	/* CMD_FLUSH, CMD_LIST */
		ack = 0;
	}

	if (genl_family < 0) {
		if (rtnl_open_byproto(&grth, 0, NETLINK_GENERIC) < 0) {
			fprintf(stderr, "Cannot open generic netlink socket\n");
			exit(1);
		}
		genl_family = genl_resolve_family(&grth,
						  TCP_METRICS_GENL_NAME);
		if (genl_family < 0)
			exit(1);
		req.n.nlmsg_type = genl_family;
	}

	if (!(cmd & CMD_FLUSH) && (atype >= 0 || (cmd & CMD_DEL))) {
		if (ack)
			req.n.nlmsg_flags |= NLM_F_ACK;
		if (atype >= 0)
			addattr_l(&req.n, sizeof(req), atype, &f.addr.data,
				  f.addr.bytelen);
	} else {
		req.n.nlmsg_flags |= NLM_F_DUMP;
	}

	f.cmd = cmd;
	if (cmd & CMD_FLUSH) {
		int round = 0;
		char flushb[4096-512];

		f.flushb = flushb;
		f.flushp = 0;
		f.flushe = sizeof(flushb);

		for (;;) {
			req.n.nlmsg_seq = grth.dump = ++grth.seq;
			if (rtnl_send(&grth, &req, req.n.nlmsg_len) < 0) {
				perror("Failed to send flush request");
				exit(1);
			}
			f.flushed = 0;
			if (rtnl_dump_filter(&grth, process_msg, stdout) < 0) {
				fprintf(stderr, "Flush terminated\n");
				exit(1);
			}
			if (f.flushed == 0) {
				if (round == 0) {
					fprintf(stderr, "Nothing to flush.\n");
				} else if (show_stats)
					printf("*** Flush is complete after %d round%s ***\n",
					       round, round > 1 ? "s" : "");
				fflush(stdout);
				return 0;
			}
			round++;
			if (flush_update() < 0)
				exit(1);
			if (show_stats) {
				printf("\n*** Round %d, deleting %d entries ***\n",
				       round, f.flushed);
				fflush(stdout);
			}
		}
		return 0;
	}

	if (ack) {
		if (rtnl_talk(&grth, &req.n, 0, 0, NULL) < 0)
			return -2;
	} else if (atype >= 0) {
		if (rtnl_talk(&grth, &req.n, 0, 0, &req.n) < 0)
			return -2;
		if (process_msg(NULL, &req.n, stdout) < 0) {
			fprintf(stderr, "Dump terminated\n");
			exit(1);
		}
	} else {
		req.n.nlmsg_seq = grth.dump = ++grth.seq;
		if (rtnl_send(&grth, &req, req.n.nlmsg_len) < 0) {
			perror("Failed to send dump request");
			exit(1);
		}

		if (rtnl_dump_filter(&grth, process_msg, stdout) < 0) {
			fprintf(stderr, "Dump terminated\n");
			exit(1);
		}
	}
	return 0;
}
Ejemplo n.º 4
0
static int seg6_do_cmd(void)
{
	SEG6_REQUEST(req, 1024, opts.cmd, NLM_F_REQUEST);
	int repl = 0, dump = 0;

	if (genl_family < 0) {
		if (rtnl_open_byproto(&grth, 0, NETLINK_GENERIC) < 0) {
			fprintf(stderr, "Cannot open generic netlink socket\n");
			exit(1);
		}
		genl_family = genl_resolve_family(&grth, SEG6_GENL_NAME);
		if (genl_family < 0)
			exit(1);
		req.n.nlmsg_type = genl_family;
	}

	switch (opts.cmd) {
	case SEG6_CMD_SETHMAC:
	{
		addattr32(&req.n, sizeof(req), SEG6_ATTR_HMACKEYID, opts.keyid);
		addattr8(&req.n, sizeof(req), SEG6_ATTR_SECRETLEN,
			 strlen(opts.pass));
		addattr8(&req.n, sizeof(req), SEG6_ATTR_ALGID, opts.alg_id);
		if (strlen(opts.pass))
			addattr_l(&req.n, sizeof(req), SEG6_ATTR_SECRET,
				  opts.pass, strlen(opts.pass));
		break;
	}
	case SEG6_CMD_SET_TUNSRC:
		addattr_l(&req.n, sizeof(req), SEG6_ATTR_DST, &opts.addr,
			  sizeof(struct in6_addr));
		break;
	case SEG6_CMD_DUMPHMAC:
		dump = 1;
		break;
	case SEG6_CMD_GET_TUNSRC:
		repl = 1;
		break;
	}

	if (!repl && !dump) {
		if (rtnl_talk(&grth, &req.n, NULL, 0) < 0)
			return -1;
	} else if (repl) {
		if (rtnl_talk(&grth, &req.n, &req.n, sizeof(req)) < 0)
			return -2;
		if (process_msg(NULL, &req.n, stdout) < 0) {
			fprintf(stderr, "Error parsing reply\n");
			exit(1);
		}
	} else {
		req.n.nlmsg_flags |= NLM_F_DUMP;
		req.n.nlmsg_seq = grth.dump = ++grth.seq;
		if (rtnl_send(&grth, &req, req.n.nlmsg_len) < 0) {
			perror("Failed to send dump request");
			exit(1);
		}

		if (rtnl_dump_filter(&grth, process_msg, stdout) < 0) {
			fprintf(stderr, "Dump terminated\n");
			exit(1);
		}
	}

	return 0;
}