Blame utils/nfnl_osf.c

Packit Service d1fe03
/*
Packit Service d1fe03
 * Copyright (c) 2005 Evgeniy Polyakov <johnpol@2ka.mxt.ru>
Packit Service d1fe03
 * 
Packit Service d1fe03
 *
Packit Service d1fe03
 * This program is free software; you can redistribute it and/or modify
Packit Service d1fe03
 * it under the terms of the GNU General Public License as published by
Packit Service d1fe03
 * the Free Software Foundation; either version 2 of the License, or
Packit Service d1fe03
 * (at your option) any later version.
Packit Service d1fe03
 *
Packit Service d1fe03
 * This program is distributed in the hope that it will be useful,
Packit Service d1fe03
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service d1fe03
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service d1fe03
 * GNU General Public License for more details.
Packit Service d1fe03
 *
Packit Service d1fe03
 * You should have received a copy of the GNU General Public License
Packit Service d1fe03
 * along with this program; if not, write to the Free Software
Packit Service d1fe03
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
Packit Service d1fe03
 */
Packit Service d1fe03
Packit Service d1fe03
#include <sys/types.h>
Packit Service d1fe03
#include <sys/socket.h>
Packit Service d1fe03
#include <sys/poll.h>
Packit Service d1fe03
#include <sys/time.h>
Packit Service d1fe03
Packit Service d1fe03
#include <arpa/inet.h>
Packit Service d1fe03
Packit Service d1fe03
#include <ctype.h>
Packit Service d1fe03
#include <errno.h>
Packit Service d1fe03
#include <stdio.h>
Packit Service d1fe03
#include <stdlib.h>
Packit Service d1fe03
#include <string.h>
Packit Service d1fe03
#include <stdarg.h>
Packit Service d1fe03
#include <time.h>
Packit Service d1fe03
#include <unistd.h>
Packit Service d1fe03
Packit Service d1fe03
#include <netinet/ip.h>
Packit Service d1fe03
#include <netinet/tcp.h>
Packit Service d1fe03
Packit Service d1fe03
#include <linux/connector.h>
Packit Service d1fe03
#include <linux/types.h>
Packit Service d1fe03
#include <linux/netlink.h>
Packit Service d1fe03
#include <linux/rtnetlink.h>
Packit Service d1fe03
#include <linux/unistd.h>
Packit Service d1fe03
Packit Service d1fe03
#include <libnfnetlink/libnfnetlink.h>
Packit Service d1fe03
Packit Service d1fe03
#include <linux/netfilter/nfnetlink.h>
Packit Service d1fe03
#include <linux/netfilter/xt_osf.h>
Packit Service d1fe03
Packit Service d1fe03
#define OPTDEL			','
Packit Service d1fe03
#define OSFPDEL 		':'
Packit Service d1fe03
#define MAXOPTSTRLEN		128
Packit Service d1fe03
Packit Service d1fe03
#ifndef NIPQUAD
Packit Service d1fe03
#define NIPQUAD(addr) \
Packit Service d1fe03
	((unsigned char *)&addr)[0], \
Packit Service d1fe03
	((unsigned char *)&addr)[1], \
Packit Service d1fe03
	((unsigned char *)&addr)[2], \
Packit Service d1fe03
	((unsigned char *)&addr)[3]
Packit Service d1fe03
#endif
Packit Service d1fe03
Packit Service d1fe03
static struct nfnl_handle *nfnlh;
Packit Service d1fe03
static struct nfnl_subsys_handle *nfnlssh;
Packit Service d1fe03
Packit Service d1fe03
static struct xt_osf_opt IANA_opts[] = {
Packit Service d1fe03
	{ .kind = 0, .length = 1,},
Packit Service d1fe03
	{ .kind=1, .length=1,},
Packit Service d1fe03
	{ .kind=2, .length=4,},
Packit Service d1fe03
	{ .kind=3, .length=3,},
Packit Service d1fe03
	{ .kind=4, .length=2,},
Packit Service d1fe03
	{ .kind=5, .length=1,},		/* SACK length is not defined */
Packit Service d1fe03
	{ .kind=6, .length=6,},
Packit Service d1fe03
	{ .kind=7, .length=6,},
Packit Service d1fe03
	{ .kind=8, .length=10,},
Packit Service d1fe03
	{ .kind=9, .length=2,},
Packit Service d1fe03
	{ .kind=10, .length=3,},
Packit Service d1fe03
	{ .kind=11, .length=1,},		/* CC: Suppose 1 */
Packit Service d1fe03
	{ .kind=12, .length=1,},		/* the same */
Packit Service d1fe03
	{ .kind=13, .length=1,},		/* and here too */
Packit Service d1fe03
	{ .kind=14, .length=3,},
Packit Service d1fe03
	{ .kind=15, .length=1,},		/* TCP Alternate Checksum Data. Length is not defined */
Packit Service d1fe03
	{ .kind=16, .length=1,},
Packit Service d1fe03
	{ .kind=17, .length=1,},
Packit Service d1fe03
	{ .kind=18, .length=3,},
Packit Service d1fe03
	{ .kind=19, .length=18,},
Packit Service d1fe03
	{ .kind=20, .length=1,},
Packit Service d1fe03
	{ .kind=21, .length=1,},
Packit Service d1fe03
	{ .kind=22, .length=1,},
Packit Service d1fe03
	{ .kind=23, .length=1,},
Packit Service d1fe03
	{ .kind=24, .length=1,},
Packit Service d1fe03
	{ .kind=25, .length=1,},
Packit Service d1fe03
	{ .kind=26, .length=1,},
Packit Service d1fe03
};
Packit Service d1fe03
Packit Service d1fe03
static FILE *osf_log_stream;
Packit Service d1fe03
Packit Service d1fe03
static void uloga(const char *f, ...)
Packit Service d1fe03
{
Packit Service d1fe03
	va_list ap;
Packit Service d1fe03
Packit Service d1fe03
	if (!osf_log_stream)
Packit Service d1fe03
		osf_log_stream = stdout;
Packit Service d1fe03
Packit Service d1fe03
	va_start(ap, f);
Packit Service d1fe03
	vfprintf(osf_log_stream, f, ap);
Packit Service d1fe03
	va_end(ap);
Packit Service d1fe03
Packit Service d1fe03
	fflush(osf_log_stream);
Packit Service d1fe03
}
Packit Service d1fe03
Packit Service d1fe03
static void ulog(const char *f, ...)
Packit Service d1fe03
{
Packit Service d1fe03
	char str[64];
Packit Service d1fe03
	struct tm tm;
Packit Service d1fe03
	struct timeval tv;
Packit Service d1fe03
	va_list ap;
Packit Service d1fe03
Packit Service d1fe03
	if (!osf_log_stream)
Packit Service d1fe03
		osf_log_stream = stdout;
Packit Service d1fe03
Packit Service d1fe03
	gettimeofday(&tv, NULL);
Packit Service d1fe03
	localtime_r((time_t *)&tv.tv_sec, &tm;;
Packit Service d1fe03
	strftime(str, sizeof(str), "%F %R:%S", &tm;;
Packit Service d1fe03
Packit Service d1fe03
	fprintf(osf_log_stream, "%s.%lu %ld ", str, tv.tv_usec, syscall(__NR_gettid));
Packit Service d1fe03
Packit Service d1fe03
	va_start(ap, f);
Packit Service d1fe03
	vfprintf(osf_log_stream, f, ap);
Packit Service d1fe03
	va_end(ap);
Packit Service d1fe03
Packit Service d1fe03
	fflush(osf_log_stream);
Packit Service d1fe03
}
Packit Service d1fe03
Packit Service d1fe03
#define ulog_err(f, a...) uloga(f ": %s [%d].\n", ##a, strerror(errno), errno)
Packit Service d1fe03
Packit Service d1fe03
static char *xt_osf_strchr(char *ptr, char c)
Packit Service d1fe03
{
Packit Service d1fe03
	char *tmp;
Packit Service d1fe03
Packit Service d1fe03
	tmp = strchr(ptr, c);
Packit Service d1fe03
	if (tmp)
Packit Service d1fe03
		*tmp = '\0';
Packit Service d1fe03
Packit Service d1fe03
	while (tmp && isspace(*(tmp + 1)))
Packit Service d1fe03
		tmp++;
Packit Service d1fe03
Packit Service d1fe03
	return tmp;
Packit Service d1fe03
}
Packit Service d1fe03
Packit Service d1fe03
static void xt_osf_parse_opt(struct xt_osf_opt *opt, __u16 *optnum, char *obuf, int olen)
Packit Service d1fe03
{
Packit Service d1fe03
	int i, op;
Packit Service d1fe03
	char *ptr, wc;
Packit Service d1fe03
	unsigned long val;
Packit Service d1fe03
Packit Service d1fe03
	ptr = &obuf[0];
Packit Service d1fe03
	i = 0;
Packit Service d1fe03
	while (ptr != NULL && i < olen && *ptr != 0) {
Packit Service d1fe03
		val = 0;
Packit Service d1fe03
		wc = OSF_WSS_PLAIN;
Packit Service d1fe03
		switch (obuf[i]) {
Packit Service d1fe03
		case 'N':
Packit Service d1fe03
			op = OSFOPT_NOP;
Packit Service d1fe03
			ptr = xt_osf_strchr(&obuf[i], OPTDEL);
Packit Service d1fe03
			if (ptr) {
Packit Service d1fe03
				*ptr = '\0';
Packit Service d1fe03
				ptr++;
Packit Service d1fe03
				i += (int)(ptr - &obuf[i]);
Packit Service d1fe03
			} else
Packit Service d1fe03
				i++;
Packit Service d1fe03
			break;
Packit Service d1fe03
		case 'S':
Packit Service d1fe03
			op = OSFOPT_SACKP;
Packit Service d1fe03
			ptr = xt_osf_strchr(&obuf[i], OPTDEL);
Packit Service d1fe03
			if (ptr) {
Packit Service d1fe03
				*ptr = '\0';
Packit Service d1fe03
				ptr++;
Packit Service d1fe03
				i += (int)(ptr - &obuf[i]);
Packit Service d1fe03
			} else
Packit Service d1fe03
				i++;
Packit Service d1fe03
			break;
Packit Service d1fe03
		case 'T':
Packit Service d1fe03
			op = OSFOPT_TS;
Packit Service d1fe03
			ptr = xt_osf_strchr(&obuf[i], OPTDEL);
Packit Service d1fe03
			if (ptr) {
Packit Service d1fe03
				*ptr = '\0';
Packit Service d1fe03
				ptr++;
Packit Service d1fe03
				i += (int)(ptr - &obuf[i]);
Packit Service d1fe03
			} else
Packit Service d1fe03
				i++;
Packit Service d1fe03
			break;
Packit Service d1fe03
		case 'W':
Packit Service d1fe03
			op = OSFOPT_WSO;
Packit Service d1fe03
			ptr = xt_osf_strchr(&obuf[i], OPTDEL);
Packit Service d1fe03
			if (ptr) {
Packit Service d1fe03
				switch (obuf[i + 1]) {
Packit Service d1fe03
				case '%':
Packit Service d1fe03
					wc = OSF_WSS_MODULO;
Packit Service d1fe03
					break;
Packit Service d1fe03
				case 'S':
Packit Service d1fe03
					wc = OSF_WSS_MSS;
Packit Service d1fe03
					break;
Packit Service d1fe03
				case 'T':
Packit Service d1fe03
					wc = OSF_WSS_MTU;
Packit Service d1fe03
					break;
Packit Service d1fe03
				default:
Packit Service d1fe03
					wc = OSF_WSS_PLAIN;
Packit Service d1fe03
					break;
Packit Service d1fe03
				}
Packit Service d1fe03
Packit Service d1fe03
				*ptr = '\0';
Packit Service d1fe03
				ptr++;
Packit Service d1fe03
				if (wc)
Packit Service d1fe03
					val = strtoul(&obuf[i + 2], NULL, 10);
Packit Service d1fe03
				else
Packit Service d1fe03
					val = strtoul(&obuf[i + 1], NULL, 10);
Packit Service d1fe03
				i += (int)(ptr - &obuf[i]);
Packit Service d1fe03
Packit Service d1fe03
			} else
Packit Service d1fe03
				i++;
Packit Service d1fe03
			break;
Packit Service d1fe03
		case 'M':
Packit Service d1fe03
			op = OSFOPT_MSS;
Packit Service d1fe03
			ptr = xt_osf_strchr(&obuf[i], OPTDEL);
Packit Service d1fe03
			if (ptr) {
Packit Service d1fe03
				if (obuf[i + 1] == '%')
Packit Service d1fe03
					wc = OSF_WSS_MODULO;
Packit Service d1fe03
				*ptr = '\0';
Packit Service d1fe03
				ptr++;
Packit Service d1fe03
				if (wc)
Packit Service d1fe03
					val = strtoul(&obuf[i + 2], NULL, 10);
Packit Service d1fe03
				else
Packit Service d1fe03
					val = strtoul(&obuf[i + 1], NULL, 10);
Packit Service d1fe03
				i += (int)(ptr - &obuf[i]);
Packit Service d1fe03
			} else
Packit Service d1fe03
				i++;
Packit Service d1fe03
			break;
Packit Service d1fe03
		case 'E':
Packit Service d1fe03
			op = OSFOPT_EOL;
Packit Service d1fe03
			ptr = xt_osf_strchr(&obuf[i], OPTDEL);
Packit Service d1fe03
			if (ptr) {
Packit Service d1fe03
				*ptr = '\0';
Packit Service d1fe03
				ptr++;
Packit Service d1fe03
				i += (int)(ptr - &obuf[i]);
Packit Service d1fe03
			} else
Packit Service d1fe03
				i++;
Packit Service d1fe03
			break;
Packit Service d1fe03
		default:
Packit Service d1fe03
			op = OSFOPT_EMPTY;
Packit Service d1fe03
			ptr = xt_osf_strchr(&obuf[i], OPTDEL);
Packit Service d1fe03
			if (ptr) {
Packit Service d1fe03
				ptr++;
Packit Service d1fe03
				i += (int)(ptr - &obuf[i]);
Packit Service d1fe03
			} else
Packit Service d1fe03
				i++;
Packit Service d1fe03
			break;
Packit Service d1fe03
		}
Packit Service d1fe03
Packit Service d1fe03
		if (op != OSFOPT_EMPTY) {
Packit Service d1fe03
			opt[*optnum].kind = IANA_opts[op].kind;
Packit Service d1fe03
			opt[*optnum].length = IANA_opts[op].length;
Packit Service d1fe03
			opt[*optnum].wc.wc = wc;
Packit Service d1fe03
			opt[*optnum].wc.val = val;
Packit Service d1fe03
			(*optnum)++;
Packit Service d1fe03
		}
Packit Service d1fe03
	}
Packit Service d1fe03
}
Packit Service d1fe03
Packit Service d1fe03
static int osf_load_line(char *buffer, int len, int del)
Packit Service d1fe03
{
Packit Service d1fe03
	int i, cnt = 0;
Packit Service d1fe03
	char obuf[MAXOPTSTRLEN];
Packit Service d1fe03
	struct xt_osf_user_finger f;
Packit Service d1fe03
	char *pbeg, *pend;
Packit Service d1fe03
	char buf[NFNL_HEADER_LEN + NFA_LENGTH(sizeof(struct xt_osf_user_finger))];
Packit Service d1fe03
	struct nlmsghdr *nmh = (struct nlmsghdr *) buf;
Packit Service d1fe03
Packit Service d1fe03
	memset(&f, 0, sizeof(struct xt_osf_user_finger));
Packit Service d1fe03
Packit Service d1fe03
	ulog("Loading '%s'.\n", buffer);
Packit Service d1fe03
Packit Service d1fe03
	for (i = 0; i < len && buffer[i] != '\0'; ++i) {
Packit Service d1fe03
		if (buffer[i] == ':')
Packit Service d1fe03
			cnt++;
Packit Service d1fe03
	}
Packit Service d1fe03
Packit Service d1fe03
	if (cnt != 8) {
Packit Service d1fe03
		ulog("Wrong input line '%s': cnt: %d, must be 8, i: %d, must be %d.\n", buffer, cnt, i, len);
Packit Service d1fe03
		return -EINVAL;
Packit Service d1fe03
	}
Packit Service d1fe03
Packit Service d1fe03
	memset(obuf, 0, sizeof(obuf));
Packit Service d1fe03
Packit Service d1fe03
	pbeg = buffer;
Packit Service d1fe03
	pend = xt_osf_strchr(pbeg, OSFPDEL);
Packit Service d1fe03
	if (pend) {
Packit Service d1fe03
		*pend = '\0';
Packit Service d1fe03
		if (pbeg[0] == 'S') {
Packit Service d1fe03
			f.wss.wc = OSF_WSS_MSS;
Packit Service d1fe03
			if (pbeg[1] == '%')
Packit Service d1fe03
				f.wss.val = strtoul(&pbeg[2], NULL, 10);
Packit Service d1fe03
			else if (pbeg[1] == '*')
Packit Service d1fe03
				f.wss.val = 0;
Packit Service d1fe03
			else
Packit Service d1fe03
				f.wss.val = strtoul(&pbeg[1], NULL, 10);
Packit Service d1fe03
		} else if (pbeg[0] == 'T') {
Packit Service d1fe03
			f.wss.wc = OSF_WSS_MTU;
Packit Service d1fe03
			if (pbeg[1] == '%')
Packit Service d1fe03
				f.wss.val = strtoul(&pbeg[2], NULL, 10);
Packit Service d1fe03
			else if (pbeg[1] == '*')
Packit Service d1fe03
				f.wss.val = 0;
Packit Service d1fe03
			else
Packit Service d1fe03
				f.wss.val = strtoul(&pbeg[1], NULL, 10);
Packit Service d1fe03
		} else if (pbeg[0] == '%') {
Packit Service d1fe03
			f.wss.wc = OSF_WSS_MODULO;
Packit Service d1fe03
			f.wss.val = strtoul(&pbeg[1], NULL, 10);
Packit Service d1fe03
		} else if (isdigit(pbeg[0])) {
Packit Service d1fe03
			f.wss.wc = OSF_WSS_PLAIN;
Packit Service d1fe03
			f.wss.val = strtoul(&pbeg[0], NULL, 10);
Packit Service d1fe03
		}
Packit Service d1fe03
Packit Service d1fe03
		pbeg = pend + 1;
Packit Service d1fe03
	}
Packit Service d1fe03
	pend = xt_osf_strchr(pbeg, OSFPDEL);
Packit Service d1fe03
	if (pend) {
Packit Service d1fe03
		*pend = '\0';
Packit Service d1fe03
		f.ttl = strtoul(pbeg, NULL, 10);
Packit Service d1fe03
		pbeg = pend + 1;
Packit Service d1fe03
	}
Packit Service d1fe03
	pend = xt_osf_strchr(pbeg, OSFPDEL);
Packit Service d1fe03
	if (pend) {
Packit Service d1fe03
		*pend = '\0';
Packit Service d1fe03
		f.df = strtoul(pbeg, NULL, 10);
Packit Service d1fe03
		pbeg = pend + 1;
Packit Service d1fe03
	}
Packit Service d1fe03
	pend = xt_osf_strchr(pbeg, OSFPDEL);
Packit Service d1fe03
	if (pend) {
Packit Service d1fe03
		*pend = '\0';
Packit Service d1fe03
		f.ss = strtoul(pbeg, NULL, 10);
Packit Service d1fe03
		pbeg = pend + 1;
Packit Service d1fe03
	}
Packit Service d1fe03
Packit Service d1fe03
	pend = xt_osf_strchr(pbeg, OSFPDEL);
Packit Service d1fe03
	if (pend) {
Packit Service d1fe03
		*pend = '\0';
Packit Service d1fe03
		i = sizeof(obuf);
Packit Service d1fe03
		snprintf(obuf, i, "%.*s,", i - 2, pbeg);
Packit Service d1fe03
		pbeg = pend + 1;
Packit Service d1fe03
	}
Packit Service d1fe03
Packit Service d1fe03
	pend = xt_osf_strchr(pbeg, OSFPDEL);
Packit Service d1fe03
	if (pend) {
Packit Service d1fe03
		*pend = '\0';
Packit Service d1fe03
		i = sizeof(f.genre);
Packit Service d1fe03
		if (pbeg[0] == '@' || pbeg[0] == '*')
Packit Service d1fe03
			pbeg++;
Packit Service d1fe03
		snprintf(f.genre, i, "%.*s", i - 1, pbeg);
Packit Service d1fe03
		pbeg = pend + 1;
Packit Service d1fe03
	}
Packit Service d1fe03
Packit Service d1fe03
	pend = xt_osf_strchr(pbeg, OSFPDEL);
Packit Service d1fe03
	if (pend) {
Packit Service d1fe03
		*pend = '\0';
Packit Service d1fe03
		i = sizeof(f.version);
Packit Service d1fe03
		snprintf(f.version, i, "%.*s", i - 1, pbeg);
Packit Service d1fe03
		pbeg = pend + 1;
Packit Service d1fe03
	}
Packit Service d1fe03
Packit Service d1fe03
	pend = xt_osf_strchr(pbeg, OSFPDEL);
Packit Service d1fe03
	if (pend) {
Packit Service d1fe03
		*pend = '\0';
Packit Service d1fe03
		i = sizeof(f.subtype);
Packit Service d1fe03
		snprintf(f.subtype, i, "%.*s", i - 1, pbeg);
Packit Service d1fe03
	}
Packit Service d1fe03
Packit Service d1fe03
	xt_osf_parse_opt(f.opt, &f.opt_num, obuf, sizeof(obuf));
Packit Service d1fe03
Packit Service d1fe03
	memset(buf, 0, sizeof(buf));
Packit Service d1fe03
Packit Service d1fe03
	if (del)
Packit Service 537035
		nfnl_fill_hdr(nfnlssh, nmh, 0, AF_UNSPEC, 0, OSF_MSG_REMOVE,
Packit Service 537035
			      NLM_F_ACK | NLM_F_REQUEST);
Packit Service d1fe03
	else
Packit Service 537035
		nfnl_fill_hdr(nfnlssh, nmh, 0, AF_UNSPEC, 0, OSF_MSG_ADD,
Packit Service 537035
			      NLM_F_ACK | NLM_F_REQUEST | NLM_F_CREATE);
Packit Service d1fe03
Packit Service d1fe03
	nfnl_addattr_l(nmh, sizeof(buf), OSF_ATTR_FINGER, &f, sizeof(struct xt_osf_user_finger));
Packit Service d1fe03
Packit Service d1fe03
	return nfnl_query(nfnlh, nmh);
Packit Service d1fe03
}
Packit Service d1fe03
Packit Service d1fe03
static int osf_load_entries(char *path, int del)
Packit Service d1fe03
{
Packit Service d1fe03
	FILE *inf;
Packit Service 49eaca
	int err = 0, lineno = 0;
Packit Service d1fe03
	char buf[1024];
Packit Service d1fe03
Packit Service d1fe03
	inf = fopen(path, "r");
Packit Service d1fe03
	if (!inf) {
Packit Service d1fe03
		ulog_err("Failed to open file '%s'", path);
Packit Service d1fe03
		return -1;
Packit Service d1fe03
	}
Packit Service d1fe03
Packit Service d1fe03
	while(fgets(buf, sizeof(buf), inf)) {
Packit Service 49eaca
		int len, rc;
Packit Service 49eaca
Packit Service 49eaca
		lineno++;
Packit Service d1fe03
Packit Service d1fe03
		if (buf[0] == '#' || buf[0] == '\n' || buf[0] == '\r')
Packit Service d1fe03
			continue;
Packit Service d1fe03
Packit Service d1fe03
		len = strlen(buf) - 1;
Packit Service d1fe03
Packit Service d1fe03
		if (len <= 0)
Packit Service d1fe03
			continue;
Packit Service d1fe03
Packit Service d1fe03
		buf[len] = '\0';
Packit Service d1fe03
Packit Service 49eaca
		rc = osf_load_line(buf, len, del);
Packit Service 49eaca
		if (rc && (!del || errno != ENOENT)) {
Packit Service 49eaca
			ulog_err("Failed to load line %d", lineno);
Packit Service 49eaca
			err = rc;
Packit Service 49eaca
		}
Packit Service d1fe03
Packit Service d1fe03
		memset(buf, 0, sizeof(buf));
Packit Service d1fe03
	}
Packit Service d1fe03
Packit Service d1fe03
	fclose(inf);
Packit Service d1fe03
	return err;
Packit Service d1fe03
}
Packit Service d1fe03
Packit Service d1fe03
int main(int argc, char *argv[])
Packit Service d1fe03
{
Packit Service d1fe03
	int ch, del = 0, err;
Packit Service d1fe03
	char *fingerprints = NULL;
Packit Service d1fe03
Packit Service d1fe03
	while ((ch = getopt(argc, argv, "f:dh")) != -1) {
Packit Service d1fe03
		switch (ch) {
Packit Service d1fe03
			case 'f':
Packit Service d1fe03
				fingerprints = optarg;
Packit Service d1fe03
				break;
Packit Service d1fe03
			case 'd':
Packit Service d1fe03
				del = 1;
Packit Service d1fe03
				break;
Packit Service d1fe03
			default:
Packit Service d1fe03
				fprintf(stderr,
Packit Service d1fe03
					"Usage: %s -f fingerprints [-d]\n",
Packit Service d1fe03
					argv[0]);
Packit Service d1fe03
				return -1;
Packit Service d1fe03
		}
Packit Service d1fe03
	}
Packit Service d1fe03
Packit Service d1fe03
	if (!fingerprints) {
Packit Service d1fe03
		err = -ENOENT;
Packit Service 49eaca
		ulog("Missing fingerprints file argument.\n");
Packit Service d1fe03
		goto err_out_exit;
Packit Service d1fe03
	}
Packit Service d1fe03
Packit Service d1fe03
	nfnlh = nfnl_open();
Packit Service d1fe03
	if (!nfnlh) {
Packit Service d1fe03
		err = -EINVAL;
Packit Service d1fe03
		ulog_err("Failed to create nfnl handler");
Packit Service d1fe03
		goto err_out_exit;
Packit Service d1fe03
	}
Packit Service d1fe03
Packit Service d1fe03
#ifndef NFNL_SUBSYS_OSF
Packit Service d1fe03
#define NFNL_SUBSYS_OSF	5
Packit Service d1fe03
#endif
Packit Service d1fe03
Packit Service d1fe03
	nfnlssh = nfnl_subsys_open(nfnlh, NFNL_SUBSYS_OSF, OSF_MSG_MAX, 0);
Packit Service d1fe03
	if (!nfnlssh) {
Packit Service d1fe03
		err = -EINVAL;
Packit Service d1fe03
		ulog_err("Faied to create nfnl subsystem");
Packit Service d1fe03
		goto err_out_close;
Packit Service d1fe03
	}
Packit Service d1fe03
Packit Service d1fe03
	err = osf_load_entries(fingerprints, del);
Packit Service d1fe03
	if (err)
Packit Service d1fe03
		goto err_out_close_subsys;
Packit Service d1fe03
Packit Service d1fe03
	nfnl_subsys_close(nfnlssh);
Packit Service d1fe03
	nfnl_close(nfnlh);
Packit Service d1fe03
Packit Service d1fe03
	return 0;
Packit Service d1fe03
Packit Service d1fe03
err_out_close_subsys:
Packit Service d1fe03
	nfnl_subsys_close(nfnlssh);
Packit Service d1fe03
err_out_close:
Packit Service d1fe03
	nfnl_close(nfnlh);
Packit Service d1fe03
err_out_exit:
Packit Service d1fe03
	return err;
Packit Service d1fe03
}