Update header files to 2.6.14
Integrate support for DCCP and tcp_diag into ss
Add -batch to ip command
diff --git a/ip/ip.c b/ip/ip.c
index 3d632ef..af348d8 100644
--- a/ip/ip.c
+++ b/ip/ip.c
@@ -22,6 +22,7 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <string.h>
+#include <errno.h>
 
 #include "SNAPSHOT.h"
 #include "utils.h"
@@ -33,6 +34,9 @@
 int oneline = 0;
 int timestamp = 0;
 char * _SL_ = NULL;
+char *batch_file = NULL;
+int force = 0;
+struct rtnl_handle rth;
 
 static void usage(void) __attribute__((noreturn));
 
@@ -48,6 +52,75 @@
 	exit(-1);
 }
 
+static const struct cmd {
+	const char *cmd;
+	int (*func)(int argc, char **argv);
+} cmds[] = {
+	{ "addr", 	do_ipaddr },
+	{ "maddr",	do_multiaddr },
+	{ "route",	do_iproute },
+	{ "rule",	do_iprule },
+	{ "neigh",	do_ipneigh },
+	{ "link",	do_iplink },
+	{ "tunnel",	do_iptunnel },
+	{ "monitor",	do_ipmonitor },
+	{ "xfrm",	do_xfrm },
+	{ 0 }
+};
+
+static int do_cmd(const char *argv0, int argc, char **argv)
+{
+	const struct cmd *c;
+
+	for (c = cmds; c->cmd; ++c)
+		if (strcmp(c->cmd, argv0) == 0)
+			return c->func(argc-1, argv+1);
+
+	fprintf(stderr, "Object \"%s\" is unknown, try \"ip help\".\n", argv0);
+	exit(-1);
+}
+
+static int batch(const char *name)
+{
+	char *line = NULL;
+	size_t len = 0;
+	int ret = 0;
+	int lineno = 0;
+
+	if (name && strcmp(name, "-") != 0) {
+		if (freopen(name, "r", stdin) == NULL) {
+			fprintf(stderr, "Cannot open file \"%s\" for reading: %s=n",
+				name, strerror(errno));
+			return -1;
+		}
+	}
+
+	if (rtnl_open(&rth, 0) < 0) {
+		fprintf(stderr, "Cannot open rtnetlink\n");
+		return -1;
+	}
+
+	while (getcmdline(&line, &len, stdin) != -1) {
+		char *largv[100];
+		int largc;
+
+		largc = makeargs(line, largv, 100);
+		if (largc == 0)
+			continue;	/* blank line */
+
+		if (do_cmd(largv[0], largc, largv)) {
+			fprintf(stderr, "Command failed %s:%d\n", name, lineno);
+			ret = 1;
+			if (!force)
+				break;
+		}
+	}
+
+	rtnl_close(&rth);
+	return ret;
+}
+
+
 int main(int argc, char **argv)
 {
 	char *basename;
@@ -113,6 +186,14 @@
 		} else if (matches(opt, "-Version") == 0) {
 			printf("ip utility, iproute2-ss%s\n", SNAPSHOT);
 			exit(0);
+		} else if (matches(opt, "-force") == 0) {
+			++force;
+		} else if (matches(opt, "-batch") == 0) {
+			argc--;
+			argv++;
+			if (argc <= 1)
+				usage();
+			batch_file = argv[1];
 		} else if (matches(opt, "-help") == 0) {
 			usage();
 		} else {
@@ -124,52 +205,18 @@
 
 	_SL_ = oneline ? "\\" : "\n" ;
 
-	if (strcmp(basename, "ipaddr") == 0)
-		return do_ipaddr(argc-1, argv+1);
-	if (strcmp(basename, "ipmaddr") == 0)
-		return do_multiaddr(argc-1, argv+1);
-	if (strcmp(basename, "iproute") == 0)
-		return do_iproute(argc-1, argv+1);
-	if (strcmp(basename, "iprule") == 0)
-		return do_iprule(argc-1, argv+1);
-	if (strcmp(basename, "ipneigh") == 0)
-		return do_ipneigh(argc-1, argv+1);
-	if (strcmp(basename, "iplink") == 0)
-		return do_iplink(argc-1, argv+1);
-	if (strcmp(basename, "iptunnel") == 0)
-		return do_iptunnel(argc-1, argv+1);
-	if (strcmp(basename, "ipmonitor") == 0)
-		return do_ipmonitor(argc-1, argv+1);
-	if (strcmp(basename, "ipxfrm") == 0)
-		return do_xfrm(argc-1, argv+1);
+	if (batch_file) 
+		return batch(batch_file);
+		
+	if (rtnl_open(&rth, 0) < 0)
+		exit(1);
 
-	if (argc > 1) {
-		if (matches(argv[1], "address") == 0)
-			return do_ipaddr(argc-2, argv+2);
-		if (matches(argv[1], "maddress") == 0)
-			return do_multiaddr(argc-2, argv+2);
-		if (matches(argv[1], "route") == 0)
-			return do_iproute(argc-2, argv+2);
-		if (matches(argv[1], "rule") == 0)
-			return do_iprule(argc-2, argv+2);
-		if (matches(argv[1], "mroute") == 0)
-			return do_multiroute(argc-2, argv+2);
-		if (matches(argv[1], "neighbor") == 0 ||
-		    matches(argv[1], "neighbour") == 0)
-			return do_ipneigh(argc-2, argv+2);
-		if (matches(argv[1], "link") == 0)
-			return do_iplink(argc-2, argv+2);
-		if (matches(argv[1], "tunnel") == 0 ||
-		    strcmp(argv[1], "tunl") == 0)
-			return do_iptunnel(argc-2, argv+2);
-		if (matches(argv[1], "monitor") == 0)
-			return do_ipmonitor(argc-2, argv+2);
-		if (matches(argv[1], "xfrm") == 0)
-			return do_xfrm(argc-2, argv+2);
-		if (matches(argv[1], "help") == 0)
-			usage();
-		fprintf(stderr, "Object \"%s\" is unknown, try \"ip help\".\n", argv[1]);
-		exit(-1);
-	}
+	if (strlen(basename) > 2) 
+		return do_cmd(basename+2, argc, argv);
+
+	if (argc > 1) 
+		return do_cmd(argv[1], argc-1, argv+1);
+
+	rtnl_close(&rth);
 	usage();
 }