Esempio n. 1
0
static const struct token *
match_token(const char *word, const struct token *table,
    struct parse_result *res)
{
	unsigned int		 i, match;
	const struct token	*t = NULL;

	match = 0;

	for (i = 0; table[i].type != ENDTOKEN; i++) {
		switch (table[i].type) {
		case NOTOKEN:
			if (word == NULL || strlen(word) == 0) {
				match++;
				t = &table[i];
			}
			break;
		case KEYWORD:
			if (word != NULL && strncmp(word, table[i].keyword,
			    strlen(word)) == 0) {
				match++;
				t = &table[i];
				if (t->value)
					res->action = t->value;
			}
			break;
		case FLAG:
			if (word != NULL && strncmp(word, table[i].keyword,
			    strlen(word)) == 0) {
				match++;
				t = &table[i];
				res->flags |= t->value;
			}
			break;
		case FAMILY:
			if (word == NULL)
				break;
			if (!strcmp(word, "inet") ||
			    !strcasecmp(word, "IPv4")) {
				match++;
				t = &table[i];
				res->family = AF_INET;
			}
			if (!strcmp(word, "inet6") ||
			    !strcasecmp(word, "IPv6")) {
				match++;
				t = &table[i];
				res->family = AF_INET6;
			}
			break;
		case ASNUM:
			if (parse_asnum(word, &res->as)) {
				match++;
				t = &table[i];
			}
			break;
		case ADDRESS:
			if (parse_addr(word, &res->family, &res->addr)) {
				match++;
				t = &table[i];
				if (t->value)
					res->action = t->value;
			}
			break;
		case PREFIX:
			if (parse_prefix(word, &res->family, &res->addr,
			    &res->prefixlen)) {
				match++;
				t = &table[i];
				if (t->value)
					res->action = t->value;
			}
			break;
		case IFNAME:
			if (!match && word != NULL && strlen(word) > 0) {
				if (strlcpy(res->ifname, word,
				    sizeof(res->ifname)) >=
				    sizeof(res->ifname))
					err(1, "interface name too long");
				match++;
				t = &table[i];
				if (t->value)
					res->action = t->value;
			}
			break;

		case ENDTOKEN:
			break;
		}
	}

	if (match != 1) {
		if (word == NULL)
			fprintf(stderr, "missing argument:\n");
		else if (match > 1)
			fprintf(stderr, "ambiguous argument: %s\n", word);
		else if (match < 1)
			fprintf(stderr, "unknown argument: %s\n", word);
		return (NULL);
	}

	return (t);
}
Esempio n. 2
0
const struct token *
match_token(int *argc, char **argv[], const struct token table[])
{
	u_int			 i, match;
	const struct token	*t = NULL;
	struct filter_set	*fs;
	const char		*word = *argv[0];

	match = 0;

	for (i = 0; table[i].type != ENDTOKEN; i++) {
		switch (table[i].type) {
		case NOTOKEN:
			if (word == NULL || strlen(word) == 0) {
				match++;
				t = &table[i];
			}
			break;
		case KEYWORD:
			if (word != NULL && strncmp(word, table[i].keyword,
			    strlen(word)) == 0) {
				match++;
				t = &table[i];
				if (t->value)
					res.action = t->value;
			}
			break;
		case FLAG:
			if (word != NULL && strncmp(word, table[i].keyword,
			    strlen(word)) == 0) {
				match++;
				t = &table[i];
				res.flags |= t->value;
			}
			break;
		case FAMILY:
			if (word == NULL)
				break;
			if (!strcmp(word, "inet") ||
			    !strcasecmp(word, "IPv4")) {
				match++;
				t = &table[i];
				res.aid = AID_INET;
			}
			if (!strcmp(word, "inet6") ||
			    !strcasecmp(word, "IPv6")) {
				match++;
				t = &table[i];
				res.aid = AID_INET6;
			}
			if (!strcasecmp(word, "VPNv4")) {
				match++;
				t = &table[i];
				res.aid = AID_VPN_IPv4;
			}
			break;
		case ADDRESS:
			if (parse_addr(word, &res.addr)) {
				match++;
				t = &table[i];
				if (t->value)
					res.action = t->value;
			}
			break;
		case PEERADDRESS:
			if (parse_addr(word, &res.peeraddr)) {
				match++;
				t = &table[i];
				if (t->value)
					res.action = t->value;
			}
			break;
		case PREFIX:
			if (parse_prefix(word, &res.addr, &res.prefixlen)) {
				match++;
				t = &table[i];
				if (t->value)
					res.action = t->value;
			}
			break;
		case ASTYPE:
			if (word != NULL && strncmp(word, table[i].keyword,
			    strlen(word)) == 0) {
				match++;
				t = &table[i];
				res.as.type = t->value;
			}
			break;
		case ASNUM:
			if (parse_asnum(word, &res.as.as)) {
				match++;
				t = &table[i];
			}
			break;
		case PEERDESC:
			if (!match && word != NULL && strlen(word) > 0) {
				if (strlcpy(res.peerdesc, word,
				    sizeof(res.peerdesc)) >=
				    sizeof(res.peerdesc))
					errx(1, "neighbor description too "
					    "long");
				match++;
				t = &table[i];
			}
			break;
		case RIBNAME:
			if (!match && word != NULL && strlen(word) > 0) {
				if (strlcpy(res.rib, word, sizeof(res.rib)) >=
				    sizeof(res.rib))
					errx(1, "rib name too long");
				match++;
				t = &table[i];
			}
			break;
		case COMMUNITY:
			if (word != NULL && strlen(word) > 0 &&
			    parse_community(word, &res)) {
				match++;
				t = &table[i];
			}
			break;
		case LOCALPREF:
		case MED:
		case PREPNBR:
		case PREPSELF:
		case WEIGHT:
		case RTABLE:
			if (word != NULL && strlen(word) > 0 &&
			    parse_number(word, &res, table[i].type)) {
				match++;
				t = &table[i];
			}
			break;
		case NEXTHOP:
			if (word != NULL && strlen(word) > 0 &&
			    parse_nexthop(word, &res)) {
				match++;
				t = &table[i];
			}
			break;
		case PFTABLE:
			if (word != NULL && strlen(word) > 0) {
				if ((fs = calloc(1,
				    sizeof(struct filter_set))) == NULL)
					err(1, NULL);
				if (strlcpy(fs->action.pftable, word,
				    sizeof(fs->action.pftable)) >=
				    sizeof(fs->action.pftable))
					errx(1, "pftable name too long");
				TAILQ_INSERT_TAIL(&res.set, fs, entry);
				match++;
				t = &table[i];
			}
			break;
		case GETOPT:
			if (bgpctl_getopt(argc, argv, table[i].value)) {
				match++;
				t = &table[i];
			}
			break;
		case FILENAME:
			if (word != NULL && strlen(word) > 0) {
				if ((res.mrtfd = open(word, O_RDONLY)) == -1) {
					/*
					 * ignore error if path has no / and
					 * does not exist. In hope to print
					 * usage.
					 */
					if (errno == ENOENT &&
					    !strchr(word, '/'))
						break;
					err(1, "mrt open(%s)", word);
				}
				match++;
				t = &table[i];
			}
			break;
		case ENDTOKEN:
			break;
		}
	}

	if (match != 1) {
		if (word == NULL)
			fprintf(stderr, "missing argument:\n");
		else if (match > 1)
			fprintf(stderr, "ambiguous argument: %s\n", word);
		else if (match < 1)
			fprintf(stderr, "unknown argument: %s\n", word);
		return (NULL);
	}

	return (t);
}