Commit d7724cb0 authored by Matthieu Boutier's avatar Matthieu Boutier

Parse Source-Specific Update TLV.

parent 9506268a
...@@ -586,6 +586,93 @@ parse_packet(const unsigned char *from, struct interface *ifp, ...@@ -586,6 +586,93 @@ parse_packet(const unsigned char *from, struct interface *ifp,
format_eui64(message + 8), seqno); format_eui64(message + 8), seqno);
handle_request(neigh, prefix, plen, message[6], handle_request(neigh, prefix, plen, message[6],
seqno, message + 8); seqno, message + 8);
} else if(type == MESSAGE_UPDATE_SRC_SPECIFIC) {
unsigned char prefix[16], src_prefix[16], *nh;
unsigned char ae, plen, src_plen, omitted;
unsigned char channels[DIVERSITY_HOPS];
unsigned short interval, seqno, metric;
const unsigned char *src_prefix_beginning = NULL;
int rc, parsed_len = 0;
if(len < 10)
goto fail;
ae = message[2];
src_plen = message[3];
plen = message[4];
omitted = message[5];
DO_NTOHS(interval, message + 6);
DO_NTOHS(seqno, message + 8);
DO_NTOHS(metric, message + 10);
if(omitted == 0 || (ae == 1 ? have_v4_prefix : have_v6_prefix))
rc = network_prefix(ae, plen, omitted, message + 12,
ae == 1 ? v4_prefix : v6_prefix,
len - 10, prefix);
else
rc = -1;
if(rc < 0)
goto fail;
parsed_len = 10 + rc;
src_prefix_beginning = message + 2 + parsed_len;
rc = network_prefix(ae, src_plen, 0, src_prefix_beginning, NULL,
len - parsed_len, src_prefix);
if(rc < 0)
goto fail;
parsed_len += rc;
if(ae == 1) {
plen += 96;
src_plen += 96;
}
if(!have_router_id) {
fprintf(stderr, "Received prefix with no router id.\n");
goto fail;
}
debugf("Received ss-update for (%s from %s) from %s on %s.\n",
format_prefix(prefix, plen),
format_prefix(src_prefix, src_plen),
format_address(from), ifp->name);
if(ae == 0) {
debugf("Received invalid Source-Specific wildcard update.\n");
retract_neighbour_routes(neigh);
goto done;
} else if(ae == 1) {
if(!have_v4_nh)
goto fail;
nh = v4_nh;
} else if(have_v6_nh) {
nh = v6_nh;
} else {
nh = neigh->address;
}
if(ae == 1) {
if(!ifp->ipv4)
goto done;
}
if((ifp->flags & IF_FARAWAY)) {
channels[0] = 0;
} else {
/* This will be overwritten by parse_update_subtlv below. */
if(metric < 256) {
/* Assume non-interfering (wired) link. */
channels[0] = 0;
} else {
/* Assume interfering. */
channels[0] = IF_CHANNEL_INTERFERING;
channels[1] = 0;
}
if(parsed_len < len)
parse_update_subtlv(message + 2 + parsed_len,
len - parsed_len, channels);
}
update_route(router_id, prefix, plen, src_prefix, src_plen,
seqno, metric, interval, neigh, nh,
channels, channels_len(channels));
} else { } else {
debugf("Received unknown packet type %d from %s on %s.\n", debugf("Received unknown packet type %d from %s on %s.\n",
type, format_address(from), ifp->name); type, format_address(from), ifp->name);
......
...@@ -39,6 +39,8 @@ THE SOFTWARE. ...@@ -39,6 +39,8 @@ THE SOFTWARE.
#define MESSAGE_UPDATE 8 #define MESSAGE_UPDATE 8
#define MESSAGE_REQUEST 9 #define MESSAGE_REQUEST 9
#define MESSAGE_MH_REQUEST 10 #define MESSAGE_MH_REQUEST 10
/* 11 and 12 are for authentication */
#define MESSAGE_UPDATE_SRC_SPECIFIC 13
/* Protocol extension through sub-TLVs. */ /* Protocol extension through sub-TLVs. */
#define SUBTLV_PAD1 0 #define SUBTLV_PAD1 0
......
...@@ -828,7 +828,7 @@ update_route(const unsigned char *id, ...@@ -828,7 +828,7 @@ update_route(const unsigned char *id,
int metric, feasible; int metric, feasible;
int add_metric; int add_metric;
int hold_time = MAX((4 * interval) / 100 + interval / 50, 15); int hold_time = MAX((4 * interval) / 100 + interval / 50, 15);
int is_v4;
if(memcmp(id, myid, 8) == 0) if(memcmp(id, myid, 8) == 0)
return NULL; return NULL;
...@@ -837,6 +837,17 @@ update_route(const unsigned char *id, ...@@ -837,6 +837,17 @@ update_route(const unsigned char *id,
format_prefix(prefix, plen), format_address(nexthop)); format_prefix(prefix, plen), format_address(nexthop));
return NULL; return NULL;
} }
if(src_plen != 0 && martian_prefix(src_prefix, src_plen)) {
fprintf(stderr, "Rejecting martian route to %s from %s through %s.\n",
format_prefix(prefix, plen),
format_prefix(src_prefix, src_plen), format_eui64(id));
return NULL;
}
is_v4 = v4mapped(prefix);
if(src_plen != 0 && is_v4 != v4mapped(src_prefix))
return NULL;
add_metric = input_filter(id, prefix, plen, add_metric = input_filter(id, prefix, plen,
src_prefix, src_plen, src_prefix, src_plen,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment