Merge pull request #13354 from zmw12306/parse_request_subtlv

babeld: add parse_request_subtlv into parse_packet
This commit is contained in:
Russ White 2023-05-02 10:28:20 -04:00 committed by GitHub
commit c12a40fee3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 96 additions and 2 deletions

View File

@ -48,6 +48,13 @@ static const unsigned char tlv_min_length[MESSAGE_MAX + 1] =
[ MESSAGE_MH_REQUEST ] = 14,
};
/* Checks whether an AE exists or must be silently ignored */
static bool
known_ae(int ae)
{
return ae <= 4;
}
/* Parse a network prefix, encoded in the somewhat baroque compressed
representation used by Babel. Return the number of bytes parsed. */
static int
@ -276,6 +283,62 @@ parse_ihu_subtlv(const unsigned char *a, int alen,
return ret;
}
static int
parse_request_subtlv(int ae, const unsigned char *a, int alen,
unsigned char *src_prefix, unsigned char *src_plen)
{
int type, len, i = 0;
int have_src_prefix = 0;
while(i < alen) {
type = a[0];
if(type == SUBTLV_PAD1) {
i++;
continue;
}
if(i + 2 > alen)
goto fail;
len = a[i + 1];
if(i + 2 + len > alen)
goto fail;
if(type == SUBTLV_PADN) {
/* Nothing to do. */
} else if(type == SUBTLV_SOURCE_PREFIX) {
int rc;
if(len < 1)
goto fail;
if(a[i + 2] == 0)
goto fail;
if(have_src_prefix != 0)
goto fail;
rc = network_prefix(ae, a[i + 2], 0, a + i + 3, NULL,
len - 1, src_prefix);
if(rc < 0)
goto fail;
if(ae==1)
*src_plen = a[i + 2] + 96;
else
*src_plen = a[i + 2];
have_src_prefix = 1;
} else {
debugf(BABEL_DEBUG_COMMON,"Received unknown%s Route Request sub-TLV %d.",
((type & 0x80) != 0) ? " mandatory" : "", type);
if((type & 0x80) != 0)
return -1;
}
i += len + 2;
}
return 1;
fail:
flog_err(EC_BABEL_PACKET, "Received truncated sub-TLV on Route Request.");
return -1;
}
static int
network_address(int ae, const unsigned char *a, unsigned int len,
unsigned char *a_r)
@ -612,8 +675,14 @@ parse_packet(const unsigned char *from, struct interface *ifp,
interval, neigh, nh, channels,
channels_len(channels));
} else if(type == MESSAGE_REQUEST) {
unsigned char prefix[16], plen;
int rc;
unsigned char prefix[16], src_prefix[16], plen, src_plen;
int rc, is_ss;
if(len < 2) goto fail;
if(!known_ae(message[2])) {
debugf(BABEL_DEBUG_COMMON,"Received request with unknown AE %d. Ignoring.",
message[2]);
goto done;
}
rc = network_prefix(message[2], message[3], 0,
message + 4, NULL, len - 2, prefix);
if(rc < 0) goto fail;
@ -621,8 +690,26 @@ parse_packet(const unsigned char *from, struct interface *ifp,
debugf(BABEL_DEBUG_COMMON,"Received request for %s from %s on %s.",
message[2] == 0 ? "any" : format_prefix(prefix, plen),
format_address(from), ifp->name);
if(message[2] == 1) {
v4tov6(src_prefix, zeroes);
src_plen = 96;
} else {
memcpy(src_prefix, zeroes, 16);
src_plen = 0;
}
rc = parse_request_subtlv(message[2], message + 4 + rc,
len - 2 - rc, src_prefix, &src_plen);
if(rc < 0)
goto done;
is_ss = !is_default(src_prefix, src_plen);
if(message[2] == 0) {
struct babel_interface *neigh_ifp =babel_get_if_nfo(neigh->ifp);
if(is_ss) {
/* Wildcard requests don't carry a source prefix. */
flog_err(EC_BABEL_PACKET,
"Received source-specific wildcard request.");
goto done;
}
/* If a neighbour is requesting a full route dump from us,
we might as well send it an IHU. */
send_ihu(neigh, NULL);

View File

@ -34,6 +34,7 @@ Copyright (c) 2007, 2008 by Juliusz Chroboczek
#define SUBTLV_PADN 1
#define SUBTLV_DIVERSITY 2 /* Also known as babelz. */
#define SUBTLV_TIMESTAMP 3 /* Used to compute RTT. */
#define SUBTLV_SOURCE_PREFIX 128 /* Source-specific routing. */
#define SUBTLV_MANDATORY 0x80
extern unsigned short myseqno;

View File

@ -104,6 +104,12 @@ void uchar_to_in6addr(struct in6_addr *dest, const unsigned char *src);
int daemonise(void);
extern const unsigned char v4prefix[16];
static inline bool
is_default(const unsigned char *prefix, int plen)
{
return plen == 0 || (plen == 96 && v4mapped(prefix));
}
/* If debugging is disabled, we want to avoid calling format_address
for every omitted debugging message. So debug is a macro. But
vararg macros are not portable. */