static int mcp_ppp_all_config_syn_parse_update(struct stream *data_s) { int type; int len; struct stream* tmp_s; tmp_s = stream_new(10240); while(STREAM_READABLE(data_s) >= 4) { type = stream_getw(data_s); len = stream_getw(data_s); //zlog_debug("<%s,%d> type:%d len:%d", __FUNCTION__, __LINE__, type, len); if(len == 0) continue; switch(type) { case MCP_PPPD_CONFIG_SYN_REMOT_USERINFO: stream_put(tmp_s, data_s->data + stream_get_getp(data_s), len); mcp_recv_pppd_remote_userinfo_ack(tmp_s); stream_forward_getp(data_s, len); stream_reset(tmp_s); break; case MCP_PPPD_CONFIG_SYN_MULTILINK_INFO: stream_put(tmp_s, data_s->data + stream_get_getp(data_s), len); mcp_recv_pppd_multilink_info_ack(tmp_s); stream_forward_getp(data_s, len); stream_reset(tmp_s); break; case MCP_PPPD_CONFIG_SYN_INTERFACE_INFO: stream_put(tmp_s, data_s->data + stream_get_getp(data_s), len); mcp_recv_pppd_interface_info_ack(tmp_s, 1); stream_forward_getp(data_s, len); stream_reset(tmp_s); break; default: zlog_err("mcp<%s:%d> wrong type:%u",__FUNCTION__,__LINE__,type); goto error; } } stream_free(tmp_s); return 0; error: stream_free(tmp_s); return -1; }
static void ospf_packet_db_desc_dump(struct stream *s, uint16_t length) { struct ospf_db_desc *dd; char dd_flags[8]; uint32_t gp; gp = stream_get_getp(s); dd = (struct ospf_db_desc *)stream_pnt(s); zlog_debug("Database Description"); zlog_debug(" Interface MTU %d", ntohs(dd->mtu)); zlog_debug(" Options %d (%s)", dd->options, ospf_options_dump(dd->options)); zlog_debug(" Flags %d (%s)", dd->flags, ospf_dd_flags_dump(dd->flags, dd_flags, sizeof dd_flags)); zlog_debug(" Sequence Number 0x%08lx", (unsigned long)ntohl(dd->dd_seqnum)); length -= OSPF_HEADER_SIZE + OSPF_DB_DESC_MIN_SIZE; stream_forward_getp(s, OSPF_DB_DESC_MIN_SIZE); ospf_lsa_header_list_dump(s, length); stream_set_getp(s, gp); }
static void ospf_lsa_header_list_dump(struct stream *s, uint16_t length) { struct lsa_header *lsa; zlog_debug(" # LSA Headers %d", length / OSPF_LSA_HEADER_SIZE); /* LSA Headers. */ while (length > 0) { lsa = (struct lsa_header *)stream_pnt(s); ospf_lsa_header_dump(lsa); stream_forward_getp(s, OSPF_LSA_HEADER_SIZE); length -= OSPF_LSA_HEADER_SIZE; } }
void ospf_packet_dump(struct stream *s) { struct ospf_header *ospfh; unsigned long gp; /* Preserve pointer. */ gp = stream_get_getp(s); /* OSPF Header dump. */ ospfh = (struct ospf_header *)stream_pnt(s); /* Until detail flag is set, return. */ if (!(term_debug_ospf_packet[ospfh->type - 1] & OSPF_DEBUG_DETAIL)) return; /* Show OSPF header detail. */ ospf_header_dump(ospfh); stream_forward_getp(s, OSPF_HEADER_SIZE); switch (ospfh->type) { case OSPF_MSG_HELLO: ospf_packet_hello_dump(s, ntohs(ospfh->length)); break; case OSPF_MSG_DB_DESC: ospf_packet_db_desc_dump(s, ntohs(ospfh->length)); break; case OSPF_MSG_LS_REQ: ospf_packet_ls_req_dump(s, ntohs(ospfh->length)); break; case OSPF_MSG_LS_UPD: ospf_packet_ls_upd_dump(s, ntohs(ospfh->length)); break; case OSPF_MSG_LS_ACK: ospf_packet_ls_ack_dump(s, ntohs(ospfh->length)); break; default: break; } stream_set_getp(s, gp); }
static void print_stream (struct stream *s) { size_t getp = stream_get_getp (s); printf ("endp: %zu, readable: %zu, writeable: %zu\n", stream_get_endp (s), STREAM_READABLE (s), STREAM_WRITEABLE (s)); while (STREAM_READABLE (s)) { printf ("0x%x ", *stream_pnt (s)); stream_forward_getp (s, 1); } printf ("\n"); /* put getp back to where it was */ stream_set_getp (s, getp); }
static void ospf_packet_ls_upd_dump(struct stream *s, uint16_t length) { uint32_t sp; struct lsa_header *lsa; int lsa_len; uint32_t count; length -= OSPF_HEADER_SIZE; sp = stream_get_getp(s); count = stream_getl(s); length -= 4; zlog_debug("Link State Update"); zlog_debug(" # LSAs %d", count); while (length > 0 && count > 0) { if (length < OSPF_HEADER_SIZE || length % 4 != 0) { zlog_debug(" Remaining %d bytes; Incorrect length.", length); break; } lsa = (struct lsa_header *)stream_pnt(s); lsa_len = ntohs(lsa->length); ospf_lsa_header_dump(lsa); switch (lsa->type) { case OSPF_ROUTER_LSA: ospf_router_lsa_dump(s, length); break; case OSPF_NETWORK_LSA: ospf_network_lsa_dump(s, length); break; case OSPF_SUMMARY_LSA: case OSPF_ASBR_SUMMARY_LSA: ospf_summary_lsa_dump(s, length); break; case OSPF_AS_EXTERNAL_LSA: ospf_as_external_lsa_dump(s, length); break; case OSPF_AS_NSSA_LSA: ospf_as_external_lsa_dump(s, length); break; case OSPF_OPAQUE_LINK_LSA: case OSPF_OPAQUE_AREA_LSA: case OSPF_OPAQUE_AS_LSA: ospf_opaque_lsa_dump(s, length); break; default: break; } stream_forward_getp(s, lsa_len); length -= lsa_len; count--; } stream_set_getp(s, sp); }
int ppp_tcp_write (struct thread *thread) { struct ppp_mcp_sock *peer; struct stream *stream; int num; int write_errno; int val, writenum; /* Yes first of all get peer pointer. */ peer = THREAD_ARG (thread); peer->t_write = NULL; if (peer->fd < 0) { PPPD_DEBUG_TCP("write: peer's fd is negative value %d", peer->fd); return -1; } if(peer->connect_status != CLIENT_CONNECT_SERVER_OK) return -1; while (1) { stream = stream_fifo_head(peer->obuf); if (stream == NULL) return 0; val = fcntl (peer->fd, F_GETFL, 0); fcntl (peer->fd, F_SETFL, val | O_NONBLOCK); /* Number of bytes to be sent. */ writenum = stream_get_endp (stream) - stream_get_getp (stream); /* Call write() system call. */ num = write (peer->fd, STREAM_PNT (stream), writenum); write_errno = errno; fcntl (peer->fd, F_SETFL, val); if (num < 0) { if (write_errno == EWOULDBLOCK || write_errno == EAGAIN || write_errno == EINTR) break; PPPD_DEBUG_TCP("erro,write packet to peer:%s, fd:%u", peer->hostname, peer->fd); ppp_connect_mcp_error_deal(peer); return 0; } /*发送了数据之后,推迟保活定时器*/ if(num > 0) pppd_postpone_keepalive_timer(peer); if (num != writenum) { stream_forward_getp(stream, num); break; } else stream_free(stream_fifo_pop (peer->obuf)); break; } if(stream_fifo_head (peer->obuf)) MCP_WRITE_ON (peer->t_write, ppp_tcp_write, peer, peer->fd); return 0; }
/* peek into option, stores ASN to *as4 if the AS4 capability was found. * Returns 0 if no as4 found, as4cap value otherwise. */ as_t peek_for_as4_capability (struct peer *peer, u_char length) { struct stream *s = BGP_INPUT (peer); size_t orig_getp = stream_get_getp (s); size_t end = orig_getp + length; as_t as4 = 0; /* The full capability parser will better flag the error.. */ if (STREAM_READABLE(s) < length) return 0; if (BGP_DEBUG (as4, AS4)) zlog_info ("%s [AS4] rcv OPEN w/ OPTION parameter len: %u," " peeking for as4", peer->host, length); /* the error cases we DONT handle, we ONLY try to read as4 out of * correctly formatted options. */ while (stream_get_getp(s) < end) { u_char opt_type; u_char opt_length; /* Check the length. */ if (stream_get_getp (s) + 2 > end) goto end; /* Fetch option type and length. */ opt_type = stream_getc (s); opt_length = stream_getc (s); /* Option length check. */ if (stream_get_getp (s) + opt_length > end) goto end; if (opt_type == BGP_OPEN_OPT_CAP) { unsigned long capd_start = stream_get_getp (s); unsigned long capd_end = capd_start + opt_length; assert (capd_end <= end); while (stream_get_getp (s) < capd_end) { struct capability_header hdr; if (stream_get_getp (s) + 2 > capd_end) goto end; hdr.code = stream_getc (s); hdr.length = stream_getc (s); if ((stream_get_getp(s) + hdr.length) > capd_end) goto end; if (hdr.code == CAPABILITY_CODE_AS4) { if (BGP_DEBUG (as4, AS4)) zlog_info ("[AS4] found AS4 capability, about to parse"); as4 = bgp_capability_as4 (peer, &hdr); goto end; } stream_forward_getp (s, hdr.length); } } } end: stream_set_getp (s, orig_getp); return as4; }
/* Zebra server IPv4 prefix delete function. */ static int zread_ipv4_delete (struct zserv *client, u_short length) { int i; struct stream *s; struct zapi_ipv4 api; struct in_addr nexthop, *nexthop_p; 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; nexthop_p = NULL; /* Type, flags, message. */ api.type = stream_getc (s); api.flags = stream_getc (s); api.message = stream_getc (s); api.safi = stream_getw (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_getp (s, ifname_len); break; case ZEBRA_NEXTHOP_IPV4: nexthop.s_addr = stream_get_ipv4 (s); nexthop_p = &nexthop; break; case ZEBRA_NEXTHOP_IPV4_IFINDEX: nexthop.s_addr = stream_get_ipv4 (s); ifindex = stream_getl (s); break; case ZEBRA_NEXTHOP_IPV6: stream_forward_getp (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_p, ifindex, client->rtm_table, api.safi); return 0; }
/* * Parse the ZEBRA_IPV4_ROUTE_ADD sent from client. Update rib and * add kernel route. */ static int 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; safi_t safi; /* Get input stream. */ s = client->ibuf; /* Allocate new rib. */ rib = XCALLOC (MTYPE_RIB, sizeof (struct rib)); /* Type, flags, message. */ rib->type = stream_getc (s); rib->flags = stream_getc (s); message = stream_getc (s); safi = stream_getw (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_getp (s, ifname_len); break; case ZEBRA_NEXTHOP_IPV4: nexthop.s_addr = stream_get_ipv4 (s); nexthop_ipv4_add (rib, &nexthop, NULL); break; case ZEBRA_NEXTHOP_IPV4_IFINDEX: nexthop.s_addr = stream_get_ipv4 (s); ifindex = stream_getl (s); nexthop_ipv4_ifindex_add (rib, &nexthop, NULL, ifindex); break; case ZEBRA_NEXTHOP_IPV6: stream_forward_getp (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); /* Table */ rib->table=zebrad.rtm_table_default; rib_add_ipv4_multipath (&p, rib, safi); return 0; }