int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { if (size < sizeof(struct ofp_header)) { return 0; } static bool isInit = false; if (!isInit) { vlog_set_verbosity("off"); isInit = true; } struct ofpbuf b; ofpbuf_use_const(&b, data, size); for (;;) { /* Check if ofpbuf contains ofp header. */ struct ofp_header *oh = ofpbuf_at(&b, 0, sizeof *oh); if (!oh) { break; } /* Check if length is geq than lower bound. */ size_t length = ntohs(oh->length); if (length < sizeof *oh) { break; } /* Check if ofpbuf contains payload. */ size_t tail_len = length - sizeof *oh; void *tail = ofpbuf_at(&b, sizeof *oh, tail_len); if (!tail) { break; } ofp_print(stdout, ofpbuf_pull(&b, length), length, NULL, NULL, 2); } ofpbuf_uninit(&b); return 0; }
void ofputil_append_queue_get_config_reply(const struct ofputil_queue_config *qc, struct ovs_list *replies) { enum ofp_version ofp_version = ofpmp_version(replies); struct ofpbuf *reply = ofpbuf_from_list(ovs_list_back(replies)); size_t start_ofs = reply->size; size_t len_ofs; ovs_be16 *len; if (ofp_version < OFP14_VERSION) { if (ofp_version < OFP12_VERSION) { struct ofp10_packet_queue *opq10; opq10 = ofpbuf_put_zeros(reply, sizeof *opq10); opq10->queue_id = htonl(qc->queue); len_ofs = (char *) &opq10->len - (char *) reply->data; } else { struct ofp12_packet_queue *opq12; opq12 = ofpbuf_put_zeros(reply, sizeof *opq12); opq12->port = ofputil_port_to_ofp11(qc->port); opq12->queue_id = htonl(qc->queue); len_ofs = (char *) &opq12->len - (char *) reply->data; } put_ofp10_queue_rate(reply, OFPQT10_MIN_RATE, qc->min_rate); put_ofp10_queue_rate(reply, OFPQT11_MAX_RATE, qc->max_rate); } else { struct ofp14_queue_desc *oqd = ofpbuf_put_zeros(reply, sizeof *oqd); oqd->port_no = ofputil_port_to_ofp11(qc->port); oqd->queue_id = htonl(qc->queue); len_ofs = (char *) &oqd->len - (char *) reply->data; put_ofp14_queue_rate(reply, OFPQDPT14_MIN_RATE, qc->min_rate); put_ofp14_queue_rate(reply, OFPQDPT14_MAX_RATE, qc->max_rate); } len = ofpbuf_at(reply, len_ofs, sizeof *len); *len = htons(reply->size - start_ofs); if (ofp_version >= OFP14_VERSION) { ofpmp_postappend(replies, start_ofs); } }
static const struct nl_policy policy[] = { [RTA_DST] = { .type = NL_A_U32, .optional = true }, [RTA_OIF] = { .type = NL_A_U32, .optional = false }, [RTA_GATEWAY] = { .type = NL_A_U32, .optional = true }, }; static const struct nl_policy policy6[] = { [RTA_DST] = { .type = NL_A_IPV6, .optional = true }, [RTA_OIF] = { .type = NL_A_U32, .optional = true }, [RTA_GATEWAY] = { .type = NL_A_IPV6, .optional = true }, }; struct nlattr *attrs[ARRAY_SIZE(policy)]; const struct rtmsg *rtm; rtm = ofpbuf_at(buf, NLMSG_HDRLEN, sizeof *rtm); if (rtm->rtm_family == AF_INET) { parsed = nl_policy_parse(buf, NLMSG_HDRLEN + sizeof(struct rtmsg), policy, attrs, ARRAY_SIZE(policy)); ipv4 = true; } else if (rtm->rtm_family == AF_INET6) { parsed = nl_policy_parse(buf, NLMSG_HDRLEN + sizeof(struct rtmsg), policy6, attrs, ARRAY_SIZE(policy6)); } else { VLOG_DBG_RL(&rl, "received non AF_INET rtnetlink route message"); return 0; } if (parsed) { const struct nlmsghdr *nlmsg;
/* Returns 1 if 'packet' is an IP fragment, 0 otherwise. */ int flow_extract(struct ofpbuf *packet, uint32_t in_port, struct flow *flow) { struct ofpbuf b = *packet; struct eth_header *eth; int retval = 0; memset(flow, 0, sizeof *flow); flow->dl_vlan = htons(OFPVID_NONE); flow->in_port = htonl(in_port); packet->l2 = b.data; packet->l3 = NULL; packet->l4 = NULL; packet->l7 = NULL; eth = pull_eth(&b); if (eth) { if (ntohs(eth->eth_type) >= 0x600) { /* This is an Ethernet II frame */ flow->dl_type = eth->eth_type; } else { /* This is an 802.2 frame */ struct llc_header *llc = ofpbuf_at(&b, 0, sizeof *llc); struct snap_header *snap = ofpbuf_at(&b, sizeof *llc, sizeof *snap); if (llc == NULL) { return 0; } if (snap && llc->llc_dsap == LLC_DSAP_SNAP && llc->llc_ssap == LLC_SSAP_SNAP && llc->llc_cntl == LLC_CNTL_SNAP && !memcmp(snap->snap_org, SNAP_ORG_ETHERNET, sizeof snap->snap_org)) { flow->dl_type = snap->snap_type; ofpbuf_pull(&b, LLC_SNAP_HEADER_LEN); } else { flow->dl_type = htons(0x05ff); ofpbuf_pull(&b, sizeof(struct llc_header)); } } /* Check for a VLAN tag */ if (flow->dl_type == htons(ETH_TYPE_VLAN)) { struct vlan_header *vh = pull_vlan(&b); if (vh) { flow->dl_type = vh->vlan_next_type; flow->dl_vlan = vh->vlan_tci & htons(VLAN_VID_MASK); flow->dl_vlan_pcp = (uint8_t)((ntohs(vh->vlan_tci) >> VLAN_PCP_SHIFT) & VLAN_PCP_BITMASK); } } memcpy(flow->dl_src, eth->eth_src, ETH_ADDR_LEN); memcpy(flow->dl_dst, eth->eth_dst, ETH_ADDR_LEN); packet->l3 = b.data; if (flow->dl_type == htons(ETH_TYPE_IP)) { const struct ip_header *nh = pull_ip(&b); if (nh) { flow->nw_tos = nh->ip_tos & 0xfc; flow->nw_proto = nh->ip_proto; flow->nw_src = nh->ip_src; flow->nw_dst = nh->ip_dst; packet->l4 = b.data; if (!IP_IS_FRAGMENT(nh->ip_frag_off)) { if (flow->nw_proto == IP_TYPE_TCP) { const struct tcp_header *tcp = pull_tcp(&b); if (tcp) { flow->tp_src = tcp->tcp_src; flow->tp_dst = tcp->tcp_dst; packet->l7 = b.data; } else { /* Avoid tricking other code into thinking that * this packet has an L4 header. */ flow->nw_proto = 0; } } else if (flow->nw_proto == IP_TYPE_UDP) { const struct udp_header *udp = pull_udp(&b); if (udp) { flow->tp_src = udp->udp_src; flow->tp_dst = udp->udp_dst; packet->l7 = b.data; } else { /* Avoid tricking other code into thinking that * this packet has an L4 header. */ flow->nw_proto = 0; } } else if (flow->nw_proto == IP_TYPE_ICMP) { const struct icmp_header *icmp = pull_icmp(&b); if (icmp) { flow->tp_src = htons(icmp->icmp_type); flow->tp_dst = htons(icmp->icmp_code); packet->l7 = b.data; } else { /* Avoid tricking other code into thinking that * this packet has an L4 header. */ flow->nw_proto = 0; } } } else { retval = 1; } } } else if (flow->dl_type == htons(ETH_TYPE_ARP)) { struct arp_eth_header *arp = pull_arp(&b); if (arp) { if (arp->ar_pro == htons(ARP_PRO_IP) && arp->ar_pln == IP_ADDR_LEN) { flow->nw_src = arp->ar_spa; flow->nw_dst = arp->ar_tpa; } flow->nw_proto = ntohs(arp->ar_op) & 0xff; } } } return retval; }
int main(int argc OVS_UNUSED, char *argv[]) { uint64_t buf_stub[4096 / 64]; struct nl_sock *sock; struct ofpbuf buf; int error; set_program_name(argv[0]); vlog_set_levels(NULL, VLF_ANY_FACILITY, VLL_DBG); error = nl_sock_create(NETLINK_ROUTE, &sock); if (error) { ovs_fatal(error, "could not create rtnetlink socket"); } error = nl_sock_join_mcgroup(sock, RTNLGRP_LINK); if (error) { ovs_fatal(error, "could not join RTNLGRP_LINK multicast group"); } ofpbuf_use_stub(&buf, buf_stub, sizeof buf_stub); for (;;) { error = nl_sock_recv(sock, &buf, false); if (error == EAGAIN) { /* Nothing to do. */ } else if (error == ENOBUFS) { ovs_error(0, "network monitor socket overflowed"); } else if (error) { ovs_fatal(error, "error on network monitor socket"); } else { struct iff_flag { unsigned int flag; const char *name; }; static const struct iff_flag flags[] = { { IFF_UP, "UP", }, { IFF_BROADCAST, "BROADCAST", }, #ifndef _WIN32 { IFF_DEBUG, "DEBUG", }, #endif { IFF_LOOPBACK, "LOOPBACK", }, #ifndef _WIN32 { IFF_POINTOPOINT, "POINTOPOINT", }, { IFF_NOTRAILERS, "NOTRAILERS", }, #endif { IFF_RUNNING, "RUNNING", }, #ifndef _WIN32 { IFF_NOARP, "NOARP", }, #endif { IFF_PROMISC, "PROMISC", }, #ifndef _WIN32 { IFF_ALLMULTI, "ALLMULTI", }, { IFF_MASTER, "MASTER", }, { IFF_SLAVE, "SLAVE", }, #endif { IFF_MULTICAST, "MULTICAST", }, #ifndef _WIN32 { IFF_PORTSEL, "PORTSEL", }, { IFF_AUTOMEDIA, "AUTOMEDIA", }, { IFF_DYNAMIC, "DYNAMIC", }, #endif }; struct nlattr *attrs[ARRAY_SIZE(rtnlgrp_link_policy)]; struct nlmsghdr *nlh; struct ifinfomsg *iim; int i; nlh = ofpbuf_at(&buf, 0, NLMSG_HDRLEN); iim = ofpbuf_at(&buf, NLMSG_HDRLEN, sizeof *iim); if (!iim) { ovs_error(0, "received bad rtnl message (no ifinfomsg)"); continue; } if (!nl_policy_parse(&buf, NLMSG_HDRLEN + sizeof(struct ifinfomsg), rtnlgrp_link_policy, attrs, ARRAY_SIZE(rtnlgrp_link_policy))) { ovs_error(0, "received bad rtnl message (policy)"); continue; } printf("netdev %s changed (%s):\n", nl_attr_get_string(attrs[IFLA_IFNAME]), (nlh->nlmsg_type == RTM_NEWLINK ? "RTM_NEWLINK" #ifndef _WIN32 : nlh->nlmsg_type == RTM_DELLINK ? "RTM_DELLINK" #endif : nlh->nlmsg_type == RTM_GETLINK ? "RTM_GETLINK" #ifndef _WIN32 : nlh->nlmsg_type == RTM_SETLINK ? "RTM_SETLINK" #endif : "other")); printf("\tflags:"); for (i = 0; i < ARRAY_SIZE(flags); i++) { if (iim->ifi_flags & flags[i].flag) { printf(" %s", flags[i].name); } } printf("\n"); if (attrs[IFLA_MASTER]) { uint32_t idx = nl_attr_get_u32(attrs[IFLA_MASTER]); char ifname[IFNAMSIZ]; #ifndef _WIN32 if (!if_indextoname(idx, ifname)) { strcpy(ifname, "unknown"); } #endif printf("\tmaster=%"PRIu32" (%s)\n", idx, ifname); } } nl_sock_wait(sock, POLLIN); poll_block(); } }