summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbharat <bharat@Build64-bharat.vyatta.com>2012-09-26 15:17:40 -0700
committerbharat <bharat@Build64-bharat.vyatta.com>2012-09-26 15:17:40 -0700
commitc2fea541719c467678f0967f9e2d5e39e505c3a2 (patch)
treee2e26a4ff84eab39d0722b04d9730f5195da92b9
parent6cffc4d634a7a66f04b904f76d88948af6433990 (diff)
downloadvyatta-cfg-quagga-c2fea541719c467678f0967f9e2d5e39e505c3a2.tar.gz
vyatta-cfg-quagga-c2fea541719c467678f0967f9e2d5e39e505c3a2.zip
- Added Multicast and Broadcast checks for route and next hop for static route command.
-rw-r--r--Makefile.am5
-rw-r--r--src/check_next_hop.c65
-rw-r--r--src/check_prefix_boundary.c85
-rw-r--r--src/check_ucast_static.c38
-rw-r--r--src/check_ucast_static.h58
-rw-r--r--templates/protocols/static/route/node.def2
-rw-r--r--templates/protocols/static/route/node.tag/next-hop/node.def1
-rw-r--r--templates/protocols/static/route6/node.def2
-rw-r--r--templates/protocols/static/route6/node.tag/next-hop/node.def2
9 files changed, 196 insertions, 62 deletions
diff --git a/Makefile.am b/Makefile.am
index 9dfe6451..cdff2263 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -12,11 +12,12 @@ sbin_SCRIPTS += scripts/vyatta-gateway-static_route-check.pl
sbin_SCRIPTS += scripts/vyatta-link-detect
sbin_SCRIPTS += scripts/vyatta-next-hop-check
-sbin_PROGRAMS = src/check_prefix_boundary
+sbin_PROGRAMS := check_prefix_boundary check_next_hop
share_perl5_DATA = lib/Vyatta/Quagga/Config.pm
-src_check_prefix_boundary = src/check_prefix_boundary.c
+check_prefix_boundary_SOURCES := src/check_prefix_boundary.c src/check_ucast_static.c
+check_next_hop_SOURCES := src/check_next_hop.c src/check_ucast_static.c
curver_DATA = cfg-version/quagga@2
diff --git a/src/check_next_hop.c b/src/check_next_hop.c
new file mode 100644
index 00000000..0730c43e
--- /dev/null
+++ b/src/check_next_hop.c
@@ -0,0 +1,65 @@
+#include "check_ucast_static.h"
+
+static void usage(void)
+{
+ fprintf(stderr, "Usage: check_next_hop [-4|-6] address\n");
+ exit(1);
+}
+
+static void get_prefix_1(inet_prefix *dst, char *arg, int family)
+{
+
+ memset(dst, 0, sizeof(*dst));
+ get_addr_1(dst, arg, family);
+
+}
+
+int main(int argc, char **argv)
+{
+ int family = AF_UNSPEC;
+
+ while (--argc) {
+ char *arg = *++argv;
+ inet_prefix dst;
+
+ if (arg[0] == '-') {
+ switch(arg[1]) {
+ case '4':
+ family = AF_INET;
+ break;
+ case '6':
+ family = AF_INET6;
+ break;
+ default:
+ usage();
+ }
+ continue;
+ }
+
+ get_prefix_1(&dst, arg, family);
+
+ /*
+ * Macros to check for Mcast are based on:
+ *
+ * Addr dst.data
+ * 224.1.2.2 ==> 0x030201e0
+ * ff01:0203:: ==> 0x030201ff
+ *
+ */
+ if (family == AF_INET) {
+ if (IS_MULTICAST(dst.data[0])) {
+ err("Invalid next_hop...next_hop cannot be multicast\n");
+ }
+ if (IS_BROADCAST(dst.data[0])) {
+ err("Invalid next_hop...next_hop cannot be broadcast\n");
+ }
+ } else if (family == AF_INET6) {
+ if (IS_IPV6_MULTICAST(dst.data[0])) {
+ err("Invalid next_hop...next_hop cannot be IPv6 multicast\n");
+ }
+ }
+
+ }
+
+ return 0;
+}
diff --git a/src/check_prefix_boundary.c b/src/check_prefix_boundary.c
index 1c9ee30a..b432c788 100644
--- a/src/check_prefix_boundary.c
+++ b/src/check_prefix_boundary.c
@@ -1,33 +1,4 @@
-/*
- * Check format of network prefix
- */
-#include <stdio.h>
-#include <stdarg.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-
-typedef struct
-{
- uint8_t family;
- uint8_t bytelen;
- unsigned int plen;
- uint32_t data[4];
-} inet_prefix;
-
-static void err(const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
-
- exit(1);
-}
+#include "check_ucast_static.h"
static void usage(void)
{
@@ -35,32 +6,6 @@ static void usage(void)
exit(1);
}
-static void get_addr_1(inet_prefix *addr, const char *name, int family)
-{
- memset(addr, 0, sizeof(*addr));
-
- if (strchr(name, ':')) {
- addr->family = AF_INET6;
- addr->bytelen = 16;
- if (family != AF_UNSPEC && family != AF_INET6)
- err("IPV6 address not allowed\n");
-
- if (inet_pton(AF_INET6, name, addr->data) <= 0)
- err("Invalid IPV6 address: %s\n", name);
-
- return;
- }
-
- addr->family = AF_INET;
- addr->bytelen = 4;
- if (family != AF_UNSPEC && family != AF_INET)
- err("IPV4 address not allowed\n");
-
- if (inet_pton(AF_INET, name, addr->data) <= 0)
- err("Invalid IPV4 address: %s\n", name);
- return;
-}
-
static void get_prefix_1(inet_prefix *dst, char *arg, int family)
{
char *slash, *endp;
@@ -103,12 +48,12 @@ static void get_netmask(inet_prefix *msk, const inet_prefix *dst)
int main(int argc, char **argv)
{
int family = AF_UNSPEC;
-
+
while (--argc) {
char *arg = *++argv;
inet_prefix dst, msk;
- if (arg[0] == '-')
+ if (arg[0] == '-') {
switch(arg[1]) {
case '4':
family = AF_INET;
@@ -119,6 +64,8 @@ int main(int argc, char **argv)
default:
usage();
}
+ continue;
+ }
get_prefix_1(&dst, arg, family);
get_netmask(&msk, &dst);
@@ -129,6 +76,28 @@ int main(int argc, char **argv)
"Did you mean %s?\n",
inet_ntop(msk.family, msk.data, buf, sizeof buf));
}
+
+ /*
+ * Macros to check for Mcast are based on:
+ *
+ * Addr dst.data
+ * 224.1.2.2 ==> 0x030201e0
+ * ff01:0203:: ==> 0x030201ff
+ *
+ */
+ if (family == AF_INET) {
+ if (IS_MULTICAST(dst.data[0])) {
+ err("Invalid Prefix...Route cannot be Multicast\n");
+ }
+ if (IS_BROADCAST(dst.data[0])) {
+ err("Invalid Prefix...Route cannot be Broadcast\n");
+ }
+ } else if (family == AF_INET6) {
+ if (IS_IPV6_MULTICAST(dst.data[0])) {
+ err("Invalid Prefix...Route cannot be IPv6 Multicast\n");
+ }
+ }
+
}
return 0;
diff --git a/src/check_ucast_static.c b/src/check_ucast_static.c
new file mode 100644
index 00000000..d3c4e557
--- /dev/null
+++ b/src/check_ucast_static.c
@@ -0,0 +1,38 @@
+#include "check_ucast_static.h"
+
+void get_addr_1(inet_prefix *addr, const char *name, int family)
+{
+ memset(addr, 0, sizeof(*addr));
+
+ if (strchr(name, ':')) {
+ addr->family = AF_INET6;
+ addr->bytelen = 16;
+ if (family != AF_UNSPEC && family != AF_INET6)
+ err("IPV6 address not allowed\n");
+
+ if (inet_pton(AF_INET6, name, addr->data) <= 0)
+ err("Invalid IPV6 address: %s\n", name);
+
+ return;
+ }
+
+ addr->family = AF_INET;
+ addr->bytelen = 4;
+ if (family != AF_UNSPEC && family != AF_INET)
+ err("IPV4 address not allowed\n");
+
+ if (inet_pton(AF_INET, name, addr->data) <= 0)
+ err("Invalid IPV4 address: %s\n", name);
+ return;
+}
+
+void err(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+
+ exit(1);
+}
diff --git a/src/check_ucast_static.h b/src/check_ucast_static.h
new file mode 100644
index 00000000..e5d87ade
--- /dev/null
+++ b/src/check_ucast_static.h
@@ -0,0 +1,58 @@
+/*
+ * Check format of network prefix
+ */
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+
+#define IS_CLASSD(a) ((((uint32_t)(a)) & 0x000000f0) == 0x000000e0)
+#define IS_MULTICAST(a) IS_CLASSD(a)
+#define IS_BROADCAST(a) ((((uint32_t)(a)) & 0xffffffff) == 0xffffffff)
+
+#define IS_IPV6_MULTICAST(a) ((((uint32_t)(a)) & 0x000000ff) == 0x000000ff)
+
+
+typedef struct
+{
+ uint8_t family;
+ uint8_t bytelen;
+ unsigned int plen;
+ uint32_t data[4];
+} inet_prefix;
+
+void get_addr_1(inet_prefix *addr, const char *name, int family);
+void err(const char *fmt, ...);
+
+/*
+static void get_addr_1(inet_prefix *addr, const char *name, int family)
+{
+ memset(addr, 0, sizeof(*addr));
+
+ if (strchr(name, ':')) {
+ addr->family = AF_INET6;
+ addr->bytelen = 16;
+ if (family != AF_UNSPEC && family != AF_INET6)
+ err("IPV6 address not allowed\n");
+
+ if (inet_pton(AF_INET6, name, addr->data) <= 0)
+ err("Invalid IPV6 address: %s\n", name);
+
+ return;
+ }
+
+ addr->family = AF_INET;
+ addr->bytelen = 4;
+ if (family != AF_UNSPEC && family != AF_INET)
+ err("IPV4 address not allowed\n");
+
+ if (inet_pton(AF_INET, name, addr->data) <= 0)
+ err("Invalid IPV4 address: %s\n", name);
+ return;
+}
+*/
+void err(const char *fmt, ...);
diff --git a/templates/protocols/static/route/node.def b/templates/protocols/static/route/node.def
index 682ca944..ced516ea 100644
--- a/templates/protocols/static/route/node.def
+++ b/templates/protocols/static/route/node.def
@@ -1,7 +1,7 @@
tag:
type: ipv4net
help: Static route
-syntax:expression: exec "${vyatta_sbindir}/check_prefix_boundary $VAR(@)"
+syntax:expression: exec "${vyatta_sbindir}/check_prefix_boundary -4 $VAR(@)"
commit:expression: $VAR(./next-hop/) != "" || $VAR(./blackhole/) != ""; \
"Must add either a next-hop or blackhole for route $VAR(@)"
diff --git a/templates/protocols/static/route/node.tag/next-hop/node.def b/templates/protocols/static/route/node.tag/next-hop/node.def
index f5d5d417..89d00664 100644
--- a/templates/protocols/static/route/node.tag/next-hop/node.def
+++ b/templates/protocols/static/route/node.tag/next-hop/node.def
@@ -1,6 +1,7 @@
tag:
type: ipv4
help: Next-hop router [REQUIRED]
+syntax:expression: exec "${vyatta_sbindir}/check_next_hop -4 $VAR(@)"
end:
if [[ -z "$VAR(./disable)" ]]
then
diff --git a/templates/protocols/static/route6/node.def b/templates/protocols/static/route6/node.def
index de3f1cd8..bba42943 100644
--- a/templates/protocols/static/route6/node.def
+++ b/templates/protocols/static/route6/node.def
@@ -1,7 +1,7 @@
tag:
type: ipv6net
help: Static IPv6 route
-syntax:expression: exec "${vyatta_sbindir}/check_prefix_boundary $VAR(@)"
+syntax:expression: exec "${vyatta_sbindir}/check_prefix_boundary -6 $VAR(@)"
commit:expression: $VAR(./next-hop/) != "" || $VAR(./blackhole/) != ""; \
"Must add either a next-hop or blackhole for route $VAR(@)"
diff --git a/templates/protocols/static/route6/node.tag/next-hop/node.def b/templates/protocols/static/route6/node.tag/next-hop/node.def
index e3a668b7..82bc78a8 100644
--- a/templates/protocols/static/route6/node.tag/next-hop/node.def
+++ b/templates/protocols/static/route6/node.tag/next-hop/node.def
@@ -4,6 +4,8 @@ type: ipv6
help: Next-hop IPv6 router [REQUIRED]
+syntax:expression: exec "${vyatta_sbindir}/check_next_hop -6 $VAR(@)"
+
end:
if [[ -z "$VAR(./disable)" ]]
then