static void ospf_packet_ls_req_dump(struct stream *s, uint16_t length) { uint32_t sp; uint32_t ls_type; struct in_addr ls_id; struct in_addr adv_router; sp = stream_get_getp(s); length -= OSPF_HEADER_SIZE; zlog_debug("Link State Request"); zlog_debug(" # Requests %d", length / 12); for (; length > 0; length -= 12) { ls_type = stream_getl(s); ls_id.s_addr = stream_get_ipv4(s); adv_router.s_addr = stream_get_ipv4(s); zlog_debug(" LS type %d", ls_type); zlog_debug(" Link State ID %s", inet_ntoa(ls_id)); zlog_debug(" Advertising Router %s", inet_ntoa(adv_router)); } stream_set_getp(s, sp); }
static void link_params_set_value(struct stream *s, struct if_link_params *iflp) { if (iflp == NULL) return; iflp->lp_status = stream_getl (s); iflp->te_metric = stream_getl (s); iflp->max_bw = stream_getf (s); iflp->max_rsv_bw = stream_getf (s); uint32_t bwclassnum = stream_getl (s); { unsigned int i; for (i = 0; i < bwclassnum && i < MAX_CLASS_TYPE; i++) iflp->unrsv_bw[i] = stream_getf (s); if (i < bwclassnum) zlog_err ("%s: received %d > %d (MAX_CLASS_TYPE) bw entries" " - outdated library?", __func__, bwclassnum, MAX_CLASS_TYPE); } iflp->admin_grp = stream_getl (s); iflp->rmt_as = stream_getl (s); iflp->rmt_ip.s_addr = stream_get_ipv4 (s); iflp->av_delay = stream_getl (s); iflp->min_delay = stream_getl (s); iflp->max_delay = stream_getl (s); iflp->delay_var = stream_getl (s); iflp->pkt_loss = stream_getf (s); iflp->res_bw = stream_getf (s); iflp->ava_bw = stream_getf (s); iflp->use_bw = stream_getf (s); }
static int attr_parse (struct stream *s, u_int16_t len) { u_int flag; u_int type; u_int16_t length; u_int16_t lim; lim = s->getp + len; printf ("attr_parse s->getp %zd, len %d, lim %d\n", s->getp, len, lim); while (s->getp < lim) { flag = stream_getc (s); type = stream_getc (s); if (flag & BGP_ATTR_FLAG_EXTLEN) length = stream_getw (s); else length = stream_getc (s); printf ("FLAG: %d\n", flag); printf ("TYPE: %d\n", type); printf ("Len: %d\n", length); switch (type) { case BGP_ATTR_ORIGIN: { u_char origin; origin = stream_getc (s); printf ("ORIGIN: %d\n", origin); } break; case BGP_ATTR_AS_PATH: { struct aspath *aspath; aspath = aspath_parse (s, length, 1); printf ("ASPATH: %s\n", aspath->str); aspath_free(aspath); } break; case BGP_ATTR_NEXT_HOP: { struct in_addr nexthop; nexthop.s_addr = stream_get_ipv4 (s); printf ("NEXTHOP: %s\n", inet_ntoa (nexthop)); } break; default: stream_getw_from (s, length); break; } } return 0; }
/* Nexthop lookup for IPv4. */ static void zread_ipv4_nexthop_lookup (struct zserv *client, u_short length) { struct in_addr addr; addr.s_addr = stream_get_ipv4 (client->ibuf); zsend_ipv4_nexthop_lookup (client, addr); }
/* Nexthop lookup for IPv4. */ static void zread_ipv4_import_lookup (struct zserv *client, u_short length) { struct prefix_ipv4 p; p.family = AF_INET; p.prefixlen = stream_getc (client->ibuf); p.prefix.s_addr = stream_get_ipv4 (client->ibuf); zsend_ipv4_import_lookup (client, &p); }
/* Zebra route add and delete treatment. */ static int rip_zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length) { struct stream *s; struct zapi_ipv4 api; unsigned long ifindex; struct in_addr nexthop; struct prefix_ipv4 p; s = zclient->ibuf; ifindex = 0; nexthop.s_addr = 0; /* Type, flags, message. */ api.type = stream_getc (s); api.flags = stream_getc (s); api.message = stream_getc (s); /* IPv4 prefix. */ memset (&p, 0, sizeof (struct prefix_ipv4)); p.family = AF_INET; p.prefixlen = stream_getc (s); stream_get (&p.prefix, s, PSIZE (p.prefixlen)); /* Nexthop, ifindex, distance, metric. */ if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP)) { api.nexthop_num = stream_getc (s); nexthop.s_addr = stream_get_ipv4 (s); } if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX)) { api.ifindex_num = stream_getc (s); ifindex = stream_getl (s); } if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE)) api.distance = stream_getc (s); else api.distance = 255; if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC)) api.metric = stream_getl (s); else api.metric = 0; /* Then fetch IPv4 prefixes. */ if (command == ZEBRA_IPV4_ROUTE_ADD) rip_redistribute_add (api.type, RIP_ROUTE_REDISTRIBUTE, &p, ifindex, &nexthop, api.metric, api.distance); else rip_redistribute_delete (api.type, RIP_ROUTE_REDISTRIBUTE, &p, ifindex); return 0; }
/* Nexthop lookup for IPv4. */ static int zread_ipv4_nexthop_lookup (struct zserv *client, u_short length) { struct in_addr addr; char buf[BUFSIZ]; addr.s_addr = stream_get_ipv4 (client->ibuf); if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV) zlog_debug("%s: looking up %s", __func__, inet_ntop (AF_INET, &addr, buf, BUFSIZ)); return zsend_ipv4_nexthop_lookup (client, addr); }
int isis_zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length) { struct stream *stream; struct zapi_ipv4 api; struct prefix_ipv4 p; unsigned long ifindex; struct in_addr nexthop; stream = zclient->ibuf; memset (&p, 0, sizeof (struct prefix_ipv4)); ifindex = 0; api.type = stream_getc (stream); api.flags = stream_getc (stream); api.message = stream_getc (stream); p.family = AF_INET; p.prefixlen = stream_getc (stream); stream_get (&p.prefix, stream, PSIZE (p.prefixlen)); if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP)) { api.nexthop_num = stream_getc (stream); nexthop.s_addr = stream_get_ipv4 (stream); } if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX)) { api.ifindex_num = stream_getc (stream); ifindex = stream_getl (stream); } if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE)) api.distance = stream_getc (stream); if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC)) api.metric = stream_getl (stream); else api.metric = 0; if (command == ZEBRA_IPV4_ROUTE_ADD) { zlog_debug ("IPv4 Route add from Z"); } return 0; }
static int bgp_import_check (struct prefix *p, u_int32_t *igpmetric, struct in_addr *igpnexthop) { struct stream *s; int ret; u_int16_t length, command; u_char version, marker; int nbytes; struct in_addr addr; struct in_addr nexthop; u_int32_t metric = 0; u_char nexthop_num; u_char nexthop_type; /* If lookup connection is not available return valid. */ if (zlookup->sock < 0) { if (igpmetric) *igpmetric = 0; return 1; } /* Send query to the lookup connection */ s = zlookup->obuf; stream_reset (s); zclient_create_header (s, ZEBRA_IPV4_IMPORT_LOOKUP); stream_putc (s, p->prefixlen); stream_put_in_addr (s, &p->u.prefix4); stream_putw_at (s, 0, stream_get_endp (s)); /* Write the packet. */ ret = writen (zlookup->sock, s->data, stream_get_endp (s)); if (ret < 0) { zlog_err ("can't write to zlookup->sock"); close (zlookup->sock); zlookup->sock = -1; return 1; } if (ret == 0) { zlog_err ("zlookup->sock connection closed"); close (zlookup->sock); zlookup->sock = -1; return 1; } /* Get result. */ stream_reset (s); /* Fetch length. */ nbytes = stream_read (s, zlookup->sock, 2); length = stream_getw (s); /* Fetch whole data. */ nbytes = stream_read (s, zlookup->sock, length - 2); marker = stream_getc (s); version = stream_getc (s); if (version != ZSERV_VERSION || marker != ZEBRA_HEADER_MARKER) { zlog_err("%s: socket %d version mismatch, marker %d, version %d", __func__, zlookup->sock, marker, version); return 0; } command = stream_getw (s); addr.s_addr = stream_get_ipv4 (s); metric = stream_getl (s); nexthop_num = stream_getc (s); /* Set IGP metric value. */ if (igpmetric) *igpmetric = metric; /* If there is nexthop then this is active route. */ if (nexthop_num) { nexthop.s_addr = 0; nexthop_type = stream_getc (s); if (nexthop_type == ZEBRA_NEXTHOP_IPV4) { nexthop.s_addr = stream_get_ipv4 (s); if (igpnexthop) *igpnexthop = nexthop; } else *igpnexthop = nexthop; return 1; } else return 0; }
static struct bgp_nexthop_cache * zlookup_read (void) { struct stream *s; uint16_t length; u_char marker; u_char version; uint16_t command; int nbytes; struct in_addr raddr; uint32_t metric; int i; u_char nexthop_num; struct nexthop *nexthop; struct bgp_nexthop_cache *bnc; s = zlookup->ibuf; stream_reset (s); nbytes = stream_read (s, zlookup->sock, 2); length = stream_getw (s); nbytes = stream_read (s, zlookup->sock, length - 2); marker = stream_getc (s); version = stream_getc (s); if (version != ZSERV_VERSION || marker != ZEBRA_HEADER_MARKER) { zlog_err("%s: socket %d version mismatch, marker %d, version %d", __func__, zlookup->sock, marker, version); return NULL; } command = stream_getw (s); raddr.s_addr = stream_get_ipv4 (s); metric = stream_getl (s); nexthop_num = stream_getc (s); if (nexthop_num) { bnc = bnc_new (); bnc->valid = 1; bnc->metric = metric; bnc->nexthop_num = nexthop_num; for (i = 0; i < nexthop_num; i++) { nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop)); nexthop->type = stream_getc (s); switch (nexthop->type) { case ZEBRA_NEXTHOP_IPV4: nexthop->gate.ipv4.s_addr = stream_get_ipv4 (s); break; case ZEBRA_NEXTHOP_IFINDEX: case ZEBRA_NEXTHOP_IFNAME: nexthop->ifindex = stream_getl (s); break; default: /* do nothing */ break; } bnc_nexthop_add (bnc, nexthop); } } else return NULL; return bnc; }
/* Zebra server IPv4 prefix delete function. */ static void zread_ipv4_delete (struct zserv *client, u_short length) { int i; struct stream *s; struct zapi_ipv4 api; struct in_addr nexthop; unsigned long ifindex; struct prefix_ipv4 p; u_char nexthop_num; u_char nexthop_type; u_char ifname_len; s = client->ibuf; ifindex = 0; nexthop.s_addr = 0; /* Type, flags, message. */ api.type = stream_getc (s); api.flags = stream_getc (s); api.message = stream_getc (s); /* IPv4 prefix. */ memset (&p, 0, sizeof (struct prefix_ipv4)); p.family = AF_INET; p.prefixlen = stream_getc (s); stream_get (&p.prefix, s, PSIZE (p.prefixlen)); /* Nexthop, ifindex, distance, metric. */ if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP)) { nexthop_num = stream_getc (s); for (i = 0; i < nexthop_num; i++) { nexthop_type = stream_getc (s); switch (nexthop_type) { case ZEBRA_NEXTHOP_IFINDEX: ifindex = stream_getl (s); break; case ZEBRA_NEXTHOP_IFNAME: ifname_len = stream_getc (s); stream_forward (s, ifname_len); break; case ZEBRA_NEXTHOP_IPV4: nexthop.s_addr = stream_get_ipv4 (s); break; case ZEBRA_NEXTHOP_IPV6: stream_forward (s, IPV6_MAX_BYTELEN); break; } } } /* Distance. */ if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE)) api.distance = stream_getc (s); else api.distance = 0; /* Metric. */ if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC)) api.metric = stream_getl (s); else api.metric = 0; rib_delete_ipv4 (api.type, api.flags, &p, &nexthop, ifindex, client->rtm_table); }
/* * Parse the ZEBRA_IPV4_ROUTE_ADD sent from client. Update rib and * add kernel route. */ static void zread_ipv4_add (struct zserv *client, u_short length) { int i; struct rib *rib; struct prefix_ipv4 p; u_char message; struct in_addr nexthop; u_char nexthop_num; u_char nexthop_type; struct stream *s; unsigned int ifindex; u_char ifname_len; /* Get input stream. */ s = client->ibuf; /* Allocate new rib. */ rib = XMALLOC (MTYPE_RIB, sizeof (struct rib)); memset (rib, 0, sizeof (struct rib)); /* Type, flags, message. */ rib->type = stream_getc (s); rib->flags = stream_getc (s); message = stream_getc (s); rib->uptime = time (NULL); /* IPv4 prefix. */ memset (&p, 0, sizeof (struct prefix_ipv4)); p.family = AF_INET; p.prefixlen = stream_getc (s); stream_get (&p.prefix, s, PSIZE (p.prefixlen)); /* Nexthop parse. */ if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP)) { nexthop_num = stream_getc (s); for (i = 0; i < nexthop_num; i++) { nexthop_type = stream_getc (s); switch (nexthop_type) { case ZEBRA_NEXTHOP_IFINDEX: ifindex = stream_getl (s); nexthop_ifindex_add (rib, ifindex); break; case ZEBRA_NEXTHOP_IFNAME: ifname_len = stream_getc (s); stream_forward (s, ifname_len); break; case ZEBRA_NEXTHOP_IPV4: nexthop.s_addr = stream_get_ipv4 (s); nexthop_ipv4_add (rib, &nexthop); break; case ZEBRA_NEXTHOP_IPV6: stream_forward (s, IPV6_MAX_BYTELEN); break; case ZEBRA_NEXTHOP_BLACKHOLE: nexthop_blackhole_add (rib); break; } } } /* Distance. */ if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE)) rib->distance = stream_getc (s); /* Metric. */ if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC)) rib->metric = stream_getl (s); rib_add_ipv4_multipath (&p, rib); }
static int zclient_read_nexthop(struct zclient *zlookup, struct pim_zlookup_nexthop nexthop_tab[], const int tab_size, struct in_addr addr) { int num_ifindex = 0; struct stream *s; const uint16_t MIN_LEN = 14; /* getc=1 getc=1 getw=2 getipv4=4 getc=1 getl=4 getc=1 */ uint16_t length, len; u_char marker; u_char version; uint16_t command; int nbytes; struct in_addr raddr; uint8_t distance; uint32_t metric; int nexthop_num; int i; if (PIM_DEBUG_ZEBRA) { char addr_str[100]; pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str)); zlog_debug("%s: addr=%s", __PRETTY_FUNCTION__, addr_str); } s = zlookup->ibuf; stream_reset(s); nbytes = stream_read(s, zlookup->sock, 2); if (nbytes < 2) { zlog_err("%s %s: failure reading zclient lookup socket: nbytes=%d", __FILE__, __PRETTY_FUNCTION__, nbytes); zclient_lookup_failed(zlookup); return -1; } length = stream_getw(s); len = length - 2; if (len < MIN_LEN) { zlog_err("%s %s: failure reading zclient lookup socket: len=%d < MIN_LEN=%d", __FILE__, __PRETTY_FUNCTION__, len, MIN_LEN); zclient_lookup_failed(zlookup); return -2; } nbytes = stream_read(s, zlookup->sock, len); if (nbytes < (length - 2)) { zlog_err("%s %s: failure reading zclient lookup socket: nbytes=%d < len=%d", __FILE__, __PRETTY_FUNCTION__, nbytes, len); zclient_lookup_failed(zlookup); return -3; } marker = stream_getc(s); version = stream_getc(s); if (version != ZSERV_VERSION || marker != ZEBRA_HEADER_MARKER) { zlog_err("%s: socket %d version mismatch, marker %d, version %d", __func__, zlookup->sock, marker, version); return -4; } command = stream_getw(s); if (command != ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB) { zlog_err("%s: socket %d command mismatch: %d", __func__, zlookup->sock, command); return -5; } raddr.s_addr = stream_get_ipv4(s); if (raddr.s_addr != addr.s_addr) { char addr_str[100]; char raddr_str[100]; pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str)); pim_inet4_dump("<raddr?>", raddr, raddr_str, sizeof(raddr_str)); zlog_warn("%s: address mismatch: addr=%s raddr=%s", __PRETTY_FUNCTION__, addr_str, raddr_str); /* warning only */ } distance = stream_getc(s); metric = stream_getl(s); nexthop_num = stream_getc(s); if (nexthop_num < 1) { zlog_err("%s: socket %d bad nexthop_num=%d", __func__, zlookup->sock, nexthop_num); return -6; } len -= MIN_LEN; for (i = 0; i < nexthop_num; ++i) { enum nexthop_types_t nexthop_type; if (len < 1) { zlog_err("%s: socket %d empty input expecting nexthop_type: len=%d", __func__, zlookup->sock, len); return -7; } nexthop_type = stream_getc(s); --len; switch (nexthop_type) { case ZEBRA_NEXTHOP_IFINDEX: case ZEBRA_NEXTHOP_IFNAME: case ZEBRA_NEXTHOP_IPV4_IFINDEX: if (num_ifindex >= tab_size) { char addr_str[100]; pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str)); zlog_warn("%s %s: found too many nexthop ifindexes (%d > %d) for address %s", __FILE__, __PRETTY_FUNCTION__, (num_ifindex + 1), tab_size, addr_str); return num_ifindex; } if (nexthop_type == ZEBRA_NEXTHOP_IPV4_IFINDEX) { if (len < 4) { zlog_err("%s: socket %d short input expecting nexthop IPv4-addr: len=%d", __func__, zlookup->sock, len); return -8; } nexthop_tab[num_ifindex].nexthop_addr.s_addr = stream_get_ipv4(s); len -= 4; } else { nexthop_tab[num_ifindex].nexthop_addr.s_addr = PIM_NET_INADDR_ANY; } nexthop_tab[num_ifindex].ifindex = stream_getl(s); nexthop_tab[num_ifindex].protocol_distance = distance; nexthop_tab[num_ifindex].route_metric = metric; ++num_ifindex; break; case ZEBRA_NEXTHOP_IPV4: if (num_ifindex >= tab_size) { char addr_str[100]; pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str)); zlog_warn("%s %s: found too many nexthop ifindexes (%d > %d) for address %s", __FILE__, __PRETTY_FUNCTION__, (num_ifindex + 1), tab_size, addr_str); return num_ifindex; } nexthop_tab[num_ifindex].nexthop_addr.s_addr = stream_get_ipv4(s); len -= 4; nexthop_tab[num_ifindex].ifindex = 0; nexthop_tab[num_ifindex].protocol_distance = distance; nexthop_tab[num_ifindex].route_metric = metric; { char addr_str[100]; char nexthop_str[100]; pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str)); pim_inet4_dump("<nexthop?>", nexthop_tab[num_ifindex].nexthop_addr, nexthop_str, sizeof(nexthop_str)); zlog_warn("%s %s: zebra returned recursive nexthop %s for address %s", __FILE__, __PRETTY_FUNCTION__, nexthop_str, addr_str); } ++num_ifindex; break; default: /* do nothing */ { char addr_str[100]; pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str)); zlog_warn("%s %s: found non-ifindex nexthop type=%d for address %s", __FILE__, __PRETTY_FUNCTION__, nexthop_type, addr_str); } break; } } return num_ifindex; }
/* Zebra route add and delete treatment. */ static int zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length) { struct stream *s; struct zapi_ipv4 api; struct in_addr nexthop; struct prefix_ipv4 p; s = zclient->ibuf; nexthop.s_addr = 0; /* Type, flags, message. */ api.type = stream_getc (s); api.flags = stream_getc (s); api.message = stream_getc (s); /* IPv4 prefix. */ memset (&p, 0, sizeof (struct prefix_ipv4)); p.family = AF_INET; p.prefixlen = stream_getc (s); stream_get (&p.prefix, s, PSIZE (p.prefixlen)); /* Nexthop, ifindex, distance, metric. */ if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP)) { api.nexthop_num = stream_getc (s); nexthop.s_addr = stream_get_ipv4 (s); } if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX)) { api.ifindex_num = stream_getc (s); stream_getl (s); /* ifindex, unused */ } if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE)) api.distance = stream_getc (s); if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC)) api.metric = stream_getl (s); else api.metric = 0; if (command == ZEBRA_IPV4_ROUTE_ADD) { if (BGP_DEBUG(zebra, ZEBRA)) { char buf[2][INET_ADDRSTRLEN]; zlog_debug("Zebra rcvd: IPv4 route add %s %s/%d nexthop %s metric %u", zebra_route_string(api.type), inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])), p.prefixlen, inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])), api.metric); } bgp_redistribute_add((struct prefix *)&p, &nexthop, NULL, api.metric, api.type); } else { if (BGP_DEBUG(zebra, ZEBRA)) { char buf[2][INET_ADDRSTRLEN]; zlog_debug("Zebra rcvd: IPv4 route delete %s %s/%d " "nexthop %s metric %u", zebra_route_string(api.type), inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])), p.prefixlen, inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])), api.metric); } bgp_redistribute_delete((struct prefix *)&p, api.type); } return 0; }
static int redist_read_ipv4_route(int command, struct zclient *zclient, zebra_size_t length, vrf_id_t vrf_id) { struct stream *s; struct zapi_ipv4 api; unsigned long ifindex; struct in_addr nexthop; struct prefix_ipv4 p; int min_len = 4; if (length < min_len) { zlog_warn("%s %s: short buffer: length=%d min=%d", __FILE__, __PRETTY_FUNCTION__, length, min_len); return -1; } s = zclient->ibuf; ifindex = 0; nexthop.s_addr = 0; /* Type, flags, message. */ api.type = stream_getc(s); api.flags = stream_getc(s); api.message = stream_getc(s); /* IPv4 prefix length. */ memset(&p, 0, sizeof(struct prefix_ipv4)); p.family = AF_INET; p.prefixlen = stream_getc(s); min_len += PSIZE(p.prefixlen) + CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP) ? 5 : 0 + CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX) ? 5 : 0 + CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE) ? 1 : 0 + CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC) ? 4 : 0; if (PIM_DEBUG_ZEBRA) { zlog_debug("%s %s: length=%d min_len=%d flags=%s%s%s%s", __FILE__, __PRETTY_FUNCTION__, length, min_len, CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP) ? "nh" : "", CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX) ? " ifi" : "", CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE) ? " dist" : "", CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC) ? " metr" : ""); } if (length < min_len) { zlog_warn("%s %s: short buffer: length=%d min_len=%d flags=%s%s%s%s", __FILE__, __PRETTY_FUNCTION__, length, min_len, CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP) ? "nh" : "", CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX) ? " ifi" : "", CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE) ? " dist" : "", CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC) ? " metr" : ""); return -1; } /* IPv4 prefix. */ stream_get(&p.prefix, s, PSIZE(p.prefixlen)); /* Nexthop, ifindex, distance, metric. */ if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) { api.nexthop_num = stream_getc(s); nexthop.s_addr = stream_get_ipv4(s); } if (CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX)) { api.ifindex_num = stream_getc(s); ifindex = stream_getl(s); } api.distance = CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE) ? stream_getc(s) : 0; api.metric = CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC) ? stream_getl(s) : 0; switch (command) { case ZEBRA_IPV4_ROUTE_ADD: if (PIM_DEBUG_ZEBRA) { char buf[2][INET_ADDRSTRLEN]; zlog_debug("%s: add %s %s/%d " "nexthop %s ifindex %ld metric%s %u distance%s %u", __PRETTY_FUNCTION__, zebra_route_string(api.type), inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])), p.prefixlen, inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])), ifindex, CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC) ? "-recv" : "-miss", api.metric, CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE) ? "-recv" : "-miss", api.distance); } break; case ZEBRA_IPV4_ROUTE_DELETE: if (PIM_DEBUG_ZEBRA) { char buf[2][INET_ADDRSTRLEN]; zlog_debug("%s: delete %s %s/%d " "nexthop %s ifindex %ld metric%s %u distance%s %u", __PRETTY_FUNCTION__, zebra_route_string(api.type), inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])), p.prefixlen, inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])), ifindex, CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC) ? "-recv" : "-miss", api.metric, CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE) ? "-recv" : "-miss", api.distance); } break; default: zlog_warn("%s: unknown command=%d", __PRETTY_FUNCTION__, command); return -1; } sched_rpf_cache_refresh(); return 0; }
int main (int argc, char **argv) { int ret; FILE *fp; struct stream *s; time_t now; int type; int subtype; size_t len; int source_as; int dest_as; int ifindex; int family; struct in_addr sip; struct in_addr dip; u_int16_t viewno, seq_num; struct prefix_ipv4 p; s = stream_new (10000); if (argc != 2) { fprintf (stderr, "Usage: %s FILENAME\n", argv[0]); exit (1); } fp = fopen (argv[1], "r"); if (!fp) { perror ("fopen"); exit (1); } while (1) { stream_reset (s); ret = fread (s->data, 12, 1, fp); if (!ret || feof (fp)) { printf ("END OF FILE\n"); break; } if (ferror (fp)) { printf ("ERROR OF FREAD\n"); break; } /* Extract header. */ now = stream_getl (s); type = stream_getw (s); subtype = stream_getw (s); len = stream_getl (s); printf ("TIME: %s", ctime (&now)); /* printf ("TYPE: %d/%d\n", type, subtype); */ if (type == MSG_PROTOCOL_BGP4MP) printf ("TYPE: BGP4MP"); else if (type == MSG_PROTOCOL_BGP4MP_ET) printf ("TYPE: BGP4MP_ET"); else if (type == MSG_TABLE_DUMP) printf ("TYPE: MSG_TABLE_DUMP"); else printf ("TYPE: Unknown %d", type); if (type == MSG_TABLE_DUMP) switch (subtype) { case AFI_IP: printf ("/AFI_IP\n"); break; case AFI_IP6: printf ("/AFI_IP6\n"); break; default: printf ("/UNKNOWN %d", subtype); break; } else { switch (subtype) { case BGP4MP_STATE_CHANGE: printf ("/CHANGE\n"); break; case BGP4MP_MESSAGE: printf ("/MESSAGE\n"); break; case BGP4MP_ENTRY: printf ("/ENTRY\n"); break; case BGP4MP_SNAPSHOT: printf ("/SNAPSHOT\n"); break; default: printf ("/UNKNOWN %d", subtype); break; } } printf ("len: %zd\n", len); ret = fread (s->data + 12, len, 1, fp); if (feof (fp)) { printf ("ENDOF FILE 2\n"); break; } if (ferror (fp)) { printf ("ERROR OF FREAD 2\n"); break; } /* printf ("now read %d\n", len); */ if (type == MSG_TABLE_DUMP) { u_char status; time_t originated; struct in_addr peer; u_int16_t attrlen; viewno = stream_getw (s); seq_num = stream_getw (s); printf ("VIEW: %d\n", viewno); printf ("SEQUENCE: %d\n", seq_num); /* start */ while (s->getp < len - 16) { p.prefix.s_addr = stream_get_ipv4 (s); p.prefixlen = stream_getc (s); printf ("PREFIX: %s/%d\n", inet_ntoa (p.prefix), p.prefixlen); status = stream_getc (s); originated = stream_getl (s); peer.s_addr = stream_get_ipv4 (s); source_as = stream_getw(s); printf ("FROM: %s AS%d\n", inet_ntoa (peer), source_as); printf ("ORIGINATED: %s", ctime (&originated)); attrlen = stream_getw (s); printf ("ATTRLEN: %d\n", attrlen); attr_parse (s, attrlen); printf ("STATUS: 0x%x\n", status); } } else { source_as = stream_getw (s); dest_as = stream_getw (s); printf ("source_as: %d\n", source_as); printf ("dest_as: %d\n", dest_as); ifindex = stream_getw (s); family = stream_getw (s); printf ("ifindex: %d\n", ifindex); printf ("family: %d\n", family); sip.s_addr = stream_get_ipv4 (s); dip.s_addr = stream_get_ipv4 (s); printf ("saddr: %s\n", inet_ntoa (sip)); printf ("daddr: %s\n", inet_ntoa (dip)); printf ("\n"); } } fclose (fp); return 0; }