mirror of
https://github.com/rtbrick/bngblaster.git
synced 2024-05-06 15:54:57 +00:00
Merge branch 'ospf_dev' into dev
This commit is contained in:
+188
-7
@@ -97,7 +97,7 @@ struct keyval_ log_names[] = {
|
||||
struct keyval_ proto_names[] = {
|
||||
{ PROTO_ISIS, "isis" },
|
||||
{ PROTO_OSPF2, "ospf2" },
|
||||
//{ PROTO_OSPF3, "ospf3" },
|
||||
{ PROTO_OSPF3, "ospf3" },
|
||||
{ 0, NULL}
|
||||
};
|
||||
|
||||
@@ -466,7 +466,7 @@ lspgen_gen_isis_attr(struct lsdb_ctx_ *ctx)
|
||||
|
||||
/* ipv6 external prefix */
|
||||
lsdb_reset_attr_template(&attr_template);
|
||||
lspgen_store_addr(ext_addr6, attr_template.key.prefix.ipv6_prefix.address, 16);
|
||||
lspgen_store_addr(ext_addr6, attr_template.key.prefix.ipv6_prefix.address, IPV6_ADDR_LEN);
|
||||
attr_template.key.prefix.ipv6_prefix.len = ctx->ipv6_ext_prefix.len;
|
||||
attr_template.key.prefix.metric = 100;
|
||||
attr_template.key.attr_type = ISIS_TLV_EXTD_IPV6_REACH;
|
||||
@@ -607,7 +607,8 @@ lspgen_gen_ospf2_attr(struct lsdb_ctx_ *ctx)
|
||||
attr_template.key.ordinal = 1;
|
||||
attr_template.key.attr_cp[0] = OSPF_MSG_LSUPDATE;
|
||||
attr_template.key.attr_cp[1] = OSPF_LSA_OPAQUE_AREA_EP;
|
||||
attr_template.key.attr_cp[2] = OSPF_TLV_EXTENDED_PREFIX_RANGE;
|
||||
attr_template.key.attr_cp[2] = OSPF_TLV_EXTENDED_PREFIX;
|
||||
attr_template.key.attr_cp[3] = OSPF_SUBTLV_EXTENDED_PREFIX_SID;;
|
||||
lsdb_add_node_attr(node, &attr_template);
|
||||
}
|
||||
addr += node->node_index;
|
||||
@@ -650,7 +651,7 @@ lspgen_gen_ospf2_attr(struct lsdb_ctx_ *ctx)
|
||||
CIRCLEQ_FOREACH(link, &node->link_qhead, link_qnode) {
|
||||
|
||||
/*
|
||||
* Is this a conncetor link ?
|
||||
* Is this a connector link ?
|
||||
*/
|
||||
if (link->key.remote_node_id[7] == CONNECTOR_MARKER) {
|
||||
lsdb_reset_attr_template(&attr_template);
|
||||
@@ -711,6 +712,185 @@ lspgen_gen_ospf2_attr(struct lsdb_ctx_ *ctx)
|
||||
dict_itor_free(itor);
|
||||
}
|
||||
|
||||
/*
|
||||
* Walk the graph of the LSDB and add the required node/link attributes for OSPFv3 LSP generation.
|
||||
*/
|
||||
void
|
||||
lspgen_gen_ospf3_attr(struct lsdb_ctx_ *ctx)
|
||||
{
|
||||
struct lsdb_node_ *node;
|
||||
struct lsdb_link_ *link;
|
||||
struct lsdb_attr_ attr_template;
|
||||
dict_itor *itor;
|
||||
__uint128_t addr, inc, ext_addr6, ext_incr6, addr_offset;
|
||||
uint32_t ext_per_node, metric, nodes_left, ext_left;
|
||||
|
||||
/*
|
||||
* Walk the node DB.
|
||||
*/
|
||||
itor = dict_itor_new(ctx->node_dict);
|
||||
if (!itor) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Node DB empty ?
|
||||
*/
|
||||
if (!dict_itor_first(itor)) {
|
||||
dict_itor_free(itor);
|
||||
LOG_NOARG(ERROR, "Empty LSDB.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* For external routes load the first address of the pool.
|
||||
*/
|
||||
ext_addr6 = lspgen_load_addr((uint8_t*)&ctx->ipv6_ext_prefix.address, IPV6_ADDR_LEN);
|
||||
ext_incr6 = lspgen_get_prefix_inc(AF_INET6, ctx->ipv6_ext_prefix.len);
|
||||
|
||||
nodes_left = ctx->num_nodes;
|
||||
ext_left = ctx->num_ext;
|
||||
|
||||
do {
|
||||
node = *dict_itor_datum(itor);
|
||||
|
||||
/* Host name */
|
||||
if (node->node_name) {
|
||||
lsdb_reset_attr_template(&attr_template);
|
||||
//attr_template.key.ordinal = 1;
|
||||
attr_template.key.attr_cp[0] = OSPF_MSG_LSUPDATE;
|
||||
attr_template.key.attr_cp[1] = OSPF_LSA_OPAQUE_AREA_RI;
|
||||
attr_template.key.attr_cp[2] = OSPF_TLV_HOSTNAME;
|
||||
strncpy(attr_template.key.hostname, node->node_name, sizeof(attr_template.key.hostname)-1);
|
||||
lsdb_add_node_attr(node, &attr_template);
|
||||
}
|
||||
|
||||
/* IPv6 loopback prefix */
|
||||
lsdb_reset_attr_template(&attr_template);
|
||||
addr = lspgen_load_addr((uint8_t*)&ctx->ipv6_node_prefix.address, IPV6_ADDR_LEN);
|
||||
lspgen_store_addr(addr, attr_template.key.prefix.ipv6_prefix.address, IPV6_ADDR_LEN);
|
||||
attr_template.key.prefix.ipv6_prefix.len = ctx->ipv6_node_prefix.len;
|
||||
attr_template.key.attr_cp[0] = OSPF_MSG_LSUPDATE;
|
||||
attr_template.key.attr_cp[1] = OSPF_LSA_INTRA_AREA_PREFIX;
|
||||
attr_template.key.attr_cp[2] = OSPF_IA_PREFIX_LSA_PREFIX;
|
||||
lsdb_add_node_attr(node, &attr_template);
|
||||
|
||||
#if 0
|
||||
if (!ctx->no_sr) {
|
||||
lsdb_reset_attr_template(&attr_template);
|
||||
lspgen_store_addr(addr, (uint8_t*)&attr_template.key.prefix.ipv6_prefix.address, IPV6_ADDR_LEN);
|
||||
attr_template.key.prefix.ipv6_prefix.len = ctx->ipv6_node_prefix.len;
|
||||
attr_template.key.prefix.sid = node->node_index;
|
||||
|
||||
attr_template.key.ordinal = 1;
|
||||
attr_template.key.attr_cp[0] = OSPF_MSG_LSUPDATE;
|
||||
attr_template.key.attr_cp[1] = OSPF_LSA_OPAQUE_AREA_EP;
|
||||
attr_template.key.attr_cp[2] = OSPF_TLV_EXTENDED_PREFIX_RANGE;
|
||||
lsdb_add_node_attr(node, &attr_template);
|
||||
}
|
||||
addr += node->node_index;
|
||||
#endif
|
||||
|
||||
/* external prefixes */
|
||||
ext_per_node = ext_left / nodes_left;
|
||||
ext_left -= ext_per_node;
|
||||
while (ext_per_node--) {
|
||||
/* ipv6 external prefix */
|
||||
lsdb_reset_attr_template(&attr_template);
|
||||
lspgen_store_addr(ext_addr6, attr_template.key.prefix.ipv6_prefix.address, IPV6_ADDR_LEN);
|
||||
attr_template.key.prefix.ipv6_prefix.len = ctx->ipv6_ext_prefix.len;
|
||||
attr_template.key.prefix.metric = 100;
|
||||
attr_template.key.attr_cp[0] = OSPF_MSG_LSUPDATE;
|
||||
attr_template.key.attr_cp[1] = OSPF_LSA_EXTERNAL;
|
||||
attr_template.key.start_tlv = true;
|
||||
lsdb_add_node_attr(node, &attr_template);
|
||||
ext_addr6 += ext_incr6;
|
||||
}
|
||||
|
||||
if (!ctx->no_sr) {
|
||||
/* SR capability */
|
||||
lsdb_reset_attr_template(&attr_template);
|
||||
addr = lspgen_load_addr((uint8_t*)&ctx->ipv4_node_prefix.address, sizeof(ipv4addr_t));
|
||||
addr += node->node_index;
|
||||
lspgen_store_addr(addr, attr_template.key.cap.router_id, sizeof(ipv4addr_t));
|
||||
attr_template.key.cap.srgb_base = ctx->srgb_base;
|
||||
attr_template.key.cap.srgb_range = ctx->srgb_range;
|
||||
attr_template.key.attr_cp[0] = OSPF_MSG_LSUPDATE;
|
||||
attr_template.key.attr_cp[1] = OSPF_LSA_OPAQUE_AREA_RI;
|
||||
attr_template.key.attr_cp[2] = OSPF_TLV_SID_LABEL_RANGE;
|
||||
//attr_template.key.ordinal = 1;
|
||||
lsdb_add_node_attr(node, &attr_template);
|
||||
}
|
||||
|
||||
/*
|
||||
* Walk all of our neighbors.
|
||||
*/
|
||||
CIRCLEQ_FOREACH(link, &node->link_qhead, link_qnode) {
|
||||
|
||||
/*
|
||||
* Is this a connector link ?
|
||||
*/
|
||||
if (link->key.remote_node_id[7] == CONNECTOR_MARKER) {
|
||||
lsdb_reset_attr_template(&attr_template);
|
||||
|
||||
attr_template.key.attr_cp[0] = OSPF_MSG_LSUPDATE;
|
||||
attr_template.key.attr_cp[1] = OSPF_LSA_ROUTER;
|
||||
attr_template.key.attr_cp[2] = OSPF_ROUTER_LSA_LINK_PTP;
|
||||
|
||||
memcpy(attr_template.key.link.remote_node_id, link->key.remote_node_id, 4);
|
||||
memcpy(attr_template.key.link.local_node_id, link->key.local_link_id, 4);
|
||||
attr_template.key.link.metric = link->link_metric;
|
||||
lsdb_add_node_attr(node, &attr_template);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate a ptp neighbor for each link
|
||||
* TODO Type-2 LSA handling.
|
||||
*/
|
||||
lsdb_reset_attr_template(&attr_template);
|
||||
|
||||
addr = lspgen_load_addr((uint8_t*)&ctx->ipv4_link_prefix.address, sizeof(ipv4addr_t));
|
||||
inc = lspgen_get_prefix_inc(AF_INET, ctx->ipv4_link_prefix.len);
|
||||
addr += link->link_index * inc;
|
||||
addr_offset = 0;
|
||||
if (lspgen_load_addr(link->key.remote_node_id, 4) < lspgen_load_addr(link->key.local_node_id, 4)) {
|
||||
addr_offset = 1;
|
||||
}
|
||||
|
||||
lspgen_store_addr(addr + addr_offset, attr_template.key.link.local_node_id, 4);
|
||||
|
||||
attr_template.key.attr_cp[0] = OSPF_MSG_LSUPDATE;
|
||||
attr_template.key.attr_cp[1] = OSPF_LSA_ROUTER;
|
||||
attr_template.key.attr_cp[2] = OSPF_ROUTER_LSA_LINK_PTP;
|
||||
memcpy(attr_template.key.link.remote_node_id, link->key.remote_node_id, 4);
|
||||
metric = link->link_metric;
|
||||
if (metric > 65535) {
|
||||
metric = 65535;
|
||||
}
|
||||
attr_template.key.link.metric = metric;
|
||||
lsdb_add_node_attr(node, &attr_template);
|
||||
|
||||
#if 0
|
||||
/* Generate an IPv6 prefix for each link */
|
||||
lsdb_reset_attr_template(&attr_template);
|
||||
lspgen_store_addr(addr, (uint8_t*)&attr_template.key.prefix.ipv6_prefix.address, IPV6_ADDR_LEN);
|
||||
attr_template.key.prefix.ipv6_prefix.len = ctx->ipv6_link_prefix.len;
|
||||
attr_template.key.prefix.metric = metric;
|
||||
|
||||
attr_template.key.attr_cp[0] = OSPF_MSG_LSUPDATE;
|
||||
attr_template.key.attr_cp[1] = OSPF_LSA_INTRA_AREA_PREFIX;
|
||||
attr_template.key.attr_cp[2] = OSPF_IA_PREFIX_LSA_PREFIX;
|
||||
lsdb_add_node_attr(node, &attr_template);
|
||||
#endif
|
||||
}
|
||||
|
||||
nodes_left--;
|
||||
} while (dict_itor_next(itor));
|
||||
|
||||
dict_itor_free(itor);
|
||||
}
|
||||
|
||||
void
|
||||
lspgen_init_ctx(struct lsdb_ctx_ *ctx)
|
||||
{
|
||||
@@ -798,9 +978,9 @@ lspgen_compute_end_prefix6(struct ipv6_prefix_ *start_prefix, unsigned int num_p
|
||||
}
|
||||
|
||||
prefix_inc = lspgen_get_prefix_inc(AF_INET6, start_prefix->len);
|
||||
addr = lspgen_load_addr((uint8_t *)&start_prefix->address, 16);
|
||||
addr = lspgen_load_addr((uint8_t *)&start_prefix->address, IPV6_ADDR_LEN);
|
||||
addr += prefix_inc * (num_prefixes-1);
|
||||
lspgen_store_addr(addr, (uint8_t *)&end_prefix.address, 16);
|
||||
lspgen_store_addr(addr, (uint8_t *)&end_prefix.address, IPV6_ADDR_LEN);
|
||||
|
||||
return &end_prefix;
|
||||
}
|
||||
@@ -1243,8 +1423,9 @@ main(int argc, char *argv[])
|
||||
lspgen_gen_isis_attr(ctx);
|
||||
} else if (ctx->protocol_id == PROTO_OSPF2) {
|
||||
lspgen_gen_ospf2_attr(ctx);
|
||||
} else if (ctx->protocol_id == PROTO_OSPF3) {
|
||||
lspgen_gen_ospf3_attr(ctx);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -161,7 +161,7 @@ lspgen_write_ctrl_buffer(lsdb_ctx_t *ctx)
|
||||
static void
|
||||
lspgen_ctrl_encode_packet(lsdb_ctx_t *ctx, lsdb_packet_t *packet)
|
||||
{
|
||||
struct io_buffer_ *buf;
|
||||
struct io_buffer_ *buf, *src_buf;
|
||||
char hextable[] = "0123456789abcdef";
|
||||
uint8_t hi_byte, lo_byte;
|
||||
uint32_t idx, val;
|
||||
@@ -185,9 +185,10 @@ lspgen_ctrl_encode_packet(lsdb_ctx_t *ctx, lsdb_packet_t *packet)
|
||||
idx = 20;
|
||||
}
|
||||
|
||||
for (; idx < packet->buf.idx; idx++) {
|
||||
hi_byte = packet->buf.data[idx] >> 4;
|
||||
lo_byte = packet->buf.data[idx] & 0xf;
|
||||
src_buf = &packet->buf[0];
|
||||
for (; idx < src_buf->idx; idx++) {
|
||||
hi_byte = src_buf->data[idx] >> 4;
|
||||
lo_byte = src_buf->data[idx] & 0xf;
|
||||
|
||||
val = (hextable[hi_byte] << 8) | hextable[lo_byte];
|
||||
push_be_uint(buf, 2, val);
|
||||
@@ -285,7 +286,7 @@ lspgen_ctrl_write_cb(timer_s *timer)
|
||||
/*
|
||||
* Hexdumping doubles the data plus 4 bytes for two quotation marks, comma and whitespace.
|
||||
*/
|
||||
if (buffer_left < ((packet->buf.idx * 2) + 4)) {
|
||||
if (buffer_left < ((packet->buf[0].idx * 2) + 4)) {
|
||||
|
||||
/* no space, release buffer and try later */
|
||||
lspgen_write_ctrl_buffer(ctx);
|
||||
|
||||
@@ -181,10 +181,10 @@ lsdb_format_node(lsdb_node_t *node)
|
||||
|
||||
if (ctx->protocol_id == PROTO_ISIS) {
|
||||
if (node->node_name) {
|
||||
snprintf(buffer, sizeof(buffer), "%s (%s)",
|
||||
snprintf(buffer, sizeof(buffer), "%s (%s)",
|
||||
lsdb_format_node_id(node->key.node_id), node->node_name);
|
||||
} else {
|
||||
snprintf(buffer, sizeof(buffer), "%s",
|
||||
snprintf(buffer, sizeof(buffer), "%s",
|
||||
lsdb_format_node_id(node->key.node_id));
|
||||
}
|
||||
} else if (ctx->protocol_id == PROTO_OSPF2 || ctx->protocol_id == PROTO_OSPF3) {
|
||||
@@ -962,14 +962,14 @@ lsdb_add_node_attr(lsdb_node_t *node, lsdb_attr_t *attr_template)
|
||||
*/
|
||||
lspgen_reset_packet_buffer(&packet);
|
||||
lspgen_serialize_attr(ctx, attr, &packet);
|
||||
attr->size = packet.buf.idx;
|
||||
attr->size = packet.buf[0].idx;
|
||||
|
||||
/*
|
||||
* Find lowest level size.
|
||||
*/
|
||||
for (idx = MAX_MSG_LEVEL-1; idx; idx--) {
|
||||
if (packet.bufX[idx].idx) {
|
||||
attr->size += packet.bufX[idx].idx;
|
||||
if (packet.buf[idx].idx) {
|
||||
attr->size += packet.buf[idx].idx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -316,8 +316,7 @@ typedef struct lsdb_packet_ {
|
||||
uint32_t id; /* Fragment # for IS-IS, LS-Update Packet # for OSPF */
|
||||
} key;
|
||||
|
||||
struct io_buffer_ buf;
|
||||
struct io_buffer_ bufX[MAX_MSG_LEVEL];
|
||||
struct io_buffer_ buf[MAX_MSG_LEVEL];
|
||||
uint8_t data[1500]; /* fixed buffer */
|
||||
uint8_t redzone[8]; /* Overwrite detection */
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
/* https://datatracker.ietf.org/doc/html/rfc6396#section-4 */
|
||||
#define MRT_TYPE_OSPFV2 11
|
||||
#define MRT_TYPE_OSPFV3 48
|
||||
#define MRT_TYPE_ISIS 32
|
||||
|
||||
/*
|
||||
@@ -62,8 +63,8 @@ lspgen_dump_mrt_node(lsdb_ctx_t *ctx, lsdb_node_t *node)
|
||||
/*
|
||||
* Copy packet
|
||||
*/
|
||||
memcpy(&mrt_record[buf.idx], packet->data, packet->buf.idx);
|
||||
buf.idx += packet->buf.idx;
|
||||
memcpy(&mrt_record[buf.idx], packet->data, packet->buf[0].idx);
|
||||
buf.idx += packet->buf[0].idx;
|
||||
break;
|
||||
|
||||
case PROTO_OSPF2:
|
||||
@@ -77,13 +78,37 @@ lspgen_dump_mrt_node(lsdb_ctx_t *ctx, lsdb_node_t *node)
|
||||
/*
|
||||
* Copy packet
|
||||
*/
|
||||
if (packet->buf.idx > 20) {
|
||||
if (packet->buf[0].idx > 20) {
|
||||
|
||||
/*
|
||||
* Skip 20 bytes of IPv4 header.
|
||||
*/
|
||||
memcpy(&mrt_record[buf.idx], packet->data+20, packet->buf.idx-20);
|
||||
buf.idx += packet->buf.idx-20;
|
||||
memcpy(&mrt_record[buf.idx], packet->data+20, packet->buf[0].idx-20);
|
||||
buf.idx += packet->buf[0].idx-20;
|
||||
}
|
||||
break;
|
||||
|
||||
case PROTO_OSPF3:
|
||||
push_be_uint(&buf, 2, MRT_TYPE_OSPFV3); /* type */
|
||||
push_be_uint(&buf, 2, 0); /* subtype */
|
||||
push_be_uint(&buf, 4, 0); /* length, will be overwritten */
|
||||
|
||||
push_be_uint(&buf, 2, 2); /* address family: ipv6 */
|
||||
push_be_uint(&buf, 8, 0); /* remote IP address */
|
||||
push_be_uint(&buf, 8, 0); /* remote IP address */
|
||||
push_be_uint(&buf, 8, 0); /* local IP address */
|
||||
push_be_uint(&buf, 8, 0); /* local IP address */
|
||||
|
||||
/*
|
||||
* Copy packet
|
||||
*/
|
||||
if (packet->buf[0].idx > 40) {
|
||||
|
||||
/*
|
||||
* Skip 40 bytes of IPv6 header.
|
||||
*/
|
||||
memcpy(&mrt_record[buf.idx], packet->data+40, packet->buf[0].idx-40);
|
||||
buf.idx += packet->buf[0].idx-40;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
#define OSPF_LSA_SUMMARY 3
|
||||
#define OSPF_LSA_ASBR_SUMMARY 4
|
||||
#define OSPF_LSA_EXTERNAL 5
|
||||
|
||||
#define OSPF_LSA_OPAQUE_LINK 9
|
||||
#define OSPF_LSA_INTRA_AREA_PREFIX 39 /* OSPFv3 LSA Type 9*/
|
||||
#define OSPF_LSA_OPAQUE_AREA_RI 104
|
||||
#define OSPF_LSA_OPAQUE_AREA_EP 107 /* rfc 7684 */
|
||||
#define OSPF_LSA_OPAQUE_DOMAIN 11
|
||||
@@ -30,4 +30,11 @@
|
||||
#define OSPF_TLV_SID_LABEL_RANGE 9
|
||||
|
||||
/* Opaque LSA Extended Prefix TLVs */
|
||||
#define OSPF_TLV_EXTENDED_PREFIX 12
|
||||
#define OSPF_TLV_EXTENDED_PREFIX_RANGE 2
|
||||
|
||||
/* Extended Prefix & Extended Prefix range subTLVs */
|
||||
#define OSPF_SUBTLV_EXTENDED_PREFIX_SID 1
|
||||
|
||||
/* Inter Area Prefix LSA */
|
||||
#define OSPF_IA_PREFIX_LSA_PREFIX 31
|
||||
|
||||
+470
-128
@@ -18,49 +18,52 @@
|
||||
*/
|
||||
void lspgen_gen_packet_node(lsdb_node_t *);
|
||||
void lspgen_serialize_ospf2_state(lsdb_attr_t *, lsdb_packet_t *, uint16_t);
|
||||
void lspgen_serialize_ospf3_state(lsdb_attr_t *, lsdb_packet_t *, uint16_t);
|
||||
|
||||
void
|
||||
lspgen_gen_isis_packet_header(lsdb_ctx_t *ctx, lsdb_node_t *node, lsdb_packet_t *packet)
|
||||
{
|
||||
struct io_buffer_ *buf;
|
||||
unsigned long long sysid;
|
||||
uint8_t lsattr;
|
||||
|
||||
/*
|
||||
* Reset buffer.
|
||||
*/
|
||||
packet->buf.data = packet->data;
|
||||
packet->buf.start_idx = 0;
|
||||
packet->buf.idx = 0;
|
||||
packet->buf.size = sizeof(packet->data);
|
||||
buf = &packet->buf[0];
|
||||
buf->data = packet->data;
|
||||
buf->start_idx = 0;
|
||||
buf->idx = 0;
|
||||
buf->size = sizeof(packet->data);
|
||||
|
||||
push_be_uint(&packet->buf, 1, 0x83); /* Intradomain Routeing Protocol Discriminator */
|
||||
push_be_uint(&packet->buf, 1, 27); /* Length Indicator always 27 for LSPs */
|
||||
push_be_uint(&packet->buf, 1, 1); /* Version/Protocol ID Extension */
|
||||
push_be_uint(&packet->buf, 1, 0); /* ID Length */
|
||||
push_be_uint(buf, 1, 0x83); /* Intradomain Routeing Protocol Discriminator */
|
||||
push_be_uint(buf, 1, 27); /* Length Indicator always 27 for LSPs */
|
||||
push_be_uint(buf, 1, 1); /* Version/Protocol ID Extension */
|
||||
push_be_uint(buf, 1, 0); /* ID Length */
|
||||
|
||||
/* PDU Type */
|
||||
if (ctx->topology_id.level == 1) {
|
||||
push_be_uint(&packet->buf, 1, ISIS_PDU_L1_LSP);
|
||||
push_be_uint(buf, 1, ISIS_PDU_L1_LSP);
|
||||
}
|
||||
if (ctx->topology_id.level == 2) {
|
||||
push_be_uint(&packet->buf, 1, ISIS_PDU_L2_LSP);
|
||||
push_be_uint(buf, 1, ISIS_PDU_L2_LSP);
|
||||
}
|
||||
|
||||
push_be_uint(&packet->buf, 1, 1); /* Version */
|
||||
push_be_uint(&packet->buf, 1, 0); /* Reserved */
|
||||
push_be_uint(&packet->buf, 1, 0); /* Maximum Area Addresses */
|
||||
push_be_uint(buf, 1, 1); /* Version */
|
||||
push_be_uint(buf, 1, 0); /* Reserved */
|
||||
push_be_uint(buf, 1, 0); /* Maximum Area Addresses */
|
||||
|
||||
push_be_uint(&packet->buf, 2, 0); /* PDU length */
|
||||
push_be_uint(&packet->buf, 2, 0); /* Remaining Lifetime - will be overwritten during checksum calc */
|
||||
push_be_uint(buf, 2, 0); /* PDU length */
|
||||
push_be_uint(buf, 2, 0); /* Remaining Lifetime - will be overwritten during checksum calc */
|
||||
|
||||
/* LSP ID */
|
||||
sysid = read_be_uint(node->key.node_id, 6);
|
||||
push_be_uint(&packet->buf, 6, sysid); /* System ID */
|
||||
push_be_uint(&packet->buf, 1, 0); /* PSN # */
|
||||
push_be_uint(&packet->buf, 1, packet->key.id); /* Fragment # */
|
||||
push_be_uint(buf, 6, sysid); /* System ID */
|
||||
push_be_uint(buf, 1, 0); /* PSN # */
|
||||
push_be_uint(buf, 1, packet->key.id); /* Fragment # */
|
||||
|
||||
push_be_uint(&packet->buf, 4, node->sequence); /* Sequence */
|
||||
push_be_uint(&packet->buf, 2, 0); /* Checksum */
|
||||
push_be_uint(buf, 4, node->sequence); /* Sequence */
|
||||
push_be_uint(buf, 2, 0); /* Checksum */
|
||||
|
||||
lsattr = 0;
|
||||
if (ctx->topology_id.level == 1) {
|
||||
@@ -75,36 +78,7 @@ lspgen_gen_isis_packet_header(lsdb_ctx_t *ctx, lsdb_node_t *node, lsdb_packet_t
|
||||
if (node->attach) {
|
||||
lsattr |= 0x08;
|
||||
}
|
||||
push_be_uint(&packet->buf, 1, lsattr); /* LSP Attributes */
|
||||
}
|
||||
|
||||
void
|
||||
lspgen_gen_ospf2_packet_header(lsdb_ctx_t *ctx, lsdb_node_t *node, lsdb_packet_t *packet)
|
||||
{
|
||||
uint32_t router_id;
|
||||
|
||||
/*
|
||||
* Reset buffer.
|
||||
*/
|
||||
packet->buf.data = packet->data;
|
||||
packet->buf.start_idx = 0;
|
||||
packet->buf.idx = 0;
|
||||
packet->buf.size = sizeof(packet->data);
|
||||
|
||||
push_be_uint(&packet->buf, 1, 2); /* Version */
|
||||
push_be_uint(&packet->buf, 1, 4); /* Message Type: Link State Update */
|
||||
push_be_uint(&packet->buf, 2, 0); /* Packet length - will be overwritten later */
|
||||
|
||||
router_id = read_be_uint(node->key.node_id, 4);
|
||||
push_be_uint(&packet->buf, 4, router_id); /* Router ID */
|
||||
push_be_uint(&packet->buf, 4, ctx->topology_id.area); /* Area ID */
|
||||
|
||||
push_be_uint(&packet->buf, 2, 0); /* Checksum - will be overwritten later */
|
||||
|
||||
push_be_uint(&packet->buf, 2, 0); /* Authentication Type */
|
||||
push_be_uint(&packet->buf, 8, 0); /* Authentication */
|
||||
|
||||
push_be_uint(&packet->buf, 4, 0); /* # LSAs - will be overwritten later */
|
||||
push_be_uint(buf, 1, lsattr); /* LSP Attributes */
|
||||
}
|
||||
|
||||
void
|
||||
@@ -115,7 +89,8 @@ lspgen_gen_packet_header(lsdb_ctx_t *ctx, lsdb_node_t *node, lsdb_packet_t *pack
|
||||
lspgen_gen_isis_packet_header(ctx, node, packet);
|
||||
break;
|
||||
case PROTO_OSPF2:
|
||||
//lspgen_gen_ospf2_packet_header(ctx, node, packet);
|
||||
break;
|
||||
case PROTO_OSPF3:
|
||||
break;
|
||||
default:
|
||||
LOG_NOARG(ERROR, "Unknown protocol\n");
|
||||
@@ -203,32 +178,46 @@ calculate_cksum(uint8_t *buf, uint16_t len)
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the size of the authentication TLV to be inserted.
|
||||
* Calculate the size of the authentication data to be inserted.
|
||||
* Helper for calculating when to start a new packet.
|
||||
*/
|
||||
uint32_t
|
||||
lspgen_calculate_isis_auth_len(lsdb_ctx_t *ctx)
|
||||
lspgen_calculate_auth_len(lsdb_ctx_t *ctx)
|
||||
{
|
||||
uint8_t auth_len;
|
||||
|
||||
auth_len = 0;
|
||||
if (ctx->authentication_key && ctx->authentication_type) {
|
||||
if (ctx->authentication_type == ISIS_AUTH_SIMPLE) {
|
||||
auth_len = strlen(ctx->authentication_key) + 1 + TLV_OVERHEAD;
|
||||
} if (ctx->authentication_type == ISIS_AUTH_MD5) {
|
||||
auth_len = 16 + 1 + TLV_OVERHEAD;
|
||||
switch (ctx->protocol_id) {
|
||||
case PROTO_ISIS:
|
||||
if (ctx->authentication_key && ctx->authentication_type) {
|
||||
if (ctx->authentication_type == ISIS_AUTH_SIMPLE) {
|
||||
auth_len = strlen(ctx->authentication_key) + 1 + TLV_OVERHEAD;
|
||||
} if (ctx->authentication_type == ISIS_AUTH_MD5) {
|
||||
auth_len = 16 + 1 + TLV_OVERHEAD;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
* BNG Blaster computes the authentication trailer for OSPF2 and OSPF3
|
||||
*/
|
||||
case PROTO_OSPF2: /* fall through */
|
||||
case PROTO_OSPF3: /* fall through */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return auth_len;
|
||||
}
|
||||
|
||||
void
|
||||
lspgen_finalize_isis_packet(lsdb_ctx_t *ctx, lsdb_node_t *node, lsdb_packet_t *packet)
|
||||
{
|
||||
struct io_buffer_ *buf;
|
||||
uint16_t checksum, lsp_lifetime;
|
||||
uint8_t auth_len;
|
||||
|
||||
buf = &packet->buf[0];
|
||||
|
||||
/*
|
||||
* Generate Authentication TLV
|
||||
*/
|
||||
@@ -240,21 +229,21 @@ lspgen_finalize_isis_packet(lsdb_ctx_t *ctx, lsdb_node_t *node, lsdb_packet_t *p
|
||||
auth_len = 16;
|
||||
}
|
||||
|
||||
push_be_uint(&packet->buf, 1, ISIS_TLV_AUTH); /* Type */
|
||||
push_be_uint(&packet->buf, 1, auth_len+1); /* Length */
|
||||
push_be_uint(&packet->buf, 1, ctx->authentication_type);
|
||||
push_be_uint(buf, 1, ISIS_TLV_AUTH); /* Type */
|
||||
push_be_uint(buf, 1, auth_len+1); /* Length */
|
||||
push_be_uint(buf, 1, ctx->authentication_type);
|
||||
|
||||
if (ctx->authentication_type == ISIS_AUTH_SIMPLE) {
|
||||
push_data(&packet->buf, (uint8_t *)ctx->authentication_key, auth_len);
|
||||
push_data(buf, (uint8_t *)ctx->authentication_key, auth_len);
|
||||
}
|
||||
if (ctx->authentication_type == ISIS_AUTH_MD5) {
|
||||
push_be_uint(&packet->buf, 8, 0);
|
||||
push_be_uint(&packet->buf, 8, 0);
|
||||
push_be_uint(buf, 8, 0);
|
||||
push_be_uint(buf, 8, 0);
|
||||
/* Update PDU length field. */
|
||||
write_be_uint(packet->data+8, 2, packet->buf.idx);
|
||||
hmac_md5(packet->buf.data, packet->buf.idx,
|
||||
write_be_uint(packet->data+8, 2, buf->idx);
|
||||
hmac_md5(buf->data, buf->idx,
|
||||
(unsigned char *)ctx->authentication_key, strlen(ctx->authentication_key),
|
||||
packet->buf.data+packet->buf.idx-16);
|
||||
buf->data+buf->idx-16);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,26 +263,24 @@ lspgen_finalize_isis_packet(lsdb_ctx_t *ctx, lsdb_node_t *node, lsdb_packet_t *p
|
||||
/*
|
||||
* Update PDU length field.
|
||||
*/
|
||||
write_be_uint(packet->data+8, 2, packet->buf.idx);
|
||||
write_be_uint(packet->data+8, 2, buf->idx);
|
||||
|
||||
/*
|
||||
* Calculate Checksum
|
||||
*/
|
||||
write_be_uint(packet->data+24, 2, 0); /* reset checksum field */
|
||||
checksum = calculate_fletcher_cksum(packet->data+12, 12, packet->buf.idx-12);
|
||||
write_be_uint(packet->data+24, 2, checksum);
|
||||
write_be_uint(buf->data+24, 2, 0); /* reset checksum field */
|
||||
checksum = calculate_fletcher_cksum(buf->data+12, 12, buf->idx-12);
|
||||
write_be_uint(buf->data+24, 2, checksum);
|
||||
}
|
||||
|
||||
void
|
||||
lspgen_finalize_ospf2_packet(__attribute__((unused))lsdb_ctx_t *ctx,
|
||||
__attribute__((unused))lsdb_node_t *node,
|
||||
lsdb_packet_t *packet)
|
||||
/*
|
||||
* Close all Message levels that the serializer may have left open.
|
||||
*/
|
||||
uint16_t
|
||||
lspgen_close_all_message_levels (lsdb_packet_t *packet)
|
||||
{
|
||||
uint16_t state;
|
||||
|
||||
/*
|
||||
* Close all Message levels that the serializer may have left open.
|
||||
*/
|
||||
state = 0;
|
||||
if (packet->prev_attr_cp[0]) {
|
||||
state |= CLOSE_LEVEL0;
|
||||
@@ -304,9 +291,11 @@ lspgen_finalize_ospf2_packet(__attribute__((unused))lsdb_ctx_t *ctx,
|
||||
if (packet->prev_attr_cp[2]) {
|
||||
state |= CLOSE_LEVEL2;
|
||||
}
|
||||
lspgen_serialize_ospf2_state(NULL, packet, state);
|
||||
memcpy(&packet->buf, &packet->bufX[0], sizeof(struct io_buffer_)); /* XXX rework */
|
||||
if (packet->prev_attr_cp[3]) {
|
||||
state |= CLOSE_LEVEL3;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -317,7 +306,10 @@ lspgen_finalize_packet(lsdb_ctx_t *ctx, lsdb_node_t *node, lsdb_packet_t *packet
|
||||
lspgen_finalize_isis_packet(ctx, node, packet);
|
||||
break;
|
||||
case PROTO_OSPF2:
|
||||
lspgen_finalize_ospf2_packet(ctx, node, packet);
|
||||
lspgen_serialize_ospf2_state(NULL, packet, lspgen_close_all_message_levels(packet));
|
||||
break;
|
||||
case PROTO_OSPF3:
|
||||
lspgen_serialize_ospf3_state(NULL, packet, lspgen_close_all_message_levels(packet));
|
||||
break;
|
||||
default:
|
||||
LOG_NOARG(ERROR, "Unknown protocol\n");
|
||||
@@ -449,7 +441,7 @@ lspgen_serialize_isis_attr(lsdb_attr_t *attr, lsdb_packet_t *packet)
|
||||
bool subtlv_present;
|
||||
io_buffer_t *buf;
|
||||
|
||||
buf = &packet->buf;
|
||||
buf = &packet->buf[0];
|
||||
|
||||
subtlv_present = lsdb_attr_subtlvs_present(attr);
|
||||
|
||||
@@ -620,8 +612,8 @@ lspgen_propagate_buffer_down (lsdb_packet_t *packet, uint level)
|
||||
return;
|
||||
}
|
||||
|
||||
cur = &packet->bufX[level];
|
||||
next = &packet->bufX[level+1];
|
||||
cur = &packet->buf[level];
|
||||
next = &packet->buf[level+1];
|
||||
|
||||
next->data = cur->data + cur->idx;
|
||||
next->size = cur->size - cur->idx;
|
||||
@@ -642,8 +634,8 @@ lspgen_propagate_buffer_up (lsdb_packet_t *packet, uint level)
|
||||
return;
|
||||
}
|
||||
|
||||
cur = &packet->bufX[level];
|
||||
prev = &packet->bufX[level-1];
|
||||
cur = &packet->buf[level];
|
||||
prev = &packet->buf[level-1];
|
||||
|
||||
prev->idx += cur->idx;
|
||||
cur->data += cur->idx;
|
||||
@@ -741,29 +733,47 @@ lspgen_serialize_ospf2_state(lsdb_attr_t *attr, lsdb_packet_t *packet, uint16_t
|
||||
{
|
||||
lsdb_ctx_t *ctx;
|
||||
lsdb_node_t *node;
|
||||
io_buffer_t *buf0, *buf1, *buf2;
|
||||
io_buffer_t *buf0, *buf1, *buf2, *buf3;
|
||||
uint16_t attr_len, checksum;
|
||||
uint32_t router_id, mask;
|
||||
|
||||
node = packet->parent;
|
||||
ctx = node->ctx;
|
||||
|
||||
buf0 = &packet->bufX[0];
|
||||
buf1 = &packet->bufX[1];
|
||||
buf2 = &packet->bufX[2];
|
||||
buf0 = &packet->buf[0];
|
||||
buf1 = &packet->buf[1];
|
||||
buf2 = &packet->buf[2];
|
||||
buf3 = &packet->buf[3];
|
||||
|
||||
LOG(PACKET, " %s\n", lspgen_format_serializer_state(state));
|
||||
|
||||
/* close Level 2 */
|
||||
if (state & CLOSE_LEVEL2) {
|
||||
switch (packet->prev_attr_cp[2]) {
|
||||
case OSPF_ROUTER_LSA_LINK_PTP:
|
||||
case OSPF_ROUTER_LSA_LINK_STUB:
|
||||
/* close Level 3 */
|
||||
if (state & CLOSE_LEVEL3) {
|
||||
switch (packet->prev_attr_cp[3]) {
|
||||
case OSPF_SUBTLV_EXTENDED_PREFIX_SID:
|
||||
write_be_uint(buf3->data+2, 2, buf3->idx-4); /* Update length */
|
||||
push_pad4(buf3);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
lspgen_propagate_buffer_up(packet, 3);
|
||||
}
|
||||
|
||||
/* close Level 2 */
|
||||
if (state & CLOSE_LEVEL2) {
|
||||
switch (packet->prev_attr_cp[2]) {
|
||||
case OSPF_TLV_EXTENDED_PREFIX_RANGE: /* fall through */
|
||||
case OSPF_TLV_EXTENDED_PREFIX:
|
||||
case OSPF_TLV_SID_LABEL_RANGE:
|
||||
write_be_uint(buf2->data+2, 2, buf2->idx-4); /* Update length */
|
||||
push_pad4(buf2);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
lspgen_propagate_buffer_up(packet, 2);
|
||||
}
|
||||
|
||||
@@ -791,7 +801,6 @@ lspgen_serialize_ospf2_state(lsdb_attr_t *attr, lsdb_packet_t *packet, uint16_t
|
||||
|
||||
/* close Level 0 */
|
||||
if (state & CLOSE_LEVEL0) {
|
||||
|
||||
switch (packet->prev_attr_cp[0]) {
|
||||
case OSPF_MSG_LSUPDATE:
|
||||
write_be_uint(buf0->data+20+2, 2, buf0->idx - 20); /* Packet length */
|
||||
@@ -838,7 +847,6 @@ lspgen_serialize_ospf2_state(lsdb_attr_t *attr, lsdb_packet_t *packet, uint16_t
|
||||
push_be_uint(buf0, 8, 0); /* Authentication */
|
||||
|
||||
push_be_uint(buf0, 4, 0); /* # LSAs - will be overwritten later */
|
||||
|
||||
break;
|
||||
default:
|
||||
LOG(ERROR, "No Level 0 open packet serializer for attr %d\n", attr->key.attr_cp[0]);
|
||||
@@ -967,6 +975,296 @@ lspgen_serialize_ospf2_state(lsdb_attr_t *attr, lsdb_packet_t *packet, uint16_t
|
||||
}
|
||||
break;
|
||||
|
||||
case OSPF_TLV_SID_LABEL_RANGE:
|
||||
if (attr->key.cap.srgb_base && attr->key.cap.srgb_range) {
|
||||
push_be_uint(buf2, 2, 9); /* Type */
|
||||
push_be_uint(buf2, 2, 0); /* Length - will be overwritten later */
|
||||
push_be_uint(buf2, 3, attr->key.cap.srgb_range); /* Range size */
|
||||
push_be_uint(buf2, 1, 0); /* Reserved */
|
||||
|
||||
/* XXX Move this to level 3 */
|
||||
push_be_uint(buf2, 2, 1); /* SID Type Label */
|
||||
push_be_uint(buf2, 2, 3); /* SID Type Length */
|
||||
push_be_uint(buf2, 3, attr->key.cap.srgb_base);
|
||||
push_pad4(buf2);
|
||||
}
|
||||
break;
|
||||
|
||||
case OSPF_TLV_EXTENDED_PREFIX_RANGE:
|
||||
push_be_uint(buf2, 2, 2); /* Type */
|
||||
push_be_uint(buf2, 2, 0); /* Length - will be overwritten later */
|
||||
push_be_uint(buf2, 1, attr->key.prefix.ipv4_prefix.len);
|
||||
push_be_uint(buf2, 1, 0); /* AF ipv4 */
|
||||
push_be_uint(buf2, 2, 1); /* Range size */
|
||||
push_be_uint(buf2, 1, 0); /* Flags */
|
||||
push_be_uint(buf2, 3, 0); /* Reserved */
|
||||
push_data(buf2, (uint8_t*)&attr->key.prefix.ipv4_prefix.address, 4); /* Prefix */
|
||||
break;
|
||||
|
||||
case OSPF_TLV_EXTENDED_PREFIX:
|
||||
push_be_uint(buf2, 2, 1); /* Type */
|
||||
push_be_uint(buf2, 2, 0); /* Length - will be overwritten later */
|
||||
push_be_uint(buf2, 1, 1); /* Route Type: Intra Area */
|
||||
push_be_uint(buf2, 1, attr->key.prefix.ipv4_prefix.len);
|
||||
push_be_uint(buf2, 1, 0); /* AF ipv4 */
|
||||
push_be_uint(buf2, 1, 0); /* Flags */
|
||||
push_data(buf2, (uint8_t*)&attr->key.prefix.ipv4_prefix.address, 4); /* Prefix */
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG(ERROR, "No Level 2 open packet serializer for attr %d\n", attr->key.attr_cp[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
lspgen_propagate_buffer_down(packet, 2);
|
||||
}
|
||||
|
||||
/* open Level 3 */
|
||||
if (state & OPEN_LEVEL3) {
|
||||
switch(attr->key.attr_cp[3]) {
|
||||
case OSPF_SUBTLV_EXTENDED_PREFIX_SID:
|
||||
push_be_uint(buf3, 2, 2); /* Type */
|
||||
push_be_uint(buf3, 2, 0); /* Length - will be overwritten later */
|
||||
push_be_uint(buf3, 3, 0); /* Flags, Reserved, MT-ID */
|
||||
push_be_uint(buf3, 1, attr->key.prefix.sid_algo); /* Algorithm */
|
||||
push_be_uint(buf3, 4, attr->key.prefix.sid); /* SID Index */
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG(ERROR, "No Level 3 open packet serializer for attr %d\n", attr->key.attr_cp[3]);
|
||||
return;
|
||||
}
|
||||
|
||||
lspgen_propagate_buffer_down(packet, 3);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
lspgen_serialize_ospf3_state(lsdb_attr_t *attr, lsdb_packet_t *packet, uint16_t state)
|
||||
{
|
||||
lsdb_ctx_t *ctx;
|
||||
lsdb_node_t *node;
|
||||
io_buffer_t *buf0, *buf1, *buf2;
|
||||
uint16_t attr_len, checksum;
|
||||
uint32_t router_id;
|
||||
|
||||
node = packet->parent;
|
||||
ctx = node->ctx;
|
||||
|
||||
buf0 = &packet->buf[0];
|
||||
buf1 = &packet->buf[1];
|
||||
buf2 = &packet->buf[2];
|
||||
|
||||
LOG(PACKET, " %s\n", lspgen_format_serializer_state(state));
|
||||
|
||||
/* close Level 2 */
|
||||
if (state & CLOSE_LEVEL2) {
|
||||
lspgen_propagate_buffer_up(packet, 2);
|
||||
}
|
||||
|
||||
/* close Level 1 */
|
||||
if (state & CLOSE_LEVEL1) {
|
||||
switch (packet->prev_attr_cp[1]) {
|
||||
case OSPF_LSA_ROUTER:
|
||||
case OSPF_LSA_EXTERNAL:
|
||||
case OSPF_LSA_OPAQUE_AREA_RI:
|
||||
case OSPF_LSA_OPAQUE_AREA_EP:
|
||||
case OSPF_LSA_INTRA_AREA_PREFIX:
|
||||
inc_be_uint(buf0->data+40+16, 4); /* Update #LSAs */
|
||||
write_be_uint(buf1->data+18, 2, buf1->idx); /* Update Packet length */
|
||||
write_be_uint(buf1->data+16, 2, 0); /* reset checksum field */
|
||||
checksum = calculate_fletcher_cksum(buf1->data+2, 14, buf1->idx-2);
|
||||
write_be_uint(buf1->data+16, 2, checksum); /* Update LSA Checksum */
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
lspgen_propagate_buffer_up(packet, 1);
|
||||
}
|
||||
|
||||
/* close Level 0 */
|
||||
if (state & CLOSE_LEVEL0) {
|
||||
switch (packet->prev_attr_cp[0]) {
|
||||
case OSPF_MSG_LSUPDATE:
|
||||
write_be_uint(buf0->data+40+2, 2, buf0->idx - 40); /* Packet length */
|
||||
write_be_uint(buf0->data+40+12, 2, calculate_cksum(buf0->data+40, buf0->idx-40)); /* Checksum */
|
||||
write_be_uint(buf0->data+4, 2, buf0->idx - 40); /* Payload length */
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* open Level 0 */
|
||||
if (state & OPEN_LEVEL0) {
|
||||
|
||||
switch(attr->key.attr_cp[0]) {
|
||||
case OSPF_MSG_LSUPDATE:
|
||||
|
||||
/* IPv6 header */
|
||||
push_be_uint(buf0, 1, 0x6c); /* Version, Traffic Class MSB */
|
||||
push_be_uint(buf0, 3, 0); /* Flow label */
|
||||
push_be_uint(buf0, 2, 0); /* Payload length - will be overwritten later */
|
||||
push_be_uint(buf0, 1, 89); /* Next Header */
|
||||
push_be_uint(buf0, 1, 255); /* Hop limit */
|
||||
push_data(buf0, (uint8_t *)&ctx->ipv6_node_prefix.address, IPV6_ADDR_LEN); /* Source Address */
|
||||
push_be_uint(buf0, 8, 0xff02000000000000); /* Destination Address */
|
||||
push_be_uint(buf0, 8, 5); /* Destination Address */
|
||||
|
||||
/* OSPFv3 header */
|
||||
push_be_uint(buf0, 1, 3); /* Version */
|
||||
push_be_uint(buf0, 1, OSPF_MSG_LSUPDATE); /* Msg */
|
||||
push_be_uint(buf0, 2, 0); /* Packet length - will be overwritten later */
|
||||
|
||||
router_id = read_be_uint(node->key.node_id, 4);
|
||||
push_be_uint(buf0, 4, router_id); /* Router ID */
|
||||
push_be_uint(buf0, 4, ctx->topology_id.area); /* Area ID */
|
||||
|
||||
push_be_uint(buf0, 2, 0); /* Checksum - will be overwritten later */
|
||||
|
||||
push_be_uint(buf0, 1, 0); /* Instance ID */
|
||||
push_be_uint(buf0, 1, 0); /* Reserved */
|
||||
|
||||
push_be_uint(buf0, 4, 0); /* # LSAs - will be overwritten later */
|
||||
break;
|
||||
default:
|
||||
LOG(ERROR, "No Level 0 open packet serializer for attr %d\n", attr->key.attr_cp[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
lspgen_propagate_buffer_down(packet, 0);
|
||||
}
|
||||
|
||||
/* open Level 1 */
|
||||
if (state & OPEN_LEVEL1) {
|
||||
|
||||
switch(attr->key.attr_cp[1]) {
|
||||
case OSPF_LSA_ROUTER:
|
||||
push_be_uint(buf1, 2, lspgen_get_ospf_age(node)); /* LS-age */
|
||||
push_be_uint(buf1, 2, 0x2001); /* LS-Type */
|
||||
router_id = read_be_uint(node->key.node_id, 4);
|
||||
push_be_uint(buf1, 4, router_id); /* Link State ID */
|
||||
push_be_uint(buf1, 4, router_id); /* Advertising Router */
|
||||
push_be_uint(buf1, 4, node->sequence); /* Sequence */
|
||||
push_be_uint(buf1, 2, 0xffff); /* Checksum - will be overwritten later */
|
||||
push_be_uint(buf1, 2, 0); /* Length - will be overwritten later */
|
||||
|
||||
push_be_uint(buf1, 1, 0x02); /* Flags, E */
|
||||
push_be_uint(buf1, 3, 0); /* Options */
|
||||
break;
|
||||
|
||||
case OSPF_LSA_EXTERNAL:
|
||||
push_be_uint(buf1, 2, lspgen_get_ospf_age(node)); /* LS-age */
|
||||
push_be_uint(buf1, 2, 0x4005); /* LS-Type */
|
||||
push_data(buf1, (uint8_t*)&attr->key.prefix.ipv4_prefix.address, 4); /* Link State ID */
|
||||
router_id = read_be_uint(node->key.node_id, 4);
|
||||
push_be_uint(buf1, 4, router_id); /* Advertising Router */
|
||||
push_be_uint(buf1, 4, node->sequence); /* Sequence */
|
||||
push_be_uint(buf1, 2, 0); /* Checksum - will be overwritten later */
|
||||
push_be_uint(buf1, 2, 0); /* Length - will be overwritten later */
|
||||
|
||||
push_be_uint(buf1, 1, 0x04); /* E2 */
|
||||
push_be_uint(buf1, 3, attr->key.prefix.metric); /* Metric */
|
||||
push_be_uint(buf1, 1, attr->key.prefix.ipv6_prefix.len); /* Prefix Length */
|
||||
push_be_uint(buf1, 1, 0x00); /* Prefix Options */
|
||||
push_be_uint(buf1, 2, 0); /* Referenced LS Type */
|
||||
attr_len = (attr->key.prefix.ipv6_prefix.len+7)/8;
|
||||
push_data(buf1, attr->key.prefix.ipv6_prefix.address, attr_len); /* Prefix */
|
||||
push_pad4(buf1);
|
||||
break;
|
||||
|
||||
case OSPF_LSA_INTRA_AREA_PREFIX:
|
||||
push_be_uint(buf1, 2, lspgen_get_ospf_age(node)); /* LS-age */
|
||||
push_be_uint(buf1, 2, 0x2009); /* LS-Type */
|
||||
push_data(buf1, (uint8_t*)&attr->key.prefix.ipv4_prefix.address, 4); /* Link State ID */
|
||||
router_id = read_be_uint(node->key.node_id, 4);
|
||||
push_be_uint(buf1, 4, router_id); /* Advertising Router */
|
||||
push_be_uint(buf1, 4, node->sequence); /* Sequence */
|
||||
push_be_uint(buf1, 2, 0); /* Checksum - will be overwritten later */
|
||||
push_be_uint(buf1, 2, 0); /* Length - will be overwritten later */
|
||||
|
||||
push_be_uint(buf1, 2, 0); /* # Prefixes - will be overwritten later */
|
||||
push_be_uint(buf1, 2, 0x2001); /* # Referenced LS Type */
|
||||
|
||||
push_be_uint(buf1, 4, 0); /* Referenced Link State ID */
|
||||
push_be_uint(buf1, 4, router_id); /* Referenced Advertising Router */
|
||||
|
||||
break;
|
||||
|
||||
case OSPF_LSA_OPAQUE_AREA_RI:
|
||||
push_be_uint(buf1, 2, lspgen_get_ospf_age(node)); /* LS-age */
|
||||
push_be_uint(buf1, 2, 0x800c); /* LS-Type */
|
||||
push_be_uint(buf1, 4, 0); /* Link State ID (Instance ID) */
|
||||
router_id = read_be_uint(node->key.node_id, 4);
|
||||
push_be_uint(buf1, 4, router_id); /* Advertising Router */
|
||||
push_be_uint(buf1, 4, node->sequence); /* Sequence */
|
||||
push_be_uint(buf1, 2, 0); /* Checksum - will be overwritten later */
|
||||
push_be_uint(buf1, 2, 0); /* Length - will be overwritten later */
|
||||
break;
|
||||
|
||||
case OSPF_LSA_OPAQUE_AREA_EP:
|
||||
push_be_uint(buf1, 2, lspgen_get_ospf_age(node)); /* LS-age */
|
||||
push_be_uint(buf1, 1, 0); /* Options */
|
||||
push_be_uint(buf1, 1, 10); /* LS-Type */
|
||||
push_be_uint(buf1, 1, 7); /* Opaque Type: Extended Prefix */
|
||||
push_be_uint(buf1, 3, 0); /* Opaque subtype */
|
||||
router_id = read_be_uint(node->key.node_id, 4);
|
||||
push_be_uint(buf1, 4, router_id); /* Advertising Router */
|
||||
push_be_uint(buf1, 4, node->sequence); /* Sequence */
|
||||
push_be_uint(buf1, 2, 0); /* Checksum - will be overwritten later */
|
||||
push_be_uint(buf1, 2, 0); /* Length - will be overwritten later */
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG(ERROR, "No Level 1 open packet serializer for attr %d\n", attr->key.attr_cp[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
lspgen_propagate_buffer_down(packet, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* If users wants to generate purges encoding stops at level 1.
|
||||
*/
|
||||
if (ctx->purge) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* open Level 2 */
|
||||
if (state & OPEN_LEVEL2) {
|
||||
switch(attr->key.attr_cp[2]) {
|
||||
case OSPF_ROUTER_LSA_LINK_PTP:
|
||||
push_be_uint(buf2, 1, 1); /* Type ptp */
|
||||
push_be_uint(buf2, 1, 0); /* #TOS */
|
||||
push_be_uint(buf2, 2, attr->key.link.metric); /* metric */
|
||||
push_be_uint(buf2, 4, read_be_uint(attr->key.link.local_node_id, 4)); /* Interface ID */
|
||||
push_be_uint(buf2, 4, 0); /* Neighbor Interface ID */
|
||||
push_be_uint(buf2, 4, read_be_uint(attr->key.link.remote_node_id, 4)); /* Neighbor Router ID */
|
||||
break;
|
||||
|
||||
case OSPF_IA_PREFIX_LSA_PREFIX:
|
||||
push_be_uint(buf2, 1, attr->key.prefix.ipv6_prefix.len); /* Prefix Length */
|
||||
push_be_uint(buf2, 1, 0x00); /* Prefix Options */
|
||||
push_be_uint(buf2, 2, attr->key.prefix.metric); /* Metric */
|
||||
attr_len = (attr->key.prefix.ipv6_prefix.len+7)/8;
|
||||
push_data(buf2, attr->key.prefix.ipv6_prefix.address, attr_len); /* Prefix */
|
||||
push_pad4(buf2);
|
||||
|
||||
inc_be_uint(buf1->data+20, 2); /* Update #prefixes */
|
||||
break;
|
||||
|
||||
case OSPF_TLV_HOSTNAME:
|
||||
attr_len = strnlen(attr->key.hostname, sizeof(attr->key.hostname));
|
||||
if (attr_len) {
|
||||
push_be_uint(buf2, 2, 7); /* Type */
|
||||
push_be_uint(buf2, 2, attr_len); /* Length */
|
||||
push_data(buf2, (uint8_t *)attr->key.hostname, attr_len);
|
||||
push_pad4(buf2);
|
||||
}
|
||||
break;
|
||||
|
||||
case OSPF_TLV_SID_LABEL_RANGE:
|
||||
if (attr->key.cap.srgb_base && attr->key.cap.srgb_range) {
|
||||
push_be_uint(buf2, 2, 9); /* Type */
|
||||
@@ -1002,7 +1300,7 @@ lspgen_serialize_ospf2_state(lsdb_attr_t *attr, lsdb_packet_t *packet, uint16_t
|
||||
push_be_uint(buf2, 4, attr->key.prefix.sid); /* SID Index */
|
||||
push_pad4(buf2);
|
||||
|
||||
write_be_uint(buf2->data+2, 2, buf2->idx-4); /* Update length */
|
||||
//write_be_uint(buf2->data+2, 2, buf2->idx-4); /* Update length */
|
||||
push_pad4(buf2);
|
||||
break;
|
||||
|
||||
@@ -1016,10 +1314,12 @@ lspgen_serialize_ospf2_state(lsdb_attr_t *attr, lsdb_packet_t *packet, uint16_t
|
||||
}
|
||||
|
||||
/*
|
||||
* Serialize an OSPFv2 attribute into a packet buffer.
|
||||
* Serialize an OSPF attribute into a packet buffer.
|
||||
* Pass a custom serialization callback function.
|
||||
*/
|
||||
void
|
||||
lspgen_serialize_ospf2_attr(lsdb_attr_t *attr, lsdb_packet_t *packet)
|
||||
lspgen_serialize_ospf_attr(lsdb_attr_t *attr, lsdb_packet_t *packet,
|
||||
void (*serialize_cb)(lsdb_attr_t *, lsdb_packet_t *, uint16_t))
|
||||
{
|
||||
uint16_t state;
|
||||
|
||||
@@ -1043,9 +1343,12 @@ lspgen_serialize_ospf2_attr(lsdb_attr_t *attr, lsdb_packet_t *packet)
|
||||
state |= OPEN_LEVEL1;
|
||||
if (attr->key.attr_cp[2] && packet->prev_attr_cp[2] == 0) {
|
||||
state |= OPEN_LEVEL2;
|
||||
if (attr->key.attr_cp[3] && packet->prev_attr_cp[3] == 0) {
|
||||
state |= OPEN_LEVEL3;
|
||||
}
|
||||
}
|
||||
}
|
||||
lspgen_serialize_ospf2_state(attr, packet, state);
|
||||
(*serialize_cb)(attr, packet, state);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1057,6 +1360,12 @@ lspgen_serialize_ospf2_attr(lsdb_attr_t *attr, lsdb_packet_t *packet)
|
||||
if (attr->key.attr_cp[0]) {
|
||||
state |= OPEN_LEVEL0;
|
||||
}
|
||||
if (packet->prev_attr_cp[3]) {
|
||||
state |= CLOSE_LEVEL3;
|
||||
}
|
||||
if (attr->key.attr_cp[3]) {
|
||||
state |= OPEN_LEVEL3;
|
||||
}
|
||||
if (packet->prev_attr_cp[2]) {
|
||||
state |= CLOSE_LEVEL2;
|
||||
}
|
||||
@@ -1069,7 +1378,7 @@ lspgen_serialize_ospf2_attr(lsdb_attr_t *attr, lsdb_packet_t *packet)
|
||||
if (attr->key.attr_cp[1]) {
|
||||
state |= OPEN_LEVEL1;
|
||||
}
|
||||
lspgen_serialize_ospf2_state(attr, packet, state);
|
||||
(*serialize_cb)(attr, packet, state);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1087,7 +1396,13 @@ lspgen_serialize_ospf2_attr(lsdb_attr_t *attr, lsdb_packet_t *packet)
|
||||
if (attr->key.attr_cp[2]) {
|
||||
state |= OPEN_LEVEL2;
|
||||
}
|
||||
lspgen_serialize_ospf2_state(attr, packet, state);
|
||||
if (packet->prev_attr_cp[3]) {
|
||||
state |= CLOSE_LEVEL3;
|
||||
}
|
||||
if (attr->key.attr_cp[3]) {
|
||||
state |= OPEN_LEVEL3;
|
||||
}
|
||||
(*serialize_cb)(attr, packet, state);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1099,7 +1414,25 @@ lspgen_serialize_ospf2_attr(lsdb_attr_t *attr, lsdb_packet_t *packet)
|
||||
if (attr->key.attr_cp[2]) {
|
||||
state |= OPEN_LEVEL2;
|
||||
}
|
||||
lspgen_serialize_ospf2_state(attr, packet, state);
|
||||
if (packet->prev_attr_cp[3]) {
|
||||
state |= CLOSE_LEVEL3;
|
||||
}
|
||||
if (attr->key.attr_cp[3]) {
|
||||
state |= OPEN_LEVEL3;
|
||||
}
|
||||
(*serialize_cb)(attr, packet, state);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Different L3 message ?
|
||||
*/
|
||||
if (packet->prev_attr_cp[3] != attr->key.attr_cp[3]) {
|
||||
state |= CLOSE_LEVEL3;
|
||||
if (attr->key.attr_cp[3]) {
|
||||
state |= OPEN_LEVEL3;
|
||||
}
|
||||
(*serialize_cb)(attr, packet, state);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1111,7 +1444,9 @@ lspgen_serialize_ospf2_attr(lsdb_attr_t *attr, lsdb_packet_t *packet)
|
||||
/*
|
||||
* Figure out max level.
|
||||
*/
|
||||
if (attr->key.attr_cp[2]) {
|
||||
if (attr->key.attr_cp[3]) {
|
||||
state |= OPEN_LEVEL3;
|
||||
} else if (attr->key.attr_cp[2]) {
|
||||
state |= OPEN_LEVEL2;
|
||||
} else if (attr->key.attr_cp[1]) {
|
||||
state |= OPEN_LEVEL1;
|
||||
@@ -1126,7 +1461,7 @@ lspgen_serialize_ospf2_attr(lsdb_attr_t *attr, lsdb_packet_t *packet)
|
||||
state |= state << 8;
|
||||
}
|
||||
|
||||
lspgen_serialize_ospf2_state(attr, packet, state);
|
||||
(*serialize_cb)(attr, packet, state);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1146,7 +1481,10 @@ lspgen_serialize_attr(lsdb_ctx_t *ctx, lsdb_attr_t *attr, lsdb_packet_t *packet)
|
||||
lspgen_serialize_isis_attr(attr, packet);
|
||||
break;
|
||||
case PROTO_OSPF2:
|
||||
lspgen_serialize_ospf2_attr(attr, packet);
|
||||
lspgen_serialize_ospf_attr(attr, packet, lspgen_serialize_ospf2_state);
|
||||
break;
|
||||
case PROTO_OSPF3:
|
||||
lspgen_serialize_ospf_attr(attr, packet, lspgen_serialize_ospf3_state);
|
||||
break;
|
||||
default:
|
||||
LOG_NOARG(ERROR, "Unknown protocol\n");
|
||||
@@ -1189,14 +1527,17 @@ lspgen_calculate_tlv_space(io_buffer_t *buf, uint32_t tlv_start_idx)
|
||||
void
|
||||
lspgen_reset_packet_buffer (struct lsdb_packet_ *packet)
|
||||
{
|
||||
struct io_buffer_ *buf;
|
||||
uint idx;
|
||||
|
||||
packet->buf.data = packet->data;
|
||||
packet->buf.start_idx = 0;
|
||||
packet->buf.idx = 0;
|
||||
packet->buf.size = sizeof(packet->data);
|
||||
for (idx = 0; idx < MAX_MSG_LEVEL; idx++) {
|
||||
memcpy(&packet->bufX[idx], &packet->buf, sizeof(struct io_buffer_));
|
||||
buf = &packet->buf[0];
|
||||
|
||||
buf->data = packet->data;
|
||||
buf->start_idx = 0;
|
||||
buf->idx = 0;
|
||||
buf->size = sizeof(packet->data);
|
||||
for (idx = 1; idx < MAX_MSG_LEVEL; idx++) {
|
||||
memcpy(&packet->buf[idx], buf, sizeof(struct io_buffer_));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1377,9 +1718,9 @@ lspgen_gen_isis_packet_node(lsdb_node_t *node)
|
||||
/*
|
||||
* Space left in this packet ?
|
||||
*/
|
||||
min_len = lspgen_calculate_isis_auth_len(ctx);
|
||||
min_len = lspgen_calculate_auth_len(ctx);
|
||||
min_len += attr->size + TLV_OVERHEAD;
|
||||
if (packet && packet->buf.idx > (1465-min_len)) {
|
||||
if (packet && packet->buf[0].idx > (1465-min_len)) {
|
||||
|
||||
/*
|
||||
* No space left. Finalize this packet.
|
||||
@@ -1400,7 +1741,7 @@ lspgen_gen_isis_packet_node(lsdb_node_t *node)
|
||||
*/
|
||||
if (!packet) {
|
||||
packet = lspgen_add_packet(ctx, node, id);
|
||||
tlv_start_idx = packet->buf.idx;
|
||||
tlv_start_idx = packet->buf[0].idx;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1411,15 +1752,15 @@ lspgen_gen_isis_packet_node(lsdb_node_t *node)
|
||||
* Start a fresh TLV ?
|
||||
*/
|
||||
if ((last_attr != attr->key.attr_type) ||
|
||||
(lspgen_calculate_tlv_space(&packet->buf, tlv_start_idx) < attr->size) ||
|
||||
(lspgen_calculate_tlv_space(&packet->buf[0], tlv_start_idx) < attr->size) ||
|
||||
attr->key.start_tlv) {
|
||||
tlv_start_idx = packet->buf.idx;
|
||||
push_be_uint(&packet->buf, 1, attr->key.attr_type); /* Type */
|
||||
push_be_uint(&packet->buf, 1, 0); /* Length */
|
||||
tlv_start_idx = packet->buf[0].idx;
|
||||
push_be_uint(&packet->buf[0], 1, attr->key.attr_type); /* Type */
|
||||
push_be_uint(&packet->buf[0], 1, 0); /* Length */
|
||||
}
|
||||
|
||||
lspgen_serialize_attr(ctx, attr, packet);
|
||||
lspgen_update_tlv_length(&packet->buf, tlv_start_idx);
|
||||
lspgen_update_tlv_length(&packet->buf[0], tlv_start_idx);
|
||||
|
||||
last_attr = attr->key.attr_type;
|
||||
|
||||
@@ -1430,10 +1771,10 @@ lspgen_gen_isis_packet_node(lsdb_node_t *node)
|
||||
}
|
||||
|
||||
/*
|
||||
* Walk the graph of the LSDB and serialize OSPFv2 packets.
|
||||
* Walk the graph of the LSDB and serialize OSPF2 and OSPF3 packets.
|
||||
*/
|
||||
void
|
||||
lspgen_gen_ospf2_packet_node(lsdb_node_t *node)
|
||||
lspgen_gen_ospf_packet_node(lsdb_node_t *node)
|
||||
{
|
||||
lsdb_ctx_t *ctx;
|
||||
struct lsdb_packet_ *packet;
|
||||
@@ -1491,9 +1832,9 @@ lspgen_gen_ospf2_packet_node(lsdb_node_t *node)
|
||||
/*
|
||||
* Space left in this packet ?
|
||||
*/
|
||||
min_len = lspgen_calculate_isis_auth_len(ctx);
|
||||
min_len = lspgen_calculate_auth_len(ctx);
|
||||
min_len += attr->size;
|
||||
if (packet && packet->bufX[0].idx > (1440-min_len)) {
|
||||
if (packet && packet->buf[0].idx > (1440-min_len)) {
|
||||
|
||||
/*
|
||||
* No space left. Finalize this packet.
|
||||
@@ -1537,8 +1878,9 @@ lspgen_gen_packet_node(lsdb_node_t *node)
|
||||
case PROTO_ISIS:
|
||||
lspgen_gen_isis_packet_node(node);
|
||||
break;
|
||||
case PROTO_OSPF2:
|
||||
lspgen_gen_ospf2_packet_node(node);
|
||||
case PROTO_OSPF2: /* fall through */
|
||||
case PROTO_OSPF3:
|
||||
lspgen_gen_ospf_packet_node(node);
|
||||
break;
|
||||
default:
|
||||
LOG_NOARG(ERROR, "Unknown protocol\n");
|
||||
|
||||
@@ -161,13 +161,13 @@ lspgen_dump_pcap_node (struct lsdb_ctx_ *ctx, struct lsdb_node_ *node)
|
||||
|
||||
/* Account for the the faked ethernet & LLC header */
|
||||
eth_header_length = 17;
|
||||
push_le_uint(&buf, 4, packet->buf.idx+eth_header_length); /* captured packet length */
|
||||
push_le_uint(&buf, 4, packet->buf.idx+eth_header_length); /* original packet length */
|
||||
push_le_uint(&buf, 4, packet->buf[0].idx+eth_header_length); /* captured packet length */
|
||||
push_le_uint(&buf, 4, packet->buf[0].idx+eth_header_length); /* original packet length */
|
||||
|
||||
/* Fake an Ethernet & LLC header */
|
||||
push_be_uint(&buf, 6, 0x0180c2000014); /* Destination MAC */
|
||||
push_be_uint(&buf, 6, 0xf41e5e000000); /* Source MAC MAC */
|
||||
push_be_uint(&buf, 2, packet->buf.idx+3); /* Length + DSAP, SSAP, Mode */
|
||||
push_be_uint(&buf, 2, packet->buf[0].idx+3); /* Length + DSAP, SSAP, Mode */
|
||||
push_be_uint(&buf, 3, 0xfefe03); /* OSI DSAP, SSAP, Mode */
|
||||
|
||||
} else if (ctx->protocol_id == PROTO_OSPF2) {
|
||||
@@ -176,8 +176,8 @@ lspgen_dump_pcap_node (struct lsdb_ctx_ *ctx, struct lsdb_node_ *node)
|
||||
|
||||
/* Account for the faked Ethernet header */
|
||||
eth_header_length = 14;
|
||||
push_le_uint(&buf, 4, packet->buf.idx+eth_header_length); /* captured packet length */
|
||||
push_le_uint(&buf, 4, packet->buf.idx+eth_header_length); /* original packet length */
|
||||
push_le_uint(&buf, 4, packet->buf[0].idx+eth_header_length); /* captured packet length */
|
||||
push_le_uint(&buf, 4, packet->buf[0].idx+eth_header_length); /* original packet length */
|
||||
|
||||
/* Fake an Ethernet header */
|
||||
push_be_uint(&buf, 6, 0x01005e000005); /* Destination MAC */
|
||||
@@ -190,8 +190,8 @@ lspgen_dump_pcap_node (struct lsdb_ctx_ *ctx, struct lsdb_node_ *node)
|
||||
|
||||
/* Account for the faked Ethernet header */
|
||||
eth_header_length = 14;
|
||||
push_le_uint(&buf, 4, packet->buf.idx+eth_header_length); /* captured packet length */
|
||||
push_le_uint(&buf, 4, packet->buf.idx+eth_header_length); /* original packet length */
|
||||
push_le_uint(&buf, 4, packet->buf[0].idx+eth_header_length); /* captured packet length */
|
||||
push_le_uint(&buf, 4, packet->buf[0].idx+eth_header_length); /* original packet length */
|
||||
|
||||
/* Fake an Ethernet header */
|
||||
push_be_uint(&buf, 6, 0x333300000005); /* Destination MAC */
|
||||
@@ -202,9 +202,9 @@ lspgen_dump_pcap_node (struct lsdb_ctx_ *ctx, struct lsdb_node_ *node)
|
||||
/*
|
||||
* Copy packet
|
||||
*/
|
||||
memcpy(&pcap_packet[buf.idx], packet->data, packet->buf.idx);
|
||||
buf.idx += packet->buf.idx;
|
||||
push_le_uint(&buf, calc_pad(packet->buf.idx+eth_header_length), 0); /* write pad bytes */
|
||||
memcpy(&pcap_packet[buf.idx], packet->data, packet->buf[0].idx);
|
||||
buf.idx += packet->buf[0].idx;
|
||||
push_le_uint(&buf, calc_pad(packet->buf[0].idx+eth_header_length), 0); /* write pad bytes */
|
||||
|
||||
/*
|
||||
* Calculate total length field. It occurs twice. Overwrite and append.
|
||||
|
||||
Reference in New Issue
Block a user