# Copyright 2017 syzkaller project authors. All rights reserved. # Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. include include syz_emit_ethernet(len len[packet], packet ptr[in, eth_packet], frags ptr[in, vnet_fragmentation, opt]) vnet_fragmentation { # If set and we have remaining data after fragmentation, it is written in an additional fragment. # If not set, data remaining after fragmentation is discarded. full int32[0:1] count int32[1:4] frags array[int32[0:4096], 4] } hop_limits = 0, 1, 255 resource tcp_seq_num[int32]: 0x41424344 tcp_resources { seq tcp_seq_num ack tcp_seq_num } # These pseudo syscalls read a packet from /dev/net/tun and extract tcp sequence and acknowledgement numbers from it. # They also adds the inc arguments to the returned values, this way sequence numbers get incremented. syz_extract_tcp_res(res ptr[out, tcp_resources], seq_inc int32, ack_inc int32) syz_extract_tcp_res$synack(res ptr[out, tcp_resources], seq_inc const[1], ack_inc const[0]) ################################################################################ ################################### Ethernet ################################### ################################################################################ # https://en.wikipedia.org/wiki/Ethernet_frame#Structure # https://en.wikipedia.org/wiki/IEEE_802.1Q include include type mac_addr_t[LAST] { a0 array[const[0xaa, int8], 5] a1 LAST } [packed] mac_addr_link_local { a0 const[0x1, int8] a1 const[0x80, int8] a2 const[0xc2, int8] a3 const[0x0, int8] a4 const[0x0, int8] a5 flags[mac_addr_link_local_values, int8] } [packed] mac_addr_link_local_values = 0x0, 0x1, 0x2, 0x3, 0xe # This corresponds to the last digit in DEV_MAC/DEV_IPV4/DEV_IPV6 in executor/common_linux.h type netdev_addr_id int8[10:68] mac_addr [ empty array[const[0x0, int8], 6] # These correspond to LOCAL_MAC/REMOTE_MAC/DEV_MAC in executor/common_linux.h local mac_addr_t[const[0xaa, int8]] remote mac_addr_t[const[0xbb, int8]] dev mac_addr_t[netdev_addr_id] broadcast array[const[0xff, int8], 6] multicast array[const[0xbb, int8], 6] link_local mac_addr_link_local random array[int8, 6] ] type mac_addr_mask array[flags[mac_addr_mask_vals, int8], 6] mac_addr_mask_vals = 0, 0xff vlan_tag_ad { tpid const[ETH_P_8021AD, int16be] pcp int16:3 dei int16:1 vid int16:12[0:4] } [packed] vlan_tag_q { tpid const[ETH_P_8021Q, int16be] pcp int16:3 dei int16:1 vid int16:12[0:4] } [packed] vlan_tag { tag_ad optional[vlan_tag_ad] tag_q vlan_tag_q } [packed] eth_packet { dst_mac mac_addr src_mac mac_addr vtag optional[vlan_tag] payload eth_payload } [packed] eth_payload { eth2 eth2_packet } [packed] ################################################################################ ################################## Ethernet 2 ################################## ################################################################################ # https://en.wikipedia.org/wiki/Ethernet_frame#Ethernet_II ether_types = ETH_P_LOOP, ETH_P_PUP, ETH_P_PUPAT, ETH_P_TSN, ETH_P_IP, ETH_P_X25, ETH_P_ARP, ETH_P_IEEEPUP, ETH_P_IEEEPUPAT, ETH_P_BATMAN, ETH_P_DEC, ETH_P_DNA_DL, ETH_P_DNA_RC, ETH_P_DNA_RT, ETH_P_LAT, ETH_P_DIAG, ETH_P_CUST, ETH_P_SCA, ETH_P_TEB, ETH_P_RARP, ETH_P_ATALK, ETH_P_AARP, ETH_P_8021Q, ETH_P_ERSPAN, ETH_P_ERSPAN2, ETH_P_IPV6, ETH_P_PAUSE, ETH_P_SLOW, ETH_P_WCCP, ETH_P_MPLS_UC, ETH_P_MPLS_MC, ETH_P_ATMMPOA, ETH_P_PPP_DISC, ETH_P_PPP_SES, ETH_P_LINK_CTL, ETH_P_ATMFATE, ETH_P_PAE, ETH_P_AOE, ETH_P_8021AD, ETH_P_802_EX1, ETH_P_TIPC, ETH_P_MACSEC, ETH_P_8021AH, ETH_P_MVRP, ETH_P_1588, ETH_P_NCSI, ETH_P_PRP, ETH_P_FCOE, ETH_P_TDLS, ETH_P_FIP, ETH_P_80221, ETH_P_HSR, ETH_P_LOOPBACK, ETH_P_QINQ1, ETH_P_QINQ2, ETH_P_QINQ3, ETH_P_EDSA, ETH_P_AF_IUCV, ETH_P_802_3_MIN, ETH_P_802_3, ETH_P_AX25, ETH_P_ALL, ETH_P_802_2, ETH_P_SNAP, ETH_P_DDCMP, ETH_P_WAN_PPP, ETH_P_PPP_MP, ETH_P_LOCALTALK, ETH_P_CAN, ETH_P_CANFD, ETH_P_PPPTALK, ETH_P_TR_802_2, ETH_P_MOBITEX, ETH_P_CONTROL, ETH_P_IRDA, ETH_P_ECONET, ETH_P_HDLC, ETH_P_ARCNET, ETH_P_DSA, ETH_P_TRAILER, ETH_P_PHONET, ETH_P_IEEE802154, ETH_P_CAIF, ETH_P_XDSA, ETH_P_MAP eth2_packet [ generic eth2_packet_generic arp eth2_packet_t[ETH_P_ARP, arp_packet] ipv4 eth2_packet_t[ETH_P_IP, ipv4_packet] ipv6 eth2_packet_t[ETH_P_IPV6, ipv6_packet] llc eth2_packet_t[ETH_P_802_2, llc_packet] llc_tr eth2_packet_t[ETH_P_TR_802_2, llc_packet] x25 eth2_packet_t[ETH_P_X25, x25_packet] mpls_uc eth2_packet_t[ETH_P_MPLS_UC, mpls_packet] mpls_mc eth2_packet_t[ETH_P_MPLS_MC, mpls_packet] can eth2_packet_t[ETH_P_CAN, can_frame] canfd eth2_packet_t[ETH_P_CANFD, canfd_frame] ] [varlen] eth2_packet_generic { etype flags[ether_types, int16be] payload array[int8] } [packed] type eth2_packet_t[TYPE, PAYLOAD] { etype const[TYPE, int16be] payload PAYLOAD } [packed] ################################################################################ ###################################### ARP ##################################### ################################################################################ # https://en.wikipedia.org/wiki/Address_Resolution_Protocol#Packet_structure include arp_htypes = ARPHRD_NETROM, ARPHRD_ETHER, ARPHRD_EETHER, ARPHRD_AX25, ARPHRD_PRONET, ARPHRD_CHAOS, ARPHRD_IEEE802, ARPHRD_ARCNET, ARPHRD_APPLETLK, ARPHRD_DLCI, ARPHRD_ATM, ARPHRD_METRICOM, ARPHRD_IEEE1394, ARPHRD_EUI64, ARPHRD_INFINIBAND, ARPHRD_SLIP, ARPHRD_CSLIP, ARPHRD_SLIP6, ARPHRD_CSLIP6, ARPHRD_RSRVD, ARPHRD_ADAPT, ARPHRD_ROSE, ARPHRD_X25, ARPHRD_HWX25, ARPHRD_CAN, ARPHRD_PPP, ARPHRD_CISCO, ARPHRD_HDLC, ARPHRD_LAPB, ARPHRD_DDCMP, ARPHRD_RAWHDLC, ARPHRD_TUNNEL, ARPHRD_TUNNEL6, ARPHRD_FRAD, ARPHRD_SKIP, ARPHRD_LOOPBACK, ARPHRD_LOCALTLK, ARPHRD_FDDI, ARPHRD_BIF, ARPHRD_SIT, ARPHRD_IPDDP, ARPHRD_IPGRE, ARPHRD_PIMREG, ARPHRD_HIPPI, ARPHRD_ASH, ARPHRD_ECONET, ARPHRD_IRDA, ARPHRD_FCPP, ARPHRD_FCAL, ARPHRD_FCPL, ARPHRD_FCFABRIC, ARPHRD_IEEE802_TR, ARPHRD_IEEE80211, ARPHRD_IEEE80211_PRISM, ARPHRD_IEEE80211_RADIOTAP, ARPHRD_IEEE802154, ARPHRD_IEEE802154_MONITOR, ARPHRD_PHONET, ARPHRD_PHONET_PIPE, ARPHRD_CAIF, ARPHRD_IP6GRE, ARPHRD_NETLINK, ARPHRD_6LOWPAN, ARPHRD_VOID, ARPHRD_NONE arp_ops = ARPOP_REQUEST, ARPOP_REPLY, ARPOP_RREQUEST, ARPOP_RREPLY, ARPOP_InREQUEST, ARPOP_InREPLY, ARPOP_NAK arp_packet [ generic arp_packet_t[flags[arp_htypes, int16be], flags[ether_types, int16be], array[int8, 0:16]] ether_ipv4 arp_packet_t[const[ARPHRD_ETHER, int16be], const[ETH_P_IP, int16be], ipv4_addr] ether_ipv6 arp_packet_t[const[ARPHRD_ETHER, int16be], const[ETH_P_IPV6, int16be], ipv6_addr] ] [varlen] type arp_packet_t[HTYPE, PTYPE, ADDR] { htype HTYPE ptype PTYPE hlen const[6, int8] plen len[spa, int8] op flags[arp_ops, int16be] sha mac_addr spa ADDR tha mac_addr tpa ADDR } [packed] ################################################################################ ################################## 802.2 (LLC) ################################# ################################################################################ # https://en.wikipedia.org/wiki/IEEE_802.2 # https://en.wikipedia.org/wiki/Subnetwork_Access_Protocol include # Adding '1' as a SAP value since the lower bit in SAP has a special meaning. sap_values = 1, LLC_SAP_NULL, LLC_SAP_LLC, LLC_SAP_SNA, LLC_SAP_PNM, LLC_SAP_IP, LLC_SAP_BSPAN, LLC_SAP_MMS, LLC_SAP_8208, LLC_SAP_3COM, LLC_SAP_PRO, LLC_SAP_SNAP, LLC_SAP_BANYAN, LLC_SAP_NETBEUI, LLC_SAP_LANMGR, LLC_SAP_IMPL, LLC_SAP_DISC, LLC_SAP_OSI, LLC_SAP_LAR, LLC_SAP_RM, LLC_SAP_GLOBAL llc_generic_packet { dsap flags[sap_values, int8] ssap flags[sap_values, int8] ctrl array[int8, 1:2] payload array[int8] } [packed] sap_snap_values = 1, LLC_SAP_SNAP llc_snap_packet { dsap flags[sap_snap_values, int8] ssap flags[sap_snap_values, int8] control array[int8, 1:2] oui array[int8, 3] protocol_id flags[ether_types, int16be] payload array[int8] } [packed] llc_payload [ llc llc_generic_packet snap llc_snap_packet ] [varlen] llc_packet { # TODO: is there length or not? I don't see it in packet format... # length len[payload, int16be] payload llc_payload } [packed] ################################################################################ ###################################### x25 ##################################### ################################################################################ # Documentation/networking/x25.txt # Documentation/networking/x25-iface.txt # http://www.dafuer.com/kleinehelferlein/x25layer.htm include include x25_iface_types = X25_IFACE_DATA, X25_IFACE_CONNECT, X25_IFACE_DISCONNECT, X25_IFACE_PARAMS x25_frame_types = X25_CALL_REQUEST, X25_CALL_ACCEPTED, X25_CLEAR_REQUEST, X25_CLEAR_CONFIRMATION, X25_DATA, X25_INTERRUPT, X25_INTERRUPT_CONFIRMATION, X25_RR, X25_RNR, X25_REJ, X25_RESET_REQUEST, X25_RESET_CONFIRMATION, X25_REGISTRATION_REQUEST, X25_REGISTRATION_CONFIRMATION, X25_RESTART_REQUEST, X25_RESTART_CONFIRMATION, X25_DIAGNOSTIC, X25_ILLEGAL x25_packet { iface flags[x25_iface_types, int8] wtf int8 frame flags[x25_frame_types, int8] payload array[int8] } [packed] ################################################################################ ##################################### IPv4 ##################################### ################################################################################ # https://tools.ietf.org/html/rfc791#section-3.1 # https://en.wikipedia.org/wiki/IPv4#Header # TODO: https://en.wikipedia.org/wiki/IPsec#Authentication_Header # TODO: https://en.wikipedia.org/wiki/IPsec#Encapsulating_Security_Payload include include include include include type ipv4_addr_t[LAST] { a0 const[0xac, int8] a1 const[0x14, int8] a2 const[0x14, int8] a3 LAST } [packed] ipv4_addr_initdev { a0 const[0xac, int8] a1 const[0x1e, int8] a2 int8[0:1] a3 proc[1, 1, int8] } ipv4_addr [ # Few public random addresses 100.1.1.[0-2] rand_addr int32be[0x64010100:0x64010102] # 0.0.0.0 empty const[0x0, int32be] # These correspond to LOCAL_IPV4/REMOTE_IPV4/DEV_IPV4 in executor/common_linux.h local ipv4_addr_t[const[170, int8]] remote ipv4_addr_t[const[187, int8]] dev ipv4_addr_t[netdev_addr_id] initdev ipv4_addr_initdev # 127.0.0.1 loopback const[0x7f000001, int32be] # 224.0.0.1 multicast1 const[0xe0000001, int32be] # 224.0.0.2 multicast2 const[0xe0000002, int32be] # 255.255.255.255 broadcast const[0xffffffff, int32be] # 10.1.1.[0-2] can be used for custom things within the image private int32be[0xa010100:0xa010102] ] [size[4]] type ipv4_addr_mask flags[ipv4_addr_mask_vals, int32be] ipv4_addr_mask_vals = 0, 0xff000000, 0xffffff00, 0xffffffff, 0xff # http://www.iana.org/assignments/ip-parameters/ip-parameters.xhtml#ip-parameters-1 ipv4_option [ generic ipv4_option_generic end ipv4_option_end noop ipv4_option_noop lsrr ipv4_option_route[IPOPT_LSRR] ssrr ipv4_option_route[IPOPT_SSRR] rr ipv4_option_route[IPOPT_RR] timestamp ipv4_option_timestamp[IPOPT_TS_TSONLY, int32be] timestamp_addr ipv4_option_timestamp[IPOPT_TS_TSANDADDR, ipv4_option_timestamp_timestamp] timestamp_prespec ipv4_option_timestamp[IPOPT_TS_PRESPEC, ipv4_option_timestamp_timestamp] cipso ipv4_option_cipso ra ipv4_option_ra # IPOPT_SEC and IPOPT_SID are not supported by Linux kernel ] [varlen] ipv4_option_types = IPOPT_SEC, IPOPT_LSRR, IPOPT_TIMESTAMP, IPOPT_CIPSO, IPOPT_RR, IPOPT_SID, IPOPT_SSRR, IPOPT_RA ipv4_option_generic { type flags[ipv4_option_types, int8] length len[parent, int8] data array[int8, 0:16] } [packed] # https://tools.ietf.org/html/rfc791#section-3.1 ipv4_option_end { type const[IPOPT_END, int8] } [packed] # https://tools.ietf.org/html/rfc791#section-3.1 ipv4_option_noop { type const[IPOPT_NOOP, int8] } [packed] # https://tools.ietf.org/html/rfc791#section-3.1 type ipv4_option_route[OPT] { type const[OPT, int8] length len[parent, int8] pointer int8[4:255] data array[ipv4_addr] } [packed] # https://tools.ietf.org/html/rfc791#section-3.1 # http://www.networksorcery.com/enp/protocol/ip/option004.htm type ipv4_option_timestamp[TYP, TSTAMP] { type const[IPOPT_TIMESTAMP, int8] length len[parent, int8] pointer int8[5:255] flg const[TYP, int8:4] oflw int8:4 timestamps array[TSTAMP] } [packed] ipv4_option_timestamp_timestamp { addr ipv4_addr timestamp int32be } [packed] ipv4_option_cipso_tag_types = CIPSO_V4_TAG_INVALID, CIPSO_V4_TAG_RBITMAP, CIPSO_V4_TAG_ENUM, CIPSO_V4_TAG_RANGE, CIPSO_V4_TAG_PBITMAP, CIPSO_V4_TAG_FREEFORM # TODO: describe particular tag types ipv4_option_cipso_tag { type flags[ipv4_option_cipso_tag_types, int8] length len[parent, int8] data array[int8, 0:16] } [packed] # https://www.ietf.org/archive/id/draft-ietf-cipso-ipsecurity-01.txt ipv4_option_cipso { type const[IPOPT_CIPSO, int8] length len[parent, int8] doi flags[cipso_doi, int32be] tags array[ipv4_option_cipso_tag] } [packed] cipso_doi = CIPSO_V4_DOI_UNKNOWN, SMACK_CIPSO_DOI_DEFAULT, SMACK_CIPSO_DOI_INVALID, 1, 2, 3 # https://tools.ietf.org/html/rfc2113 ipv4_option_ra { type const[IPOPT_RA, int8] length len[parent, int8] value bool16 } [packed] ipv4_options { options array[ipv4_option] } [packed, align[4]] ipv4_types = IPPROTO_IP, IPPROTO_ICMP, IPPROTO_IGMP, IPPROTO_IPIP, IPPROTO_TCP, IPPROTO_EGP, IPPROTO_PUP, IPPROTO_UDP, IPPROTO_IDP, IPPROTO_TP, IPPROTO_DCCP, IPPROTO_IPV6, IPPROTO_RSVP, IPPROTO_GRE, IPPROTO_ESP, IPPROTO_AH, IPPROTO_MTP, IPPROTO_BEETPH, IPPROTO_ENCAP, IPPROTO_PIM, IPPROTO_COMP, IPPROTO_SCTP, IPPROTO_UDPLITE, IPPROTO_MPLS, IPPROTO_RAW, IPPROTO_L2TP type ipv4_header[PROTO] { ihl bytesize4[parent, int8:4] version const[4, int8:4] ecn int8:2 dscp int8:6 # TODO: if s/ipv4_packet_t/ipv4_packet/, (1) this crashes, (2) only at runtime with: # panic: len field "total_len" references non existent field "ipv4_packet", pos="len"/"total_len" total_len len[ipv4_packet_t, int16be] id int16be[100:104] # TODO: frag_off is actually 13 bits, 3 bits are flags frag_off int16be[0:0] ttl int8 protocol PROTO csum csum[parent, inet, int16be] src_ip ipv4_addr dst_ip ipv4_addr options ipv4_options } [packed] type ipv4_packet_t[PROTO, PAYLOAD] { header ipv4_header[PROTO] payload PAYLOAD } [packed] ipv4_packet [ generic ipv4_packet_t[flags[ipv4_types, int8], array[int8]] tcp ipv4_packet_t[const[IPPROTO_TCP, int8], tcp_packet] udp ipv4_packet_t[const[IPPROTO_UDP, int8], udp_packet] icmp ipv4_packet_t[const[IPPROTO_ICMP, int8], icmp_packet] dccp ipv4_packet_t[const[IPPROTO_DCCP, int8], dccp_packet] igmp ipv4_packet_t[const[IPPROTO_IGMP, int8], igmp_packet] gre ipv4_packet_t[const[IPPROTO_GRE, int8], gre_packet] # TODO: what proto do we need for tipc (there is no IPPROTO_TIPC)? tipc ipv4_packet_t[const[IPPROTO_TCP, int8], tipc_packet] ] [varlen] ################################################################################ ##################################### IPv6 ##################################### ################################################################################ # https://tools.ietf.org/html/rfc2460#section-3 # https://en.wikipedia.org/wiki/IPv6_packet#Fixed_header include include include include include ipv6_types = IPPROTO_IP, IPPROTO_ICMP, IPPROTO_IGMP, IPPROTO_IPIP, IPPROTO_TCP, IPPROTO_EGP, IPPROTO_PUP, IPPROTO_UDP, IPPROTO_IDP, IPPROTO_TP, IPPROTO_DCCP, IPPROTO_IPV6, IPPROTO_RSVP, IPPROTO_GRE, IPPROTO_ESP, IPPROTO_AH, IPPROTO_MTP, IPPROTO_BEETPH, IPPROTO_ENCAP, IPPROTO_PIM, IPPROTO_COMP, IPPROTO_SCTP, IPPROTO_UDPLITE, IPPROTO_MPLS, IPPROTO_RAW, IPPROTO_HOPOPTS, IPPROTO_ROUTING, IPPROTO_FRAGMENT, IPPROTO_ICMPV6, IPPROTO_NONE, IPPROTO_DSTOPTS, IPPROTO_MH, NEXTHDR_HOP, NEXTHDR_ROUTING, NEXTHDR_FRAGMENT, NEXTHDR_GRE, NEXTHDR_ESP, NEXTHDR_AUTH, NEXTHDR_ICMP, NEXTHDR_NONE, NEXTHDR_DEST, NEXTHDR_MOBILITY, IPPROTO_L2TP ipv6_addr_empty { a0 array[const[0x0, int8], 16] } [packed, align[4]] type ipv6_addr_t[LAST] { a0 const[0xfe, int8] a1 const[0x80, int8] a2 array[const[0x0, int8], 13] a3 LAST } [packed, align[4]] ipv6_addr_initdev { a0 const[0xfe, int8] a1 const[0x88, int8] a2 array[const[0x0, int8], 12] a3 int8[0:1] a4 proc[1, 1, int8] } [packed, align[4]] ipv6_addr_loopback { a0 const[0, int64be] a1 const[1, int64be] } [packed, align[4]] ipv6_addr_ipv4 { a0 array[const[0x0, int8], 10] a1 array[const[0xff, int8], 2] a3 ipv4_addr } [packed, align[4]] ipv6_addr_multicast1 { a0 const[0xff, int8] a1 const[0x1, int8] a2 array[const[0x0, int8], 13] a3 const[0x1, int8] } [packed, align[4]] ipv6_addr_multicast2 { a0 const[0xff, int8] a1 const[0x2, int8] a2 array[const[0x0, int8], 13] a3 const[0x1, int8] } [packed, align[4]] type ipv6_addr_private[BYTE2] { a0 const[0xfc, int8] a1 const[BYTE2, int8] a2 array[const[0x0, int8], 13] a3 int8[0:1] } [packed, align[4]] ipv6_addr_random = `20010000000000000000000000000000`, `20010000000000000000000000000001`, `20010000000000000000000000000002` ipv6_addr [ # Few public random addresses rand_addr stringnoz[ipv6_addr_random] empty ipv6_addr_empty # These correspond to LOCAL_IPV6/REMOTE_IPV6/DEV_IPV6 in executor/common_linux.h local ipv6_addr_t[const[0xaa, int8]] remote ipv6_addr_t[const[0xbb, int8]] dev ipv6_addr_t[netdev_addr_id] initdev ipv6_addr_initdev # Some special addresses: loopback ipv6_addr_loopback ipv4 ipv6_addr_ipv4 mcast1 ipv6_addr_multicast1 mcast2 ipv6_addr_multicast2 # Several custom private ranges with 2 addresses each: fc0X::/127. # Can be used for custom things within the tested image. private0 ipv6_addr_private[0] private1 ipv6_addr_private[1] private2 ipv6_addr_private[2] ] [size[16]] type ipv6_addr_mask array[flags[ipv4_addr_mask_vals, int32be], 4] # TODO: Describe more types of headers # NEXTHDR_HOP, NEXTHDR_TCP, NEXTHDR_UDP, NEXTHDR_IPV6, NEXTHDR_FRAGMENT, NEXTHDR_GRE, NEXTHDR_ESP, NEXTHDR_AUTH, NEXTHDR_ICMP, NEXTHDR_NONE, NEXTHDR_DEST, NEXTHDR_SCTP, NEXTHDR_MOBILITY # https://tools.ietf.org/html/rfc2402 # https://tools.ietf.org/html/rfc2406 # https://tools.ietf.org/html/rfc3775 # https://tools.ietf.org/html/rfc2460#section-4 # The length field in each of the extension headers specifies the # length of the header in 8-octet units not including the first 8 octets. ipv6_ext_header [ hopopts ipv6_hopopts_ext_header routing ipv6_rt_hdr srh ipv6_sr_hdr fragment ipv6_fragment_ext_header dstopts ipv6_dstopts_ext_header ] [varlen] ipv6_hopopts_ext_header { next_header flags[ipv6_types, int8] length bytesize8[options, int8] pad array[const[0, int8], 6] options array[ipv6_tlv_option] } [packed, align[8]] ipv6_routing_types = IPV6_SRCRT_STRICT, IPV6_SRCRT_TYPE_0, IPV6_SRCRT_TYPE_2 ipv6_rt_hdr { next_header flags[ipv6_types, int8] length bytesize8[data, int8] routing_type flags[ipv6_routing_types, int8] segments_left int8 reserved const[0, int32] data array[ipv6_addr] } [packed, align[8]] ipv6_sr_hdr { nexthdr flags[ipv6_types, int8] hdrlen bytesize8[segments, int8] type const[IPV6_SRCRT_TYPE_4, int8] segments_left len[segments, int8] first_segment int8 flags flags[ipv6_sr_flags, int8] tag int16 segments array[ipv6_addr] # TODO: this may be followed by sr6_tlv_hmac if SR6_FLAG1_HMAC is set. # However, if we place it here, we won't be able to calculate hdrlen (len of 2 fields), # and if we move segments and sr6_tlv_hmac into a separate struct, # we won't be able to calculate segments_left because it will need to # refer to a field of a subobject. What may help is allowing specifying # subfields as len/bytesize targets, e.g. "len[payload.segments]", or "bytesize[parent_struct.foo]". } [packed, align[8]] ipv6_sr_flags = SR6_FLAG1_PROTECTED, SR6_FLAG1_OAM, SR6_FLAG1_ALERT, SR6_FLAG1_HMAC ipv6_fragment_ext_header { next_header flags[ipv6_types, int8] reserved1 const[0, int8] fragment_off_hi int8 m_flag int8:1 reserved2 const[0, int8:2] fragment_off_lo int8:5 identification int32[100:104] } [packed, align[8]] ipv6_dstopts_ext_header { next_header flags[ipv6_types, int8] length bytesize8[options, int8] pad array[const[0, int8], 6] options array[ipv6_tlv_option] } [packed, align[8]] ipv6_tlv_option [ generic ipv6_tlv_generic pad1 ipv6_tlv_pad1 padn ipv6_tlv_padn ra ipv6_tlv_ra jumbo ipv6_tlv_jumbo calipso ipv6_tlv_calipso hao ipv6_tlv_hao enc_lim ipv6_tlv_enc_lim ] [varlen] ipv6_tlv_generic { type int8 length len[data, int8] data array[int8] } [packed] ipv6_tlv_pad1 { type const[IPV6_TLV_PAD1, int8] len const[1, int8] pad const[0, int8] } [packed] ipv6_tlv_padn { type const[IPV6_TLV_PADN, int8] len len[pad, int8] pad array[const[0, int8]] } [packed] ipv6_tlv_ra { type const[IPV6_TLV_ROUTERALERT, int8] len const[2, int8] ra int16be } [packed] ipv6_tlv_jumbo { type const[IPV6_TLV_JUMBO, int8] len const[4, int8] pkt_len int32be } [packed] # https://tools.ietf.org/html/rfc5570#section-5.1 ipv6_tlv_calipso { type const[IPV6_TLV_CALIPSO, int8] len bytesize[payload, int8] payload ipv6_tlv_calipso_payload } [packed] # TODO: checksum is generally incorrect. ipv6_tlv_calipso_payload { domain flags[calipso_doi, int32be] compartment_length bytesize4[compartment_bitmap, int8] sensitivity_level int8 checksum int16 compartment_bitmap array[int64] } [packed] calipso_doi = 0, 1, 2, 3 ipv6_tlv_hao { type const[IPV6_TLV_HAO, int8] len bytesize[addr, int8] addr ipv6_addr } [packed] ipv6_tlv_enc_lim { type const[IPV6_TLV_TNL_ENCAP_LIMIT, int8] len const[1, int8] encap_limit int8 } [packed] ipv6_packet [ generic ipv6_packet_t[flags[ipv6_types, int8], array[int8]] tcp ipv6_packet_t[const[IPPROTO_TCP, int8], tcp_packet] udp ipv6_packet_t[const[IPPROTO_UDP, int8], udp_packet] icmpv6 ipv6_packet_t[const[IPPROTO_ICMPV6, int8], icmpv6_packet] dccp_packet ipv6_packet_t[const[IPPROTO_DCCP, int8], dccp_packet] gre_packet ipv6_packet_t[const[IPPROTO_GRE, int8], gre_packet] # TODO: what proto do we need for tipc (there is no IPPROTO_TIPC)? tipc_packet ipv6_packet_t[const[IPPROTO_TCP, int8], tipc_packet] ] [varlen] type ipv6_packet_t[PROTO, PAYLOAD] { priority int8:4 version const[6, int8:4] # TODO: flow_label is actually 20 bits, 4 bits are part of priority flow_label array[int8, 3] length len[payload, int16be] next_header PROTO hop_limit flags[hop_limits, int8] src_ip ipv6_addr dst_ip ipv6_addr payload ipv6_packet_payload[PAYLOAD] } [packed] type ipv6_packet_payload[PAYLOAD] { ext_headers array[ipv6_ext_header] payload PAYLOAD } [packed] ################################################################################ ###################################### TCP ##################################### ################################################################################ # https://tools.ietf.org/html/rfc793#section-3.1 # https://en.wikipedia.org/wiki/Transmission_Control_Protocol#TCP_segment_structure # http://www.iana.org/assignments/tcp-parameters/tcp-parameters.xhtml include include tcp_option [ generic tcp_generic_option nop tcp_nop_option eol tcp_eol_option mss tcp_mss_option window tcp_window_option sack_perm tcp_sack_perm_option sack tcp_sack_option timestamp tcp_timestamp_option md5sig tcp_md5sig_option fastopen tcp_fastopen_option exp_fastopen tcp_exp_fastopen_option exp_smc tcp_exp_smc_option mptcp tcp_mptcp_option ] [varlen] tcp_option_types = TCPOPT_NOP, TCPOPT_EOL, TCPOPT_MSS, TCPOPT_WINDOW, TCPOPT_SACK_PERM, TCPOPT_SACK, TCPOPT_TIMESTAMP, TCPOPT_MD5SIG, TCPOPT_FASTOPEN, TCPOPT_EXP tcp_generic_option { type flags[tcp_option_types, int8] length len[parent, int8] data array[int8, 0:16] } [packed] # https://tools.ietf.org/html/rfc793#section-3.1 tcp_nop_option { type const[TCPOPT_NOP, int8] } [packed] # https://tools.ietf.org/html/rfc793#section-3.1 tcp_eol_option { type const[TCPOPT_EOL, int8] } [packed] # https://tools.ietf.org/html/rfc793#section-3.1 tcp_mss_option { type const[TCPOPT_MSS, int8] length len[parent, int8] seg_size int16 } [packed] # https://tools.ietf.org/html/rfc7323#section-2 tcp_window_option { type const[TCPOPT_WINDOW, int8] length len[parent, int8] shift int8 } [packed] # https://tools.ietf.org/html/rfc2018#section-2 tcp_sack_perm_option { type const[TCPOPT_SACK_PERM, int8] length len[parent, int8] } [packed] # https://tools.ietf.org/html/rfc2018#section-3 tcp_sack_option { type const[TCPOPT_SACK, int8] length len[parent, int8] data array[int32be] } [packed] # https://tools.ietf.org/html/rfc7323#section-3 tcp_timestamp_option { type const[TCPOPT_TIMESTAMP, int8] length len[parent, int8] tsval int32be tsecr int32be } [packed] # https://tools.ietf.org/html/rfc2385#section-3.0 tcp_md5sig_option { type const[TCPOPT_MD5SIG, int8] length len[parent, int8] md5 array[int8, 16] } [packed] # https://tools.ietf.org/html/rfc7413#section-4.1.1 tcp_fastopen_option { type const[TCPOPT_FASTOPEN, int8] length len[parent, int8] data array[int8, 0:16] } [packed] tcp_exp_fastopen_option { type const[TCPOPT_EXP, int8] length len[parent, int8] subtype const[TCPOPT_FASTOPEN_MAGIC, int16be] data array[int8, 0:16] } [packed] tcp_exp_smc_option { type const[TCPOPT_EXP, int8] length len[parent, int8] subtype const[TCPOPT_SMC_MAGIC, int32be] } [packed] tcp_options { options array[tcp_option] } [packed, align[4]] tcp_flags = TCPHDR_FIN, TCPHDR_SYN, TCPHDR_RST, TCPHDR_PSH, TCPHDR_ACK, TCPHDR_URG, TCPHDR_ECE, TCPHDR_CWR, TCPHDR_SYN_ECN tcp_header { src_port sock_port dst_port sock_port seq_num tcp_seq_num ack_num tcp_seq_num ns int8:1 reserved const[0, int8:3] data_off bytesize4[parent, int8:4] flags flags[tcp_flags, int8] window_size int16be csum csum[tcp_packet, pseudo, IPPROTO_TCP, int16be] urg_ptr int16be options tcp_options } [packed] tcp_packet { header tcp_header payload tcp_payload } [packed] tcp_payload { payload array[int8] } [packed] ################################################################################ ###################################### UDP ##################################### ################################################################################ # https://tools.ietf.org/html/rfc768 # https://en.wikipedia.org/wiki/User_Datagram_Protocol#Packet_structure include udp_packet { src_port sock_port dst_port sock_port length len[parent, int16be] csum csum[parent, pseudo, IPPROTO_UDP, int16be] payload udp_payload } [packed] udp_payload [ opaque array[int8] gue gue_packet wg wg_packet ] [varlen] gue_packet { hdr guehdr opaque array[int8] } [packed] guehdr { hlen bytesize4[parent, int8:5] control int8:1 version int8:2 proto_ctype int8 flags flags[guehdr_flags, int16] priv optional[flags[guehdr_prov_flags, int32]] } [packed] guehdr_flags = GUE_FLAG_PRIV guehdr_prov_flags = GUE_PFLAG_REMCSUM ################################################################################ ###################################### GRE ##################################### ################################################################################ # https://en.wikipedia.org/wiki/Generic_Routing_Encapsulation include gre_packet { pptp gre_packet_pptp # TODO: add more packets # TODO: the payload should be ipv4_packet/ipv6_packet, but this creates recursion # ipv4 -> gre -> ipv4 -> ... cisco_ipv4 gre_packet_cisco[ETH_P_IP, array[int8]] cisco_ipv6 gre_packet_cisco[ETH_P_IPV6, array[int8]] erspan1 gre_packet_erspan[ETH_P_ERSPAN, erspan_md1_msg] erspan2 gre_packet_erspan[ETH_P_ERSPAN2, erspan_md2_msg] teb gre_packet_erspan[ETH_P_TEB, array[int8]] } [packed] type gre_packet_cisco[PROTO, PAYLOAD] { C int16:1 R const[0, int16:1] K int16:1 S int16:1 reserved const[0, int16:9] version const[0, int16:3] protocol const[PROTO, int16be] # checksum, key, sequence number add array[int16be, 0:3] payload PAYLOAD } [packed] gre_packet_pptp { C const[0, int16:1] R const[0, int16:1] K const[1, int16:1] S int16:1 reserved const[0, int16:4] A int16:1 flags const[0, int16:4] version const[1, int16:3] protocol const[0x880b, int16be] payload_len bytesize[payload, int16be] key_call_id pptp_call_id # sequence/ack number add array[int16be, 0:2] payload ppp_packet } [packed] type ppp_packet array[int8] type gre_packet_erspan[PROTO, PAYLOAD] { H const[8, int16] protocol const[PROTO, int16be] seq int32be[0:4] payload PAYLOAD } [packed] ################################################################################ ##################################### ERSPAN ################################### ################################################################################ include include type erspan_base_hdr[VER] { vlan_upper int8:4 ver const[VER, int8:4] vlan int8:8 session_id_upper int8:2 t int8:1 en int8:2 cos int8:3 session_id int8:8 } [packed] erspan_md1 { index int32be } [packed] erspan_md1_msg { base erspan_base_hdr[1] version const[1, int32] payload erspan_md1 } erspan_md2 { timestamp int32be sgt int16be hwid_upper int8:2 ft int8:5 p int8:1 o int8:1 gra int8:2 dir int8:1 hwid int8:1 } [packed] erspan_md2_msg { base erspan_base_hdr[2] version const[2, int32] payload erspan_md2 } ################################################################################ ###################################### ICMP #################################### ################################################################################ # https://en.wikipedia.org/wiki/Internet_Control_Message_Protocol#ICMP_datagram_structure # https://tools.ietf.org/html/rfc792 # https://tools.ietf.org/html/rfc4884#section-4.1 # http://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml include icmp_ipv4_header { ihl bytesize4[parent, int8:4] version const[4, int8:4] ecn int8:2 dscp int8:6 total_len int16be id icmp_id frag_off int16be ttl int8 protocol flags[ipv4_types, int8] csum int16be src_ip ipv4_addr dst_ip ipv4_addr options ipv4_options } [packed] icmp_echo_reply_packet { type const[ICMP_ECHOREPLY, int8] code const[0, int8] csum csum[parent, inet, int16be] id icmp_id seq_num int16be data array[int8] } [packed] type icmp_id int16be[100:104] icmp_dest_unreach_codes = ICMP_NET_UNREACH, ICMP_HOST_UNREACH, ICMP_PROT_UNREACH, ICMP_PORT_UNREACH, ICMP_FRAG_NEEDED, ICMP_SR_FAILED, ICMP_NET_UNKNOWN, ICMP_HOST_UNKNOWN, ICMP_HOST_ISOLATED, ICMP_NET_ANO, ICMP_HOST_ANO, ICMP_NET_UNR_TOS, ICMP_HOST_UNR_TOS, ICMP_PKT_FILTERED, ICMP_PREC_VIOLATION, ICMP_PREC_CUTOFF icmp_dest_unreach_packet { type const[ICMP_DEST_UNREACH, int8] code flags[icmp_dest_unreach_codes, int8] csum csum[parent, inet, int16be] unused const[0, int8] length int8 mtu int16be iph icmp_ipv4_header data array[int8, 0:8] } [packed] icmp_source_quench_packet { type const[ICMP_SOURCE_QUENCH, int8] code const[0, int8] csum csum[parent, inet, int16be] unused const[0, int32] iph icmp_ipv4_header data array[int8, 0:8] } [packed] icmp_redirect_codes = ICMP_REDIR_NET, ICMP_REDIR_HOST, ICMP_REDIR_NETTOS, ICMP_REDIR_HOSTTOS icmp_redirect_packet { type const[ICMP_REDIRECT, int8] code flags[icmp_redirect_codes, int8] csum csum[parent, inet, int16be] ip ipv4_addr iph icmp_ipv4_header data array[int8, 0:8] } [packed] icmp_echo_packet { type const[ICMP_ECHO, int8] code const[0, int8] csum csum[parent, inet, int16be] id int16be seq_num int16be data array[int8] } [packed] icmp_time_exceeded_codes = ICMP_EXC_TTL, ICMP_EXC_FRAGTIME icmp_time_exceeded_packet { type const[ICMP_TIME_EXCEEDED, int8] code flags[icmp_time_exceeded_codes, int8] csum csum[parent, inet, int16be] unused1 const[0, int8] length int8 unused2 const[0, int16] iph icmp_ipv4_header data array[int8, 0:8] } [packed] icmp_parameter_prob_packet { type const[ICMP_PARAMETERPROB, int8] code const[0, int8] csum csum[parent, inet, int16be] pointer int8 length int8 unused const[0, int16] iph icmp_ipv4_header data array[int8, 0:8] } [packed] icmp_timestamp_packet { type const[ICMP_TIMESTAMP, int8] code const[0, int8] csum csum[parent, inet, int16be] id int16be seq_num int16be orig_ts int32be recv_ts int32be trans_ts int32be } [packed] icmp_timestamp_reply_packet { type const[ICMP_TIMESTAMPREPLY, int8] code const[0, int8] csum csum[parent, inet, int16be] id int16be seq_num int16be orig_ts int32be recv_ts int32be trans_ts int32be } [packed] icmp_info_request_packet { type const[ICMP_INFO_REQUEST, int8] code const[0, int8] csum csum[parent, inet, int16be] id int16be seq_num int16be } [packed] icmp_info_reply_packet { type const[ICMP_INFO_REPLY, int8] code const[0, int8] csum csum[parent, inet, int16be] id int16be seq_num int16be } [packed] icmp_address_request_packet { type const[ICMP_ADDRESS, int8] code const[0, int8] csum csum[parent, inet, int16be] mask int32be } [packed] icmp_address_reply_packet { type const[ICMP_ADDRESSREPLY, int8] code const[0, int8] csum csum[parent, inet, int16be] mask int32be } [packed] icmp_types = ICMP_ECHOREPLY, ICMP_DEST_UNREACH, ICMP_SOURCE_QUENCH, ICMP_REDIRECT, ICMP_ECHO, ICMP_TIME_EXCEEDED, ICMP_PARAMETERPROB, ICMP_TIMESTAMP, ICMP_TIMESTAMPREPLY, ICMP_INFO_REQUEST, ICMP_INFO_REPLY, ICMP_ADDRESS, ICMP_ADDRESSREPLY icmp_packet [ echo_reply icmp_echo_reply_packet dest_unreach icmp_dest_unreach_packet source_quench icmp_source_quench_packet redirect icmp_redirect_packet echo icmp_echo_packet time_exceeded icmp_time_exceeded_packet parameter_prob icmp_parameter_prob_packet timestamp icmp_timestamp_packet timestamp_reply icmp_timestamp_reply_packet info_request icmp_info_request_packet info_reply icmp_info_reply_packet address_request icmp_address_request_packet address_reply icmp_address_reply_packet ] [varlen] ################################################################################ ##################################### ICMPv6 ################################### ################################################################################ # https://tools.ietf.org/html/rfc4443 # http://www.iana.org/assignments/icmpv6-parameters/icmpv6-parameters.xhtml include icmpv6_ipv6_packet { priority int8:4 version const[6, int8:4] flow_label array[int8, 3] length int16be next_header flags[ipv6_types, int8] hop_limit flags[hop_limits, int8] src_ip ipv6_addr dst_ip ipv6_addr ext_headers array[ipv6_ext_header] data array[int8] } [packed] icmpv6_dest_unreach_codes = ICMPV6_NOROUTE, ICMPV6_ADM_PROHIBITED, ICMPV6_NOT_NEIGHBOUR, ICMPV6_ADDR_UNREACH, ICMPV6_PORT_UNREACH, ICMPV6_POLICY_FAIL, ICMPV6_REJECT_ROUTE icmpv6_dest_unreach_packet { type const[ICMPV6_DEST_UNREACH, int8] code flags[icmpv6_dest_unreach_codes, int8] csum csum[parent, pseudo, IPPROTO_ICMPV6, int16be] length int8 unused array[const[0, int8], 3] packet icmpv6_ipv6_packet } [packed] icmpv6_pkt_toobig_packet { type const[ICMPV6_PKT_TOOBIG, int8] code const[0, int8] csum csum[parent, pseudo, IPPROTO_ICMPV6, int16be] mtu int32be packet icmpv6_ipv6_packet } [packed] icmpv6_time_exceed_codes = ICMPV6_EXC_HOPLIMIT, ICMPV6_EXC_FRAGTIME icmpv6_time_exceed_packet { type const[ICMPV6_TIME_EXCEED, int8] code flags[icmpv6_time_exceed_codes, int8] csum csum[parent, pseudo, IPPROTO_ICMPV6, int16be] length int8 unused array[const[0, int8], 3] packet icmpv6_ipv6_packet } [packed] icmpv6_param_prob_codes = ICMPV6_HDR_FIELD, ICMPV6_UNK_NEXTHDR, ICMPV6_UNK_OPTION icmpv6_param_prob_packet { type const[ICMPV6_PARAMPROB, int8] code flags[icmpv6_param_prob_codes, int8] csum csum[parent, pseudo, IPPROTO_ICMPV6, int16be] pointer int32be packet icmpv6_ipv6_packet } [packed] icmpv6_echo_request_packet { type const[ICMPV6_ECHO_REQUEST, int8] code const[0, int8] csum csum[parent, pseudo, IPPROTO_ICMPV6, int16be] id int16be seq_num int16be data array[int8] } [packed] icmpv6_echo_reply_packet { type const[ICMPV6_ECHO_REPLY, int8] code const[0, int8] csum csum[parent, pseudo, IPPROTO_ICMPV6, int16be] id int16be seq_num int16be data array[int8] } [packed] icmpv6_mld_types = ICMPV6_MGM_QUERY, ICMPV6_MGM_REPORT, ICMPV6_MGM_REDUCTION # https://tools.ietf.org/html/rfc2710#section-3 icmpv6_mld_packet { type flags[icmpv6_mld_types, int8] code const[0, int8] csum csum[parent, pseudo, IPPROTO_ICMPV6, int16be] mrd int16be unused int16 addr ipv6_addr } [packed] # https://tools.ietf.org/html/rfc3810#section-5.1 icmpv6_mldv2_listener_query_packet { type const[ICMPV6_MGM_QUERY, int8] code const[0, int8] csum csum[parent, pseudo, IPPROTO_ICMPV6, int16be] mrd int16be unused int16 mca ipv6_addr qrv int8:3 suppress int8:1 resv2 int8:4 qqic int8 nsrcs len[srcs, int16be] srcs array[ipv6_addr] } [packed] icmpv6_mldv2_grec { type int8 auxwords len[aux, int8] nsrcs len[srcs, int16be] mca ipv6_addr srcs array[ipv6_addr] aux array[int32] } [packed] # https://tools.ietf.org/html/rfc3810#section-5.2 icmpv6_mldv2_listener_report_packet { type const[ICMPV6_MLD2_REPORT, int8] code const[0, int8] csum csum[parent, pseudo, IPPROTO_ICMPV6, int16be] unused int16 ngrec len[grec, int16be] grec array[icmpv6_mldv2_grec] } [packed] icmpv6_ni_types = ICMPV6_NI_QUERY, ICMPV6_NI_REPLY # https://tools.ietf.org/html/rfc4620#section-4 icmpv6_ni_packet { type flags[icmpv6_ni_types, int8] code const[0, int8] csum csum[parent, pseudo, IPPROTO_ICMPV6, int16be] qtype int16be flags int16be nonce int64be data array[int8] } [packed] icmpv6_ndisc_option_types = ND_OPT_SOURCE_LL_ADDR, ND_OPT_TARGET_LL_ADDR, ND_OPT_PREFIX_INFO, ND_OPT_REDIRECT_HDR, ND_OPT_MTU, ND_OPT_NONCE, ND_OPT_ROUTE_INFO, ND_OPT_RDNSS, ND_OPT_DNSSL, ND_OPT_6CO # https://tools.ietf.org/html/rfc4861#section-4.6 icmpv6_ndisc_option { option_type flags[icmpv6_ndisc_option_types, int8] length bytesize8[parent, int8] # TODO: define the option formats data array[int8] } [packed] # https://tools.ietf.org/html/rfc4861#section-4.1 icmpv6_ndisc_router_solicit_packet { type const[NDISC_ROUTER_SOLICITATION, int8] code const[0, int8] csum csum[parent, pseudo, IPPROTO_ICMPV6, int16be] unused array[const[0, int8], 4] options array[icmpv6_ndisc_option] } [packed] # https://tools.ietf.org/html/rfc4861#section-4.2 icmpv6_ndisc_router_advert_packet { type const[NDISC_ROUTER_ADVERTISEMENT, int8] code const[0, int8] csum csum[parent, pseudo, IPPROTO_ICMPV6, int16be] cur_hop_limit flags[hop_limits, int8] # TODO: Implement bitflags for the router advert flags router_flags int8 router_lifetime int16 reachable_time int32 retrans_time int32 options array[icmpv6_ndisc_option] } [packed] # https://tools.ietf.org/html/rfc4861#section-4.3 icmpv6_ndisc_neigh_solicit_packet { type const[NDISC_NEIGHBOUR_SOLICITATION, int8] code const[0, int8] csum csum[parent, pseudo, IPPROTO_ICMPV6, int16be] target_addr ipv6_addr options array[icmpv6_ndisc_option] } [packed] # https://tools.ietf.org/html/rfc4861#section-4.4 icmpv6_ndisc_neigh_advert_packet { type const[NDISC_NEIGHBOUR_ADVERTISEMENT, int8] code const[0, int8] csum csum[parent, pseudo, IPPROTO_ICMPV6, int16be] # TODO: Implement bitflags for the neighbor advert flags neighbor_flags int8 unused array[const[0, int8], 3] target_addr ipv6_addr options array[icmpv6_ndisc_option] } [packed] # https://tools.ietf.org/html/rfc4861#section-4.5 icmpv6_ndisc_redir_packet { type const[NDISC_REDIRECT, int8] code const[0, int8] csum csum[parent, pseudo, IPPROTO_ICMPV6, int16be] unused array[const[0, int8], 4] target_addr ipv6_addr dst_addr ipv6_addr options array[icmpv6_ndisc_option] } [packed] icmpv6_packet [ dest_unreach icmpv6_dest_unreach_packet pkt_toobig icmpv6_pkt_toobig_packet time_exceed icmpv6_time_exceed_packet param_prob icmpv6_param_prob_packet echo_request icmpv6_echo_request_packet echo_reply icmpv6_echo_reply_packet mld icmpv6_mld_packet mlv2_query icmpv6_mldv2_listener_query_packet mlv2_report icmpv6_mldv2_listener_report_packet ni icmpv6_ni_packet ndisc_rs icmpv6_ndisc_router_solicit_packet ndisc_ra icmpv6_ndisc_router_advert_packet ndisc_na icmpv6_ndisc_neigh_advert_packet ndisc_ns icmpv6_ndisc_neigh_solicit_packet ndisc_redir icmpv6_ndisc_redir_packet # TODO: ICMPV6_DHAAD_REQUEST, ICMPV6_DHAAD_REPLY, ICMPV6_MOBILE_PREFIX_SOL, ICMPV6_MOBILE_PREFIX_ADV (with ipv6 ext headers) ] [varlen] ################################################################################ ###################################### DCCP #################################### ################################################################################ # https://tools.ietf.org/html/rfc4340#section-5 include # TODO: describe each type dccp_types = DCCP_PKT_REQUEST, DCCP_PKT_RESPONSE, DCCP_PKT_DATA, DCCP_PKT_ACK, DCCP_PKT_DATAACK, DCCP_PKT_CLOSEREQ, DCCP_PKT_CLOSE, DCCP_PKT_RESET, DCCP_PKT_SYNC, DCCP_PKT_SYNCACK, DCCP_PKT_INVALID dccp_header { src_port sock_port dst_port sock_port offset bytesize4[parent, int8] cscov const[1, int8:4] # TODO: cscov might have other values, affects checksummed data ccval int8:4 csum csum[parent, pseudo, IPPROTO_DCCP, int16be] x const[0, int8:1] type flags[dccp_types, int8:4] reserved1 int8:3 seq_num array[int8, 3] reserved2 int8 ack_num array[int8, 3] # TODO: seq_num and ack_num might have different size depending on x # TODO: options } [packed] dccp_packet { header dccp_header payload array[int8] } [packed] ################################################################################ ###################################### IGMP #################################### ################################################################################ # https://tools.ietf.org/html/rfc2236 # https://tools.ietf.org/html/rfc3376#section-4 include igmp_types = IGMP_HOST_MEMBERSHIP_QUERY, IGMP_HOST_MEMBERSHIP_REPORT, IGMP_DVMRP, IGMP_PIM, IGMP_TRACE, IGMPV2_HOST_MEMBERSHIP_REPORT, IGMP_HOST_LEAVE_MESSAGE, IGMPV3_HOST_MEMBERSHIP_REPORT, IGMP_MTRACE_RESP, IGMP_MTRACE igmp_packet { type flags[igmp_types, int8] mrtime int8 csum csum[parent, inet, int16be] addr ipv4_addr data array[int8] } [packed] # TODO: describe particular IGMP packets # TODO: open IGMP sockets from userspace ################################################################################ ###################################### MPLS #################################### ################################################################################ # https://en.wikipedia.org/wiki/Multiprotocol_Label_Switching mpls_packet { labels array[mpls_label] payload mpls_payload } [packed] mpls_label { label int32be:20 tc const[0, int32be:3] s int32be:1 ttl const[0, int32be:8] } mpls_payload [ generic array[int8] ipv4 ipv4_packet ipv6 ipv6_packet llc llc_packet ] [varlen] ################################################################################ ###################################### TIPC #################################### ################################################################################ # http://tipc.sourceforge.net/protocol.html # http://tipc.sourceforge.net/protocol.html#anchor50 # TODO: describe more TIPC packets, the current description is far from being complete. # But first we need to ensure that syzkaller manages to enable TIPC receiving, # because currently it always crashes kernel earlier. # Also, do we need to nest TIPC packets in UDP for UDP media? include include tipc_packet [ payload_conn tipc_payload_msg[tipc_payload_hdr6[TIPC_CONN_MSG]] payload_mcast tipc_payload_msg[tipc_payload_hdr11[TIPC_MCAST_MSG]] payload_named tipc_payload_msg[tipc_payload_hdr10[TIPC_NAMED_MSG]] payload_direct tipc_payload_msg[tipc_payload_hdr8[TIPC_DIRECT_MSG]] name_distributor tipc_name_distributor_msg ] [varlen] type tipc_payload_msg[HDR] { hdr tipc_payload_hdr[HDR] data array[const[0, int8]] } type tipc_payload_hdr[HDR] { hdr HDR } type tipc_payload_hdr6[TYP] { # w0 message_size bytesize[tipc_payload_msg, int32be:17] y const[0, int32be:1] s int32be:1 d int32be:1 n int32be:1 hsize bytesize4[tipc_payload_hdr, int32be:4] user flags[tipc_importance, int32be:4] ver const[TIPC_VERSION, int32be:3] # w1 broadcast_acknowledge int32be:16 res const[0, int32be:3] lcs flags[tipc_scope, int32be:2] reroute int32be:4 error flags[tipc_error, int32be:4] mtype const[TYP, int32be:3] # w2 link_sequence int32be:16 link_acknowledge int32be:16 # w3 previous_node int32be[0:4] # w4 originating_port int32be[20000:20004] # w5 destination_port int32be[20000:20004] } [size[24]] type tipc_payload_hdr8[TYP] { hdr6 tipc_payload_hdr6[TYP] # w6 originating_node int32be[0:4] # w7 destination_node int32be[0:4] } [size[32]] type tipc_payload_hdr10[TYP] { hdr8 tipc_payload_hdr8[TYP] # w8 name_type int32be[0:4] # w9 name_instance int32be[0:4] } [size[40]] type tipc_payload_hdr11[TYP] { hdr10 tipc_payload_hdr10[TYP] # w10 name_sequence_upper int32be[0:4] } [size[44]] tipc_name_distributor_msg { hdr tipc_name_distributor_hdr data array[tipc_name_publication] } tipc_name_distributor_hdr { # w0 message_size bytesize[tipc_name_distributor_msg, int32be:17] y const[0, int32be:1] s const[0, int32be:1] d const[0, int32be:1] n int32be:1 hsize bytesize4[parent, int32be:4] user const[NAME_DISTRIBUTOR, int32be:4] ver const[TIPC_VERSION, int32be:3] # w1 broadcast_acknowledge int32be:16 res const[0, int32be:13] mtype int32be:3[0:1] # w2 link_sequence int32be:16 link_acknowledge int32be:16 # w3 previous_node int32be[0:4] # w4 originating_port int32be[20000:20004] # w5 destination_port int32be[20000:20004] # w6 originating_node int32be[0:4] # w7 destination_node int32be[0:4] # w8 res1 const[0, int32be] # w9 res2 const[0, int32be:23] m int32be:1 item_size const[7, int32be:8] } tipc_name_publication { type int32be lower_bound int32be upper_bound int32be reference int32be key int32be node int32be scope int32be:4 res int32be:28 } [size[28]] tipc_importance = TIPC_LOW_IMPORTANCE, TIPC_MEDIUM_IMPORTANCE, TIPC_HIGH_IMPORTANCE, TIPC_CRITICAL_IMPORTANCE tipc_error = TIPC_OK, TIPC_ERR_NO_NAME, TIPC_ERR_NO_PORT, TIPC_ERR_NO_NODE, TIPC_ERR_OVERLOAD, TIPC_CONN_SHUTDOWN tipc_scope = TIPC_CFG_SRV, TIPC_ZONE_SCOPE, TIPC_CLUSTER_SCOPE, TIPC_NODE_SCOPE