Import patch ipxfrm-20040707_2.diff

(Logical change 1.53)
diff --git a/lib/libnetlink.c b/lib/libnetlink.c
index 4beeca6..cb67a20 100644
--- a/lib/libnetlink.c
+++ b/lib/libnetlink.c
@@ -30,13 +30,13 @@
 	close(rth->fd);
 }
 
-int rtnl_open(struct rtnl_handle *rth, unsigned subscriptions)
+int rtnl_open_byproto(struct rtnl_handle *rth, unsigned subscriptions, int protocol)
 {
 	int addr_len;
 
 	memset(rth, 0, sizeof(rth));
 
-	rth->fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+	rth->fd = socket(AF_NETLINK, SOCK_RAW, protocol);
 	if (rth->fd < 0) {
 		perror("Cannot open netlink socket");
 		return -1;
@@ -67,6 +67,11 @@
 	return 0;
 }
 
+int rtnl_open(struct rtnl_handle *rth, unsigned subscriptions)
+{
+	return rtnl_open_byproto(rth, subscriptions, NETLINK_ROUTE);
+}
+
 int rtnl_wilddump_request(struct rtnl_handle *rth, int family, int type)
 {
 	struct {
@@ -521,3 +526,16 @@
 		fprintf(stderr, "!!!Deficit %d, rta_len=%d\n", len, rta->rta_len);
 	return 0;
 }
+
+int parse_rtattr_byindex(struct rtattr *tb[], int max, struct rtattr *rta, int len)
+{
+	int i = 0;
+	while (RTA_OK(rta, len)) {
+		if (rta->rta_type <= max)
+			tb[i++] = rta;
+		rta = RTA_NEXT(rta,len);
+	}
+	if (len)
+		fprintf(stderr, "!!!Deficit %d, rta_len=%d\n", len, rta->rta_len);
+	return i;
+}
diff --git a/lib/utils.c b/lib/utils.c
index 7834b7a..739383a 100644
--- a/lib/utils.c
+++ b/lib/utils.c
@@ -58,6 +58,20 @@
 	return 0;
 }
 
+int get_u64(__u64 *val, const char *arg, int base)
+{
+	unsigned long long res;
+	char *ptr;
+
+	if (!arg || !*arg)
+		return -1;
+	res = strtoull(arg, &ptr, base);
+	if (!ptr || ptr == arg || *ptr || res == 0xFFFFFFFFULL)
+ 		return -1;
+ 	*val = res;
+ 	return 0;
+}
+
 int get_u32(__u32 *val, const char *arg, int base)
 {
 	unsigned long res;
@@ -186,7 +200,7 @@
 	return 0;
 }
 
-int get_prefix_1(inet_prefix *dst, char *arg, int family)
+int get_prefix_1(inet_prefix *dst, const char *arg, int family)
 {
 	int err;
 	unsigned plen;
@@ -235,7 +249,7 @@
 	return err;
 }
 
-int get_addr(inet_prefix *dst, char *arg, int family)
+int get_addr(inet_prefix *dst, const char *arg, int family)
 {
 	if (family == AF_PACKET) {
 		fprintf(stderr, "Error: \"%s\" may be inet address, but it is not allowed in this context.\n", arg);
@@ -248,7 +262,7 @@
 	return 0;
 }
 
-int get_prefix(inet_prefix *dst, char *arg, int family)
+int get_prefix(inet_prefix *dst, const char *arg, int family)
 {
 	if (family == AF_PACKET) {
 		fprintf(stderr, "Error: \"%s\" may be inet prefix, but it is not allowed in this context.\n", arg);
@@ -261,7 +275,7 @@
 	return 0;
 }
 
-__u32 get_addr32(char *name)
+__u32 get_addr32(const char *name)
 {
 	inet_prefix addr;
 	if (get_addr_1(&addr, name, AF_INET)) {
@@ -277,6 +291,12 @@
 	exit(-1);
 }
 
+void missarg(const char *key)
+{
+	fprintf(stderr, "Error: argument \"%s\" is required\n", key);
+	exit(-1);
+}
+
 void invarg(const char *msg, const char *arg)
 {
 	fprintf(stderr, "Error: argument \"%s\" is wrong: %s\n", arg, msg);
@@ -344,7 +364,7 @@
 
 	if (getenv("PROC_NET_PSCHED")) {
 		snprintf(name, sizeof(name)-1, "%s", getenv("PROC_NET_PSCHED"));
-	} else if (getenv("PROC_ROOT")) { 
+	} else if (getenv("PROC_ROOT")) {
 		snprintf(name, sizeof(name)-1, "%s/net/psched", getenv("PROC_ROOT"));
 	} else {
 		strcpy(name, "/proc/net/psched");
@@ -427,7 +447,7 @@
 		sethostent(1);
 	fflush(stdout);
 
-	if ((h_ent = gethostbyaddr(addr, len, af)) != NULL) 
+	if ((h_ent = gethostbyaddr(addr, len, af)) != NULL)
 		n->name = strdup(h_ent->h_name);
 
 	/* Even if we fail, "negative" entry is remembered. */
@@ -436,7 +456,7 @@
 #endif
 
 
-const char *format_host(int af, int len, const void *addr, 
+const char *format_host(int af, int len, const void *addr,
 			char *buf, int buflen)
 {
 #ifdef RESOLVE_HOSTNAMES