Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OSPF: print the Extended Link Opaque TLV and subTLVs #1204

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CREDITS
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ Additional people who have contributed patches (in alphabetical order):
Nicolas Ferrero <toorop at babylo dot net>
Niels Provos <provos at openbsd dot org>
Nikhil AP <nikhilap at arista dot com>
Nikhil Goyal <nikhilg at arista dot com
Nikolay Edigaryev <edigaryev at gmail dot com>
niks3089 <niks3089 at gmail dot com>
Noritoshi Demizu <demizu at users dot sourceforge dot net>
Expand Down
17 changes: 17 additions & 0 deletions ospf.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,16 @@
#define LS_OPAQUE_RI_TLV_SR_LOCAL_BLOCK 14 /* rfc8865 */
#define LS_OPAQUE_RI_TLV_SRMS_PREFERENCE 15 /* rfc8865 */

#define LS_OPAQUE_EXTENDED_LINK_TLV 1 /* rfc7684 */

#define LS_OPAQUE_EXTENDED_LINK_SUBTLV_ADJ_SID 2 /* rfc8665 */

#define LS_OPAQUE_EXTENDED_LINK_SUBTLV_ADJ_SID_FLAG_B 0x80
#define LS_OPAQUE_EXTENDED_LINK_SUBTLV_ADJ_SID_FLAG_V 0x40
#define LS_OPAQUE_EXTENDED_LINK_SUBTLV_ADJ_SID_FLAG_L 0x20
#define LS_OPAQUE_EXTENDED_LINK_SUBTLV_ADJ_SID_FLAG_G 0x10
#define LS_OPAQUE_EXTENDED_LINK_SUBTLV_ADJ_SID_FLAG_P 0x8

/* rla_link.link_type */
#define RLA_TYPE_ROUTER 1 /* point-to-point to another router */
#define RLA_TYPE_TRANSIT 2 /* connection to transit network */
Expand Down Expand Up @@ -266,6 +276,13 @@ struct lsa {
nd_byte data[1]; /* may repeat */
} un_ep_tlv[1]; /* may repeat */

/* Extended Link LSA */
struct {
nd_uint16_t type;
nd_uint16_t length;
nd_byte data[1]; /* may repeat */
} un_el_tlv[1]; /* may repeat */

/* Unknown LSA */
struct unknown {
nd_byte data[1]; /* may repeat */
Expand Down
141 changes: 141 additions & 0 deletions print-ospf.c
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,33 @@ static const struct tok lsa_opaque_ri_tlv_sr_algos[] = {
{ 0, NULL }
};

static const struct tok lsa_opaque_el_tlv_values[] = {
{ LS_OPAQUE_EXTENDED_LINK_TLV, "Extended Link" },
{ 0, NULL }
};

static const struct tok lsa_opaque_extended_link_link_type_values[] = {
{ RLA_TYPE_ROUTER, "Point-to-Point Link" },
{ RLA_TYPE_TRANSIT, "Link to Transit Network" },
{ RLA_TYPE_STUB, "Link to Stub Network" },
{ RLA_TYPE_VIRTUAL, "Virtual Link" },
{ 0, NULL }
};

static const struct tok lsa_opaque_extended_link_subtlv_adj_sid_flag_values[] = {
{ LS_OPAQUE_EXTENDED_LINK_SUBTLV_ADJ_SID_FLAG_B, "Backup" },
{ LS_OPAQUE_EXTENDED_LINK_SUBTLV_ADJ_SID_FLAG_V, "Value/Index" },
{ LS_OPAQUE_EXTENDED_LINK_SUBTLV_ADJ_SID_FLAG_L, "Local/Global" },
{ LS_OPAQUE_EXTENDED_LINK_SUBTLV_ADJ_SID_FLAG_G, "Group" },
{ LS_OPAQUE_EXTENDED_LINK_SUBTLV_ADJ_SID_FLAG_P, "Persistent" },
{ 0, NULL }
};

static const struct tok lsa_opaque_extended_link_subtlv_values[] = {
{ LS_OPAQUE_EXTENDED_LINK_SUBTLV_ADJ_SID, "Adj-SID Sub-TLV" },
{ 0, NULL }
};

static const struct tok ospf_lls_tlv_values[] = {
{ OSPF_LLS_EO, "Extended Options" },
{ OSPF_LLS_MD5, "MD5 Authentication" },
Expand Down Expand Up @@ -930,6 +957,113 @@ ospf_ep_lsa_print(netdissect_options *ndo, const uint8_t *tptr, u_int lsa_length
return 0;
}

static int
ospf_el_lsa_print(netdissect_options *ndo, const uint8_t *tptr, u_int lsa_length)
{
u_int tlv_type, tlv_length, link_type, sub_tlv_flags;
u_int sub_tlv_type, sub_tlv_length, sub_tlv_remaining;
const uint8_t *sub_tlv_tptr;
u_int vflag, lflag;

while (lsa_length >= 4) {
tlv_type = GET_BE_U_2(tptr);
tlv_length = GET_BE_U_2(tptr+2);
tptr+=4;
lsa_length-=4;

/* Infinite loop protection. */
if (tlv_type == 0 || tlv_length == 0) {
return -1;
}

ND_PRINT("\n\t %s TLV (%u), length: %u, value: ",
tok2str(lsa_opaque_el_tlv_values,"unknown",tlv_type),
tlv_type,
tlv_length);

switch (tlv_type) {
case LS_OPAQUE_EXTENDED_LINK_TLV:
link_type = GET_U_1(tptr);

ND_PRINT("\n\t Link Type: %s (%u)",
tok2str(lsa_opaque_extended_link_link_type_values,"unknown",link_type),
link_type);
ND_PRINT("\n\t Reserved: %u", GET_BE_U_3(tptr+1));
ND_PRINT("\n\t Link ID: %s", GET_IPADDR_STRING(tptr+4));
ND_PRINT("\n\t Link Data: %s", GET_IPADDR_STRING(tptr+8));

sub_tlv_tptr = tptr + 12;
sub_tlv_remaining = tlv_length - 12;

while(sub_tlv_remaining > 0) {
sub_tlv_type = GET_BE_U_2(sub_tlv_tptr);
sub_tlv_length = GET_BE_U_2(sub_tlv_tptr + 2);
sub_tlv_remaining-=4;
sub_tlv_tptr+=4;

ND_PRINT("\n\t %s (%u), length: %u, value: ",
tok2str(lsa_opaque_extended_link_subtlv_values,"unknown",sub_tlv_type),
sub_tlv_type,
sub_tlv_length);

switch(sub_tlv_type){

case LS_OPAQUE_EXTENDED_LINK_SUBTLV_ADJ_SID:
sub_tlv_flags = GET_U_1(sub_tlv_tptr);

ND_PRINT("\n\t Flags: [%s]",
bittok2str(lsa_opaque_extended_link_subtlv_adj_sid_flag_values, "none", sub_tlv_flags));
ND_PRINT("\n\t Reserved: %u", GET_U_1(sub_tlv_tptr+1));
ND_PRINT("\n\t MT-ID: %u", GET_U_1(sub_tlv_tptr+2));
ND_PRINT("\n\t Weight: %u", GET_U_1(sub_tlv_tptr+3));

vflag = sub_tlv_flags & LS_OPAQUE_EXTENDED_LINK_SUBTLV_ADJ_SID_FLAG_V;
lflag = sub_tlv_flags & LS_OPAQUE_EXTENDED_LINK_SUBTLV_ADJ_SID_FLAG_L;
if (vflag && lflag) {
ND_PRINT("\n\t SID/Label: %u",GET_BE_U_3(sub_tlv_tptr + 4));
}
else if ( !vflag && !lflag ) {
ND_PRINT("\n\t SID/Label: %u",GET_BE_U_4(sub_tlv_tptr + 4));
}
else {
ND_PRINT("\n\t Invalid V-Flag and L-flag combination");
if (!print_unknown_data(ndo, sub_tlv_tptr, "\n\t ", sub_tlv_length))
return(-1);
}
break;

default:
if (ndo->ndo_vflag <= 1) {
if (!print_unknown_data(ndo, sub_tlv_tptr, "\n\t ", sub_tlv_length))
return(-1);
}
break;
}

if (sub_tlv_length % 4) {
sub_tlv_length += (4 - (sub_tlv_length % 4));
}
sub_tlv_tptr+=sub_tlv_length;
sub_tlv_remaining-=sub_tlv_length;
}
break;
default:
if (ndo->ndo_vflag <= 1) {
if (!print_unknown_data(ndo, tptr, "\n\t ", tlv_length))
return -1;
}
}

/* in OSPF everything has to be 32-bit aligned, including TLVs */
if (tlv_length % 4) {
tlv_length += (4 - (tlv_length % 4));
}
tptr+=tlv_length;
lsa_length-=tlv_length;
}
return 0;
}

/*
* Print a single link state advertisement. If truncated or if LSA length
* field is less than the length of the LSA header, return NULl, else
Expand Down Expand Up @@ -1231,6 +1365,13 @@ ospf_print_lsa(netdissect_options *ndo,
}
break;

case LS_OPAQUE_TYPE_EL:
if (ospf_el_lsa_print(ndo, (const u_char *)(lsap->lsa_un.un_el_tlv),
ls_length) == -1) {
return(ls_end);
}
break;

default:
if (ndo->ndo_vflag <= 1) {
if (!print_unknown_data(ndo, (const uint8_t *)lsap->lsa_un.un_unknown,
Expand Down
1 change: 1 addition & 0 deletions tests/TESTLIST
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ ospf-ack ospf-ack.pcap ospf-ack.out -v
ospf-sr ospf-sr.pcapng ospf-sr-v.out -v
ospf-sr2 ospf-sr2.pcapng ospf-sr2-v.out -v
ospf-sr-ri-sid ospf-sr-ri-sid.pcap ospf-sr-ri-sid-v.out -v
ospf-sr-link ospf-sr-link.pcap ospf-sr-link-v.out -v
ospf3_ah-vv OSPFv3_with_AH.pcap ospf3_ah-vv.out -v -v
ospf3_auth-vv ospf3_auth.pcapng ospf3_auth-vv.out -v -v
ospf3_bc-vv OSPFv3_broadcast_adjacency.pcap ospf3_bc-vv.out -v -v
Expand Down
Loading