| # 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 <linux/types.h> |
| include <linux/byteorder/generic.h> |
| |
| 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] |
| } |
| |
| 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 <uapi/linux/if.h> |
| include <uapi/linux/if_ether.h> |
| |
| 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:43] |
| |
| 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] |
| 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_QINQ1, 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 array[vlan_tag_ad, 0:1] |
| tag_q vlan_tag_q |
| } [packed] |
| |
| eth_packet { |
| dst_mac mac_addr |
| src_mac mac_addr |
| vtag array[vlan_tag, 0:1] |
| 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_IPX, 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] |
| ipx eth2_packet_t[ETH_P_IPX, ipx_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 <uapi/linux/if_arp.h> |
| |
| 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_generic_packet { |
| htype flags[arp_htypes, int16be] |
| ptype flags[ether_types, int16be] |
| hlen const[6, int8] |
| plen len[spa, int8] |
| op flags[arp_ops, int16be] |
| sha mac_addr |
| spa array[int8, 0:16] |
| tha mac_addr |
| tpa array[int8, 16] |
| } [packed] |
| |
| arp_ether_ipv4_packet { |
| htype const[ARPHRD_ETHER, int16be] |
| ptype const[ETH_P_IP, int16be] |
| hlen const[6, int8] |
| plen const[4, int8] |
| op flags[arp_ops, int16be] |
| sha mac_addr |
| spa ipv4_addr |
| tha mac_addr |
| tpa ipv4_addr |
| } [packed] |
| |
| arp_ether_ipv6_packet { |
| htype const[ARPHRD_ETHER, int16be] |
| ptype const[ETH_P_IPV6, int16be] |
| hlen const[6, int8] |
| plen const[16, int8] |
| op flags[arp_ops, int16be] |
| sha mac_addr |
| spa ipv6_addr |
| tha mac_addr |
| tpa ipv6_addr |
| } [packed] |
| |
| arp_packet [ |
| generic arp_generic_packet |
| ether_ipv4 arp_ether_ipv4_packet |
| ether_ipv6 arp_ether_ipv6_packet |
| ] [varlen] |
| |
| ################################################################################ |
| ################################## 802.2 (LLC) ################################# |
| ################################################################################ |
| |
| # https://en.wikipedia.org/wiki/IEEE_802.2 |
| # https://en.wikipedia.org/wiki/Subnetwork_Access_Protocol |
| |
| include <uapi/linux/llc.h> |
| |
| # 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_IPX, 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] |
| |
| ################################################################################ |
| ###################################### IPX ##################################### |
| ################################################################################ |
| |
| # http://www.networksorcery.com/enp/protocol/ipx.htm |
| # https://en.wikipedia.org/wiki/Internetwork_Packet_Exchange#IPX_packet_structure |
| |
| include <net/ipx.h> |
| |
| ipx_network [ |
| random int32be |
| current const[0x0, int32be] |
| broadcast const[0xffffffff, int32be] |
| ] |
| |
| ipx_node [ |
| random array[int8, 6] |
| current array[const[0x0, int8], 6] |
| broadcast array[const[0xff, int8], 6] |
| ] |
| |
| ipx_addr { |
| network ipx_network |
| node ipx_node |
| socket int16be |
| } [packed] |
| |
| ipx_packet_types = IPX_TYPE_UNKNOWN, IPX_TYPE_RIP, IPX_TYPE_SAP, IPX_TYPE_SPX, IPX_TYPE_NCP, IPX_TYPE_PPROP |
| |
| ipx_packet { |
| csum const[0xffff, int16be] |
| length len[parent, int16be] |
| control int8 |
| type flags[ipx_packet_types, int8] |
| dst_addr ipx_addr |
| src_addr ipx_addr |
| payload array[int8] |
| } [packed] |
| |
| # TODO: setup ipx on virtual interfaces in executor |
| # TODO: describe particular ipx types |
| # TODO: open ipx sockets from userspace |
| |
| ################################################################################ |
| ###################################### x25 ##################################### |
| ################################################################################ |
| |
| # Documentation/networking/x25.txt |
| # Documentation/networking/x25-iface.txt |
| # http://www.dafuer.com/kleinehelferlein/x25layer.htm |
| |
| include <uapi/linux/if_x25.h> |
| include <net/x25.h> |
| |
| 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 <uapi/linux/in.h> |
| include <uapi/linux/ip.h> |
| include <uapi/linux/l2tp.h> |
| include <net/cipso_ipv4.h> |
| |
| 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 [ |
| # random |
| rand_addr int32be |
| # 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] |
| ] [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_lsrr |
| ssrr ipv4_option_ssrr |
| rr ipv4_option_rr |
| timestamp ipv4_option_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_END, IPOPT_NOOP, 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 |
| ipv4_option_lsrr { |
| type const[IPOPT_LSRR, int8] |
| length len[parent, int8] |
| pointer int8 |
| data array[ipv4_addr] |
| } [packed] |
| |
| # https://tools.ietf.org/html/rfc791#section-3.1 |
| ipv4_option_ssrr { |
| type const[IPOPT_SSRR, int8] |
| length len[parent, int8] |
| pointer int8 |
| data array[ipv4_addr] |
| } [packed] |
| |
| # https://tools.ietf.org/html/rfc791#section-3.1 |
| ipv4_option_rr { |
| type const[IPOPT_RR, int8] |
| length len[parent, int8] |
| pointer int8 |
| data array[ipv4_addr] |
| } [packed] |
| |
| ipv4_option_timestamp_flags = IPOPT_TS_TSONLY, IPOPT_TS_TSANDADDR, IPOPT_TS_PRESPEC |
| |
| ipv4_option_timestamp_timestamp { |
| addr array[ipv4_addr, 0:1] |
| timestamp int32be |
| } [packed] |
| |
| # https://tools.ietf.org/html/rfc791#section-3.1 |
| # http://www.networksorcery.com/enp/protocol/ip/option004.htm |
| ipv4_option_timestamp { |
| type const[IPOPT_TIMESTAMP, int8] |
| length len[parent, int8] |
| pointer int8 |
| flg flags[ipv4_option_timestamp_flags, int8:4] |
| oflw int8:4 |
| timestamps array[ipv4_option_timestamp_timestamp] |
| } [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 int32be |
| tags array[ipv4_option_cipso_tag] |
| } [packed] |
| |
| # https://tools.ietf.org/html/rfc2113 |
| ipv4_option_ra { |
| type const[IPOPT_RA, int8] |
| length len[parent, int8] |
| value int32be |
| } [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 |
| |
| ipv4_header { |
| ihl bytesize4[parent, int8:4] |
| version const[4, int8:4] |
| ecn int8:2 |
| dscp int8:6 |
| total_len len[ipv4_packet, int16be] |
| id int16be[100:104] |
| frag_off int16be |
| # TODO: frag_off is actually 13 bits, 3 bits are flags |
| ttl int8 |
| protocol flags[ipv4_types, int8] |
| csum csum[parent, inet, int16be] |
| src_ip ipv4_addr |
| dst_ip ipv4_addr |
| options ipv4_options |
| } [packed] |
| |
| ipv4_packet { |
| header ipv4_header |
| payload ipv4_payload |
| } [packed] |
| |
| ################################################################################ |
| ##################################### IPv6 ##################################### |
| ################################################################################ |
| |
| # https://tools.ietf.org/html/rfc2460#section-3 |
| # https://en.wikipedia.org/wiki/IPv6_packet#Fixed_header |
| |
| include <uapi/linux/in6.h> |
| include <uapi/linux/ipv6.h> |
| include <uapi/linux/seg6.h> |
| include <uapi/linux/ip6_tunnel.h> |
| include <net/ipv6.h> |
| |
| 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] |
| } |
| |
| type ipv6_addr_t[LAST] { |
| a0 const[0xfe, int8] |
| a1 const[0x80, int8] |
| a2 array[const[0x0, int8], 13] |
| a3 LAST |
| } [packed] |
| |
| 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] |
| } |
| |
| 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] |
| |
| ipv6_addr_multicast1 { |
| a0 const[0xff, int8] |
| a1 const[0x1, int8] |
| a2 array[const[0x0, int8], 13] |
| a3 const[0x1, int8] |
| } [packed] |
| |
| ipv6_addr_multicast2 { |
| a0 const[0xff, int8] |
| a1 const[0x2, int8] |
| a2 array[const[0x0, int8], 13] |
| a3 const[0x1, int8] |
| } [packed] |
| |
| ipv6_addr [ |
| rand_addr array[int8, 16] |
| 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 |
| loopback ipv6_addr_loopback |
| ipv4 ipv6_addr_ipv4 |
| mcast1 ipv6_addr_multicast1 |
| mcast2 ipv6_addr_multicast2 |
| ] [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_hopots_ext_header |
| routing ipv6_rt_hdr |
| srh ipv6_sr_hdr |
| fragment ipv6_fragment_ext_header |
| dstopts ipv6_dstopts_ext_header |
| ] [varlen] |
| |
| ipv6_hopots_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. |
| # TODO: domain should be flags, but it's unclear if we have any domains registered by default. |
| ipv6_tlv_calipso_payload { |
| domain int32be |
| compartment_length bytesize4[compartment_bitmap, int8] |
| sensitivity_level int8 |
| checksum int16 |
| compartment_bitmap array[int64] |
| } [packed] |
| |
| 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 { |
| priority int8:4 |
| version const[6, int8:4] |
| flow_label array[int8, 3] |
| # TODO: flow_label is actually 20 bits, 4 bits are part of priority |
| length len[payload, int16be] |
| next_header flags[ipv6_types, int8] |
| hop_limit int8 |
| src_ip ipv6_addr |
| dst_ip ipv6_addr |
| payload ipv6_packet_payload |
| } [packed] |
| |
| ipv6_packet_payload { |
| ext_headers array[ipv6_ext_header] |
| payload ipv6_payload |
| } [packed] |
| |
| ################################################################################ |
| ###################################### IP ###################################### |
| ################################################################################ |
| |
| ipv4_payload [ |
| tcp tcp_packet |
| udp udp_packet |
| icmp icmp_packet |
| dccp dccp_packet |
| igmp igmp_packet |
| gre gre_packet |
| tipc tipc_packet |
| ] [varlen] |
| |
| ipv6_payload [ |
| tcp tcp_packet |
| udp udp_packet |
| icmpv6 icmpv6_packet |
| dccp dccp_packet |
| gre gre_packet |
| tipc tipc_packet |
| ] [varlen] |
| |
| ################################################################################ |
| ###################################### 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 <net/tcp.h> |
| include <uapi/linux/tcp.h> |
| |
| 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 = 0, 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 <net/gue.h> |
| |
| udp_packet { |
| src_port sock_port |
| dst_port sock_port |
| length len[parent, int16be] |
| csum csum[parent, pseudo, IPPROTO_UDP, int16be] |
| extensions array[udp_extensions] |
| data array[int8] |
| } [packed] |
| |
| udp_extensions [ |
| guehdr guehdr |
| ] [varlen] |
| |
| guehdr { |
| hlen bytesize4[parent, int8:5] |
| control int8:1 |
| version int8:2 |
| proto_ctype int8 |
| flags flags[guehdr_flags, int16] |
| priv array[flags[guehdr_prov_flags, int32], 0:1] |
| } [packed] |
| |
| guehdr_flags = GUE_FLAG_PRIV |
| guehdr_prov_flags = GUE_PFLAG_REMCSUM |
| |
| ################################################################################ |
| ###################################### GRE ##################################### |
| ################################################################################ |
| |
| # https://en.wikipedia.org/wiki/Generic_Routing_Encapsulation |
| |
| include <net/gre.h> |
| |
| 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] |
| erspan2 gre_packet_erspan[ETH_P_ERSPAN2, erspan_md2] |
| 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 <net/erspan.h> |
| include <uapi/linux/erspan.h> |
| |
| type erspan_base_hdr[VER] { |
| vlan_upper int8:4 |
| ver const[VER, int8:4] |
| vlan int8 |
| session_id_upper int8:2 |
| t int8:1 |
| en int8:2 |
| cos int8:3 |
| session_id int8 |
| } [packed] |
| |
| erspan_md1 { |
| base erspan_base_hdr[1] |
| version const[1, int32] |
| index int32be |
| } [packed] |
| |
| erspan_md2 { |
| base erspan_base_hdr[2] |
| version const[2, int32] |
| 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] |
| |
| ################################################################################ |
| ###################################### 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 <uapi/linux/icmp.h> |
| |
| 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 <uapi/linux/icmpv6.h> |
| |
| 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 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] |
| |
| 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 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 |
| 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_MLD2_REPORT |
| # 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 <uapi/linux/dccp.h> |
| |
| # 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 <uapi/linux/igmp.h> |
| |
| 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] |
| |
| # TODO: is it this ordering or reverse? |
| mpls_label { |
| ttl int32be:8 |
| s int32be:1 |
| tc int32be:3 |
| label int32be:20 |
| } |
| |
| 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 <uapi/linux/tipc.h> |
| include <net/tipc/msg.h> |
| |
| 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 |