Home | History | Annotate | Download | only in linux
      1 # Copyright 2017 syzkaller project authors. All rights reserved.
      2 # Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
      3 
      4 include <linux/types.h>
      5 include <linux/byteorder/generic.h>
      6 
      7 syz_emit_ethernet(len len[packet], packet ptr[in, eth_packet], frags ptr[in, vnet_fragmentation, opt])
      8 
      9 vnet_fragmentation {
     10 # If set and we have remaining data after fragmentation, it is written in an additional fragment.
     11 # If not set, data remaining after fragmentation is discarded.
     12 	full	int32[0:1]
     13 	count	int32[1:4]
     14 	frags	array[int32[0:4096], 4]
     15 }
     16 
     17 resource tcp_seq_num[int32]: 0x41424344
     18 
     19 tcp_resources {
     20 	seq	tcp_seq_num
     21 	ack	tcp_seq_num
     22 }
     23 
     24 # These pseudo syscalls read a packet from /dev/net/tun and extract tcp sequence and acknowledgement numbers from it.
     25 # They also adds the inc arguments to the returned values, this way sequence numbers get incremented.
     26 syz_extract_tcp_res(res ptr[out, tcp_resources], seq_inc int32, ack_inc int32)
     27 syz_extract_tcp_res$synack(res ptr[out, tcp_resources], seq_inc const[1], ack_inc const[0])
     28 
     29 ################################################################################
     30 ################################### Ethernet ###################################
     31 ################################################################################
     32 
     33 # https://en.wikipedia.org/wiki/Ethernet_frame#Structure
     34 # https://en.wikipedia.org/wiki/IEEE_802.1Q
     35 
     36 include <uapi/linux/if.h>
     37 include <uapi/linux/if_ether.h>
     38 
     39 type mac_addr_t[LAST] {
     40 	a0	array[const[0xaa, int8], 5]
     41 	a1	LAST
     42 } [packed]
     43 
     44 mac_addr_link_local {
     45 	a0	const[0x1, int8]
     46 	a1	const[0x80, int8]
     47 	a2	const[0xc2, int8]
     48 	a3	const[0x0, int8]
     49 	a4	const[0x0, int8]
     50 	a5	flags[mac_addr_link_local_values, int8]
     51 } [packed]
     52 
     53 mac_addr_link_local_values = 0x0, 0x1, 0x2, 0x3, 0xe
     54 
     55 # This corresponds to the last digit in DEV_MAC/DEV_IPV4/DEV_IPV6 in executor/common_linux.h
     56 type netdev_addr_id int8[10:33]
     57 
     58 mac_addr [
     59 	empty		array[const[0x0, int8], 6]
     60 # These correspond to LOCAL_MAC/REMOTE_MAC/DEV_MAC in executor/common_linux.h
     61 	local		mac_addr_t[const[0xaa, int8]]
     62 	remote		mac_addr_t[const[0xbb, int8]]
     63 	dev		mac_addr_t[netdev_addr_id]
     64 	broadcast	array[const[0xff, int8], 6]
     65 	link_local	mac_addr_link_local
     66 	random		array[int8, 6]
     67 ]
     68 
     69 type mac_addr_mask array[flags[mac_addr_mask_vals, int8], 6]
     70 mac_addr_mask_vals = 0, 0xff
     71 
     72 vlan_tag_ad {
     73 	tpid	const[ETH_P_QINQ1, int16be]
     74 	pcp	int16:3
     75 	dei	int16:1
     76 	vid	int16:12[0:4]
     77 } [packed]
     78 
     79 vlan_tag_q {
     80 	tpid	const[ETH_P_8021Q, int16be]
     81 	pcp	int16:3
     82 	dei	int16:1
     83 	vid	int16:12[0:4]
     84 } [packed]
     85 
     86 vlan_tag {
     87 	tag_ad	array[vlan_tag_ad, 0:1]
     88 	tag_q	vlan_tag_q
     89 } [packed]
     90 
     91 eth_packet {
     92 	dst_mac	mac_addr
     93 	src_mac	mac_addr
     94 	vtag	array[vlan_tag, 0:1]
     95 	payload	eth_payload
     96 } [packed]
     97 
     98 eth_payload {
     99 	eth2	eth2_packet
    100 } [packed]
    101 
    102 ################################################################################
    103 ################################## Ethernet 2 ##################################
    104 ################################################################################
    105 
    106 # https://en.wikipedia.org/wiki/Ethernet_frame#Ethernet_II
    107 
    108 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
    109 
    110 eth2_packet [
    111 	generic	eth2_packet_generic
    112 	arp	eth2_packet_t[ETH_P_ARP, arp_packet]
    113 	ipv4	eth2_packet_t[ETH_P_IP, ipv4_packet]
    114 	ipv6	eth2_packet_t[ETH_P_IPV6, ipv6_packet]
    115 	llc	eth2_packet_t[ETH_P_802_2, llc_packet]
    116 	llc_tr	eth2_packet_t[ETH_P_TR_802_2, llc_packet]
    117 	ipx	eth2_packet_t[ETH_P_IPX, ipx_packet]
    118 	x25	eth2_packet_t[ETH_P_X25, x25_packet]
    119 	mpls_uc	eth2_packet_t[ETH_P_MPLS_UC, mpls_packet]
    120 	mpls_mc	eth2_packet_t[ETH_P_MPLS_MC, mpls_packet]
    121 	can	eth2_packet_t[ETH_P_CAN, can_frame]
    122 	canfd	eth2_packet_t[ETH_P_CANFD, canfd_frame]
    123 ] [varlen]
    124 
    125 eth2_packet_generic {
    126 	etype	flags[ether_types, int16be]
    127 	payload	array[int8]
    128 } [packed]
    129 
    130 type eth2_packet_t[TYPE, PAYLOAD] {
    131 	etype	const[TYPE, int16be]
    132 	payload	PAYLOAD
    133 } [packed]
    134 
    135 ################################################################################
    136 ###################################### ARP #####################################
    137 ################################################################################
    138 
    139 # https://en.wikipedia.org/wiki/Address_Resolution_Protocol#Packet_structure
    140 
    141 include <uapi/linux/if_arp.h>
    142 
    143 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
    144 
    145 arp_ops = ARPOP_REQUEST, ARPOP_REPLY, ARPOP_RREQUEST, ARPOP_RREPLY, ARPOP_InREQUEST, ARPOP_InREPLY, ARPOP_NAK
    146 
    147 arp_generic_packet {
    148 	htype	flags[arp_htypes, int16be]
    149 	ptype	flags[ether_types, int16be]
    150 	hlen	const[6, int8]
    151 	plen	len[spa, int8]
    152 	op	flags[arp_ops, int16be]
    153 	sha	mac_addr
    154 	spa	array[int8, 0:16]
    155 	tha	mac_addr
    156 	tpa	array[int8, 16]
    157 } [packed]
    158 
    159 arp_ether_ipv4_packet {
    160 	htype	const[ARPHRD_ETHER, int16be]
    161 	ptype	const[ETH_P_IP, int16be]
    162 	hlen	const[6, int8]
    163 	plen	const[4, int8]
    164 	op	flags[arp_ops, int16be]
    165 	sha	mac_addr
    166 	spa	ipv4_addr
    167 	tha	mac_addr
    168 	tpa	ipv4_addr
    169 } [packed]
    170 
    171 arp_ether_ipv6_packet {
    172 	htype	const[ARPHRD_ETHER, int16be]
    173 	ptype	const[ETH_P_IPV6, int16be]
    174 	hlen	const[6, int8]
    175 	plen	const[16, int8]
    176 	op	flags[arp_ops, int16be]
    177 	sha	mac_addr
    178 	spa	ipv6_addr
    179 	tha	mac_addr
    180 	tpa	ipv6_addr
    181 } [packed]
    182 
    183 arp_packet [
    184 	generic		arp_generic_packet
    185 	ether_ipv4	arp_ether_ipv4_packet
    186 	ether_ipv6	arp_ether_ipv6_packet
    187 ] [varlen]
    188 
    189 ################################################################################
    190 ################################## 802.2 (LLC) #################################
    191 ################################################################################
    192 
    193 # https://en.wikipedia.org/wiki/IEEE_802.2
    194 # https://en.wikipedia.org/wiki/Subnetwork_Access_Protocol
    195 
    196 include <uapi/linux/llc.h>
    197 
    198 # Adding '1' as a SAP value since the lower bit in SAP has a special meaning.
    199 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
    200 
    201 llc_generic_packet {
    202 	dsap	flags[sap_values, int8]
    203 	ssap	flags[sap_values, int8]
    204 	ctrl	array[int8, 1:2]
    205 	payload	array[int8]
    206 } [packed]
    207 
    208 sap_snap_values = 1, LLC_SAP_SNAP
    209 
    210 llc_snap_packet {
    211 	dsap		flags[sap_snap_values, int8]
    212 	ssap		flags[sap_snap_values, int8]
    213 	control		array[int8, 1:2]
    214 	oui		array[int8, 3]
    215 	protocol_id	flags[ether_types, int16be]
    216 	payload		array[int8]
    217 } [packed]
    218 
    219 llc_payload [
    220 	llc	llc_generic_packet
    221 	snap	llc_snap_packet
    222 ] [varlen]
    223 
    224 llc_packet {
    225 # TODO: is there length or not? I don't see it in packet format...
    226 #	length	len[payload, int16be]
    227 	payload	llc_payload
    228 } [packed]
    229 
    230 ################################################################################
    231 ###################################### IPX #####################################
    232 ################################################################################
    233 
    234 # http://www.networksorcery.com/enp/protocol/ipx.htm
    235 # https://en.wikipedia.org/wiki/Internetwork_Packet_Exchange#IPX_packet_structure
    236 
    237 include <net/ipx.h>
    238 
    239 ipx_network [
    240 	random		int32be
    241 	current		const[0x0, int32be]
    242 	broadcast	const[0xffffffff, int32be]
    243 ]
    244 
    245 ipx_node [
    246 	random		array[int8, 6]
    247 	current		array[const[0x0, int8], 6]
    248 	broadcast	array[const[0xff, int8], 6]
    249 ]
    250 
    251 ipx_addr {
    252 	network	ipx_network
    253 	node	ipx_node
    254 	socket	int16be
    255 } [packed]
    256 
    257 ipx_packet_types = IPX_TYPE_UNKNOWN, IPX_TYPE_RIP, IPX_TYPE_SAP, IPX_TYPE_SPX, IPX_TYPE_NCP, IPX_TYPE_PPROP
    258 
    259 ipx_packet {
    260 	csum		const[0xffff, int16be]
    261 	length		len[parent, int16be]
    262 	control		int8
    263 	type		flags[ipx_packet_types, int8]
    264 	dst_addr	ipx_addr
    265 	src_addr	ipx_addr
    266 	payload		array[int8]
    267 } [packed]
    268 
    269 # TODO: setup ipx on virtual interfaces in executor
    270 # TODO: describe particular ipx types
    271 # TODO: open ipx sockets from userspace
    272 
    273 ################################################################################
    274 ###################################### x25 #####################################
    275 ################################################################################
    276 
    277 # Documentation/networking/x25.txt
    278 # Documentation/networking/x25-iface.txt
    279 # http://www.dafuer.com/kleinehelferlein/x25layer.htm
    280 
    281 include <uapi/linux/if_x25.h>
    282 include <net/x25.h>
    283 
    284 x25_iface_types = X25_IFACE_DATA, X25_IFACE_CONNECT, X25_IFACE_DISCONNECT, X25_IFACE_PARAMS
    285 
    286 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
    287 
    288 x25_packet {
    289 	iface	flags[x25_iface_types, int8]
    290 	wtf	int8
    291 	frame	flags[x25_frame_types, int8]
    292 	payload	array[int8]
    293 } [packed]
    294 
    295 # TODO: open x25 sockets from userspace
    296 
    297 ################################################################################
    298 ##################################### IPv4 #####################################
    299 ################################################################################
    300 
    301 # https://tools.ietf.org/html/rfc791#section-3.1
    302 # https://en.wikipedia.org/wiki/IPv4#Header
    303 
    304 # TODO: https://en.wikipedia.org/wiki/IPsec#Authentication_Header
    305 # TODO: https://en.wikipedia.org/wiki/IPsec#Encapsulating_Security_Payload
    306 
    307 include <uapi/linux/in.h>
    308 include <uapi/linux/ip.h>
    309 include <uapi/linux/l2tp.h>
    310 include <net/cipso_ipv4.h>
    311 
    312 type ipv4_addr_t[LAST] {
    313 	a0	const[0xac, int8]
    314 	a1	const[0x14, int8]
    315 	a2	const[0x14, int8]
    316 	a3	LAST
    317 } [packed]
    318 
    319 ipv4_addr [
    320 # 0.0.0.0
    321 	empty		const[0x0, int32be]
    322 # These correspond to LOCAL_IPV4/REMOTE_IPV4/DEV_IPV4 in executor/common_linux.h
    323 	local		ipv4_addr_t[const[170, int8]]
    324 	remote		ipv4_addr_t[const[187, int8]]
    325 	dev		ipv4_addr_t[netdev_addr_id]
    326 # 127.0.0.1
    327 	loopback	const[0x7f000001, int32be]
    328 # 224.0.0.1
    329 	multicast1	const[0xe0000001, int32be]
    330 # 224.0.0.2
    331 	multicast2	const[0xe0000002, int32be]
    332 # 255.255.255.255
    333 	broadcast	const[0xffffffff, int32be]
    334 # random
    335 	rand_addr	int32be
    336 ]
    337 
    338 type ipv4_addr_mask flags[ipv4_addr_mask_vals, int32be]
    339 ipv4_addr_mask_vals = 0, 0xff000000, 0xffffff00, 0xffffffff, 0xff
    340 
    341 # http://www.iana.org/assignments/ip-parameters/ip-parameters.xhtml#ip-parameters-1
    342 ipv4_option [
    343 	generic		ipv4_option_generic
    344 	end		ipv4_option_end
    345 	noop		ipv4_option_noop
    346 	lsrr		ipv4_option_lsrr
    347 	ssrr		ipv4_option_ssrr
    348 	rr		ipv4_option_rr
    349 	timestamp	ipv4_option_timestamp
    350 	cipso		ipv4_option_cipso
    351 	ra		ipv4_option_ra
    352 # IPOPT_SEC and IPOPT_SID are not supported by Linux kernel
    353 ] [varlen]
    354 
    355 ipv4_option_types = IPOPT_END, IPOPT_NOOP, IPOPT_SEC, IPOPT_LSRR, IPOPT_TIMESTAMP, IPOPT_CIPSO, IPOPT_RR, IPOPT_SID, IPOPT_SSRR, IPOPT_RA
    356 
    357 ipv4_option_generic {
    358 	type	flags[ipv4_option_types, int8]
    359 	length	len[parent, int8]
    360 	data	array[int8, 0:16]
    361 } [packed]
    362 
    363 # https://tools.ietf.org/html/rfc791#section-3.1
    364 ipv4_option_end {
    365 	type	const[IPOPT_END, int8]
    366 } [packed]
    367 
    368 # https://tools.ietf.org/html/rfc791#section-3.1
    369 ipv4_option_noop {
    370 	type	const[IPOPT_NOOP, int8]
    371 } [packed]
    372 
    373 # https://tools.ietf.org/html/rfc791#section-3.1
    374 ipv4_option_lsrr {
    375 	type	const[IPOPT_LSRR, int8]
    376 	length	len[parent, int8]
    377 	pointer	int8
    378 	data	array[ipv4_addr]
    379 } [packed]
    380 
    381 # https://tools.ietf.org/html/rfc791#section-3.1
    382 ipv4_option_ssrr {
    383 	type	const[IPOPT_SSRR, int8]
    384 	length	len[parent, int8]
    385 	pointer	int8
    386 	data	array[ipv4_addr]
    387 } [packed]
    388 
    389 # https://tools.ietf.org/html/rfc791#section-3.1
    390 ipv4_option_rr {
    391 	type	const[IPOPT_RR, int8]
    392 	length	len[parent, int8]
    393 	pointer	int8
    394 	data	array[ipv4_addr]
    395 } [packed]
    396 
    397 ipv4_option_timestamp_flags = IPOPT_TS_TSONLY, IPOPT_TS_TSANDADDR, IPOPT_TS_PRESPEC
    398 
    399 ipv4_option_timestamp_timestamp {
    400 	addr		array[ipv4_addr, 0:1]
    401 	timestamp	int32be
    402 } [packed]
    403 
    404 # https://tools.ietf.org/html/rfc791#section-3.1
    405 # http://www.networksorcery.com/enp/protocol/ip/option004.htm
    406 ipv4_option_timestamp {
    407 	type		const[IPOPT_TIMESTAMP, int8]
    408 	length		len[parent, int8]
    409 	pointer		int8
    410 	flg		flags[ipv4_option_timestamp_flags, int8:4]
    411 	oflw		int8:4
    412 	timestamps	array[ipv4_option_timestamp_timestamp]
    413 } [packed]
    414 
    415 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
    416 
    417 # TODO: describe particular tag types
    418 ipv4_option_cipso_tag {
    419 	type	flags[ipv4_option_cipso_tag_types, int8]
    420 	length	len[parent, int8]
    421 	data	array[int8, 0:16]
    422 } [packed]
    423 
    424 # https://www.ietf.org/archive/id/draft-ietf-cipso-ipsecurity-01.txt
    425 ipv4_option_cipso {
    426 	type	const[IPOPT_CIPSO, int8]
    427 	length	len[parent, int8]
    428 	doi	int32be
    429 	tags	array[ipv4_option_cipso_tag]
    430 } [packed]
    431 
    432 # https://tools.ietf.org/html/rfc2113
    433 ipv4_option_ra {
    434 	type	const[IPOPT_RA, int8]
    435 	length	len[parent, int8]
    436 	value	int32be
    437 } [packed]
    438 
    439 ipv4_options {
    440 	options	array[ipv4_option]
    441 } [packed, align_4]
    442 
    443 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
    444 
    445 ipv4_header {
    446 	ihl		bytesize4[parent, int8:4]
    447 	version		const[4, int8:4]
    448 	ecn		int8:2
    449 	dscp		int8:6
    450 	total_len	len[ipv4_packet, int16be]
    451 	id		int16be[100:104]
    452 	frag_off	int16be
    453 # TODO: frag_off is actually 13 bits, 3 bits are flags
    454 	ttl		int8
    455 	protocol	flags[ipv4_types, int8]
    456 	csum		csum[parent, inet, int16be]
    457 	src_ip		ipv4_addr
    458 	dst_ip		ipv4_addr
    459 	options		ipv4_options
    460 } [packed]
    461 
    462 ipv4_packet {
    463 	header	ipv4_header
    464 	payload	ipv4_payload
    465 } [packed]
    466 
    467 ################################################################################
    468 ##################################### IPv6 #####################################
    469 ################################################################################
    470 
    471 # https://tools.ietf.org/html/rfc2460#section-3
    472 # https://en.wikipedia.org/wiki/IPv6_packet#Fixed_header
    473 
    474 include <uapi/linux/in6.h>
    475 include <uapi/linux/ipv6.h>
    476 include <uapi/linux/seg6.h>
    477 include <uapi/linux/ip6_tunnel.h>
    478 include <net/ipv6.h>
    479 
    480 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
    481 
    482 ipv6_addr_empty {
    483 	a0	array[const[0x0, int8], 16]
    484 }
    485 
    486 type ipv6_addr_t[LAST] {
    487 	a0	const[0xfe, int8]
    488 	a1	const[0x80, int8]
    489 	a2	array[const[0x0, int8], 13]
    490 	a3	LAST
    491 } [packed]
    492 
    493 ipv6_addr_loopback {
    494 	a0	const[0, int64be]
    495 	a1	const[1, int64be]
    496 } [packed, align_4]
    497 
    498 ipv6_addr_ipv4 {
    499 	a0	array[const[0x0, int8], 10]
    500 	a1	array[const[0xff, int8], 2]
    501 	a3	ipv4_addr
    502 } [packed]
    503 
    504 ipv6_addr_multicast1 {
    505 	a0	const[0xff, int8]
    506 	a1	const[0x1, int8]
    507 	a2	array[const[0x0, int8], 13]
    508 	a3	const[0x1, int8]
    509 } [packed]
    510 
    511 ipv6_addr_multicast2 {
    512 	a0	const[0xff, int8]
    513 	a1	const[0x2, int8]
    514 	a2	array[const[0x0, int8], 13]
    515 	a3	const[0x1, int8]
    516 } [packed]
    517 
    518 ipv6_addr [
    519 	empty		ipv6_addr_empty
    520 # These correspond to LOCAL_IPV6/REMOTE_IPV6/DEV_IPV6 in executor/common_linux.h
    521 	local		ipv6_addr_t[const[0xaa, int8]]
    522 	remote		ipv6_addr_t[const[0xbb, int8]]
    523 	dev		ipv6_addr_t[netdev_addr_id]
    524 	loopback	ipv6_addr_loopback
    525 	ipv4		ipv6_addr_ipv4
    526 	mcast1		ipv6_addr_multicast1
    527 	mcast2		ipv6_addr_multicast2
    528 ]
    529 
    530 type ipv6_addr_mask array[flags[ipv4_addr_mask_vals, int32be], 4]
    531 
    532 # TODO: Describe more types of headers
    533 # 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
    534 # https://tools.ietf.org/html/rfc2402
    535 # https://tools.ietf.org/html/rfc2406
    536 # https://tools.ietf.org/html/rfc3775
    537 
    538 # https://tools.ietf.org/html/rfc2460#section-4
    539 # The length field in each of the extension headers specifies the
    540 # length of the header in 8-octet units not including the first 8 octets.
    541 ipv6_ext_header [
    542 	hopopts		ipv6_hopots_ext_header
    543 	routing		ipv6_rt_hdr
    544 	srh		ipv6_sr_hdr
    545 	fragment	ipv6_fragment_ext_header
    546 	dstopts		ipv6_dstopts_ext_header
    547 ] [varlen]
    548 
    549 ipv6_hopots_ext_header {
    550 	next_header	flags[ipv6_types, int8]
    551 	length		bytesize8[options, int8]
    552 	pad		array[const[0, int8], 6]
    553 	options		array[ipv6_tlv_option]
    554 } [packed, align_8]
    555 
    556 ipv6_routing_types = IPV6_SRCRT_STRICT, IPV6_SRCRT_TYPE_0, IPV6_SRCRT_TYPE_2
    557 
    558 ipv6_rt_hdr {
    559 	next_header	flags[ipv6_types, int8]
    560 	length		bytesize8[data, int8]
    561 	routing_type	flags[ipv6_routing_types, int8]
    562 	segments_left	int8
    563 	reserved	const[0, int32]
    564 	data		array[ipv6_addr]
    565 } [packed, align_8]
    566 
    567 ipv6_sr_hdr {
    568 	nexthdr		flags[ipv6_types, int8]
    569 	hdrlen		bytesize8[segments, int8]
    570 	type		const[IPV6_SRCRT_TYPE_4, int8]
    571 	segments_left	len[segments, int8]
    572 	first_segment	int8
    573 	flags		flags[ipv6_sr_flags, int8]
    574 	tag		int16
    575 	segments	array[ipv6_addr]
    576 # TODO: this may be followed by sr6_tlv_hmac if SR6_FLAG1_HMAC is set.
    577 # However, if we place it here, we won't be able to calculate hdrlen (len of 2 fields),
    578 # and if we move segments and sr6_tlv_hmac into a separate struct,
    579 # we won't be able to calculate segments_left because it will need to
    580 # refer to a field of a subobject. What may help is allowing specifying
    581 # subfields as len/bytesize targets, e.g. "len[payload.segments]", or "bytesize[parent_struct.foo]".
    582 } [packed, align_8]
    583 
    584 ipv6_sr_flags = SR6_FLAG1_PROTECTED, SR6_FLAG1_OAM, SR6_FLAG1_ALERT, SR6_FLAG1_HMAC
    585 
    586 ipv6_fragment_ext_header {
    587 	next_header	flags[ipv6_types, int8]
    588 	reserved1	const[0, int8]
    589 	fragment_off_hi	int8
    590 	m_flag		int8:1
    591 	reserved2	const[0, int8:2]
    592 	fragment_off_lo	int8:5
    593 	identification	int32[100:104]
    594 } [packed, align_8]
    595 
    596 ipv6_dstopts_ext_header {
    597 	next_header	flags[ipv6_types, int8]
    598 	length		bytesize8[options, int8]
    599 	pad		array[const[0, int8], 6]
    600 	options		array[ipv6_tlv_option]
    601 } [packed, align_8]
    602 
    603 ipv6_tlv_option [
    604 	generic	ipv6_tlv_generic
    605 	pad1	ipv6_tlv_pad1
    606 	padn	ipv6_tlv_padn
    607 	ra	ipv6_tlv_ra
    608 	jumbo	ipv6_tlv_jumbo
    609 	calipso	ipv6_tlv_calipso
    610 	hao	ipv6_tlv_hao
    611 	enc_lim	ipv6_tlv_enc_lim
    612 ] [varlen]
    613 
    614 ipv6_tlv_generic {
    615 	type	int8
    616 	length	len[data, int8]
    617 	data	array[int8]
    618 } [packed]
    619 
    620 ipv6_tlv_pad1 {
    621 	type	const[IPV6_TLV_PAD1, int8]
    622 	len	const[1, int8]
    623 	pad	const[0, int8]
    624 } [packed]
    625 
    626 ipv6_tlv_padn {
    627 	type	const[IPV6_TLV_PADN, int8]
    628 	len	len[pad, int8]
    629 	pad	array[const[0, int8]]
    630 } [packed]
    631 
    632 ipv6_tlv_ra {
    633 	type	const[IPV6_TLV_ROUTERALERT, int8]
    634 	len	const[2, int8]
    635 	ra	int16be
    636 } [packed]
    637 
    638 ipv6_tlv_jumbo {
    639 	type	const[IPV6_TLV_JUMBO, int8]
    640 	len	const[4, int8]
    641 	pkt_len	int32be
    642 } [packed]
    643 
    644 # https://tools.ietf.org/html/rfc5570#section-5.1
    645 ipv6_tlv_calipso {
    646 	type	const[IPV6_TLV_CALIPSO, int8]
    647 	len	bytesize[payload, int8]
    648 	payload	ipv6_tlv_calipso_payload
    649 } [packed]
    650 
    651 # TODO: checksum is generally incorrect.
    652 # TODO: domain should be flags, but it's unclear if we have any domains registered by default.
    653 ipv6_tlv_calipso_payload {
    654 	domain			int32be
    655 	compartment_length	bytesize4[compartment_bitmap, int8]
    656 	sensitivity_level	int8
    657 	checksum		int16
    658 	compartment_bitmap	array[int64]
    659 } [packed]
    660 
    661 ipv6_tlv_hao {
    662 	type	const[IPV6_TLV_HAO, int8]
    663 	len	bytesize[addr, int8]
    664 	addr	ipv6_addr
    665 } [packed]
    666 
    667 ipv6_tlv_enc_lim {
    668 	type		const[IPV6_TLV_TNL_ENCAP_LIMIT, int8]
    669 	len		const[1, int8]
    670 	encap_limit	int8
    671 } [packed]
    672 
    673 ipv6_packet {
    674 	priority	int8:4
    675 	version		const[6, int8:4]
    676 	flow_label	array[int8, 3]
    677 # TODO: flow_label is actually 20 bits, 4 bits are part of priority
    678 	length		len[payload, int16be]
    679 	next_header	flags[ipv6_types, int8]
    680 	hop_limit	int8
    681 	src_ip		ipv6_addr
    682 	dst_ip		ipv6_addr
    683 	payload		ipv6_packet_payload
    684 } [packed]
    685 
    686 ipv6_packet_payload {
    687 	ext_headers	array[ipv6_ext_header]
    688 	payload		ipv6_payload
    689 } [packed]
    690 
    691 ################################################################################
    692 ###################################### IP ######################################
    693 ################################################################################
    694 
    695 ipv4_payload [
    696 	tcp	tcp_packet
    697 	udp	udp_packet
    698 	icmp	icmp_packet
    699 	dccp	dccp_packet
    700 	igmp	igmp_packet
    701 	gre	gre_packet
    702 ] [varlen]
    703 
    704 ipv6_payload [
    705 	tcp	tcp_packet
    706 	udp	udp_packet
    707 	icmpv6	icmpv6_packet
    708 	dccp	dccp_packet
    709 	gre	gre_packet
    710 ] [varlen]
    711 
    712 ################################################################################
    713 ###################################### TCP #####################################
    714 ################################################################################
    715 
    716 # https://tools.ietf.org/html/rfc793#section-3.1
    717 # https://en.wikipedia.org/wiki/Transmission_Control_Protocol#TCP_segment_structure
    718 # http://www.iana.org/assignments/tcp-parameters/tcp-parameters.xhtml
    719 
    720 include <net/tcp.h>
    721 include <uapi/linux/tcp.h>
    722 
    723 tcp_option [
    724 	generic		tcp_generic_option
    725 	nop		tcp_nop_option
    726 	eol		tcp_eol_option
    727 	mss		tcp_mss_option
    728 	window		tcp_window_option
    729 	sack_perm	tcp_sack_perm_option
    730 	sack		tcp_sack_option
    731 	timestamp	tcp_timestamp_option
    732 	md5sig		tcp_md5sig_option
    733 	fastopen	tcp_fastopen_option
    734 	exp_fastopen	tcp_exp_fastopen_option
    735 	exp_smc		tcp_exp_smc_option
    736 ] [varlen]
    737 
    738 tcp_option_types = TCPOPT_NOP, TCPOPT_EOL, TCPOPT_MSS, TCPOPT_WINDOW, TCPOPT_SACK_PERM, TCPOPT_SACK, TCPOPT_TIMESTAMP, TCPOPT_MD5SIG, TCPOPT_FASTOPEN, TCPOPT_EXP
    739 
    740 tcp_generic_option {
    741 	type	flags[tcp_option_types, int8]
    742 	length	len[parent, int8]
    743 	data	array[int8, 0:16]
    744 } [packed]
    745 
    746 # https://tools.ietf.org/html/rfc793#section-3.1
    747 tcp_nop_option {
    748 	type	const[TCPOPT_NOP, int8]
    749 } [packed]
    750 
    751 # https://tools.ietf.org/html/rfc793#section-3.1
    752 tcp_eol_option {
    753 	type	const[TCPOPT_EOL, int8]
    754 } [packed]
    755 
    756 # https://tools.ietf.org/html/rfc793#section-3.1
    757 tcp_mss_option {
    758 	type		const[TCPOPT_MSS, int8]
    759 	length		len[parent, int8]
    760 	seg_size	int16
    761 } [packed]
    762 
    763 # https://tools.ietf.org/html/rfc7323#section-2
    764 tcp_window_option {
    765 	type	const[TCPOPT_WINDOW, int8]
    766 	length	len[parent, int8]
    767 	shift	int8
    768 } [packed]
    769 
    770 # https://tools.ietf.org/html/rfc2018#section-2
    771 tcp_sack_perm_option {
    772 	type	const[TCPOPT_SACK_PERM, int8]
    773 	length	len[parent, int8]
    774 } [packed]
    775 
    776 # https://tools.ietf.org/html/rfc2018#section-3
    777 tcp_sack_option {
    778 	type	const[TCPOPT_SACK, int8]
    779 	length	len[parent, int8]
    780 	data	array[int32be]
    781 } [packed]
    782 
    783 # https://tools.ietf.org/html/rfc7323#section-3
    784 tcp_timestamp_option {
    785 	type	const[TCPOPT_TIMESTAMP, int8]
    786 	length	len[parent, int8]
    787 	tsval	int32be
    788 	tsecr	int32be
    789 } [packed]
    790 
    791 # https://tools.ietf.org/html/rfc2385#section-3.0
    792 tcp_md5sig_option {
    793 	type	const[TCPOPT_MD5SIG, int8]
    794 	length	len[parent, int8]
    795 	md5	array[int8, 16]
    796 } [packed]
    797 
    798 # https://tools.ietf.org/html/rfc7413#section-4.1.1
    799 tcp_fastopen_option {
    800 	type	const[TCPOPT_FASTOPEN, int8]
    801 	length	len[parent, int8]
    802 	data	array[int8, 0:16]
    803 } [packed]
    804 
    805 tcp_exp_fastopen_option {
    806 	type	const[TCPOPT_EXP, int8]
    807 	length	len[parent, int8]
    808 	subtype	const[TCPOPT_FASTOPEN_MAGIC, int16be]
    809 	data	array[int8, 0:16]
    810 } [packed]
    811 
    812 tcp_exp_smc_option {
    813 	type	const[TCPOPT_EXP, int8]
    814 	length	len[parent, int8]
    815 	subtype	const[TCPOPT_SMC_MAGIC, int32be]
    816 } [packed]
    817 
    818 tcp_options {
    819 	options	array[tcp_option]
    820 } [packed, align_4]
    821 
    822 tcp_flags = 0, TCPHDR_FIN, TCPHDR_SYN, TCPHDR_RST, TCPHDR_PSH, TCPHDR_ACK, TCPHDR_URG, TCPHDR_ECE, TCPHDR_CWR, TCPHDR_SYN_ECN
    823 
    824 tcp_header {
    825 	src_port	sock_port
    826 	dst_port	sock_port
    827 	seq_num		tcp_seq_num
    828 	ack_num		tcp_seq_num
    829 	ns		int8:1
    830 	reserved	const[0, int8:3]
    831 	data_off	bytesize4[parent, int8:4]
    832 	flags		flags[tcp_flags, int8]
    833 	window_size	int16be
    834 	csum		csum[tcp_packet, pseudo, IPPROTO_TCP, int16be]
    835 	urg_ptr		int16be
    836 	options		tcp_options
    837 } [packed]
    838 
    839 tcp_packet {
    840 	header	tcp_header
    841 	payload	tcp_payload
    842 } [packed]
    843 
    844 tcp_payload {
    845 	payload	array[int8]
    846 } [packed]
    847 
    848 ################################################################################
    849 ###################################### UDP #####################################
    850 ################################################################################
    851 
    852 # https://tools.ietf.org/html/rfc768
    853 # https://en.wikipedia.org/wiki/User_Datagram_Protocol#Packet_structure
    854 
    855 include <net/gue.h>
    856 
    857 udp_packet {
    858 	src_port	sock_port
    859 	dst_port	sock_port
    860 	length		len[parent, int16be]
    861 	csum		csum[parent, pseudo, IPPROTO_UDP, int16be]
    862 	extensions	array[udp_extensions]
    863 	data		array[int8]
    864 } [packed]
    865 
    866 udp_extensions [
    867 	guehdr	guehdr
    868 ] [varlen]
    869 
    870 guehdr {
    871 	hlen		bytesize4[parent, int8:5]
    872 	control		int8:1
    873 	version		int8:2
    874 	proto_ctype	int8
    875 	flags		flags[guehdr_flags, int16]
    876 	priv		array[flags[guehdr_prov_flags, int32], 0:1]
    877 } [packed]
    878 
    879 guehdr_flags = GUE_FLAG_PRIV
    880 guehdr_prov_flags = GUE_PFLAG_REMCSUM
    881 
    882 ################################################################################
    883 ###################################### GRE #####################################
    884 ################################################################################
    885 
    886 # https://en.wikipedia.org/wiki/Generic_Routing_Encapsulation
    887 
    888 include <net/gre.h>
    889 
    890 gre_packet {
    891 	pptp		gre_packet_pptp
    892 # TODO: add more packets
    893 # TODO: the payload should be ipv4_packet/ipv6_packet, but this creates recursion
    894 # ipv4 -> gre -> ipv4 -> ...
    895 	cisco_ipv4	gre_packet_cisco[ETH_P_IP, array[int8]]
    896 	cisco_ipv6	gre_packet_cisco[ETH_P_IPV6, array[int8]]
    897 	erspan1		gre_packet_erspan[ETH_P_ERSPAN, erspan_md1]
    898 	erspan2		gre_packet_erspan[ETH_P_ERSPAN2, erspan_md2]
    899 	teb		gre_packet_erspan[ETH_P_TEB, array[int8]]
    900 } [packed]
    901 
    902 type gre_packet_cisco[PROTO, PAYLOAD] {
    903 	C		int16:1
    904 	R		const[0, int16:1]
    905 	K		int16:1
    906 	S		int16:1
    907 	reserved	const[0, int16:9]
    908 	version		const[0, int16:3]
    909 	protocol	const[PROTO, int16be]
    910 # checksum, key, sequence number
    911 	add		array[int16be, 0:3]
    912 	payload		PAYLOAD
    913 } [packed]
    914 
    915 gre_packet_pptp {
    916 	C		const[0, int16:1]
    917 	R		const[0, int16:1]
    918 	K		const[1, int16:1]
    919 	S		int16:1
    920 	reserved	const[0, int16:4]
    921 	A		int16:1
    922 	flags		const[0, int16:4]
    923 	version		const[1, int16:3]
    924 	protocol	const[0x880b, int16be]
    925 	payload_len	bytesize[payload, int16be]
    926 	key_call_id	pptp_call_id
    927 # sequence/ack number
    928 	add		array[int16be, 0:2]
    929 	payload		ppp_packet
    930 } [packed]
    931 
    932 type ppp_packet array[int8]
    933 
    934 type gre_packet_erspan[PROTO, PAYLOAD] {
    935 	H		const[8, int16]
    936 	protocol	const[PROTO, int16be]
    937 	seq		int32be[0:4]
    938 	payload		PAYLOAD
    939 } [packed]
    940 
    941 ################################################################################
    942 ##################################### ERSPAN ###################################
    943 ################################################################################
    944 
    945 include <net/erspan.h>
    946 include <uapi/linux/erspan.h>
    947 
    948 type erspan_base_hdr[VER] {
    949 	vlan_upper		int8:4
    950 	ver			const[VER, int8:4]
    951 	vlan			int8
    952 	session_id_upper	int8:2
    953 	t			int8:1
    954 	en			int8:2
    955 	cos			int8:3
    956 	session_id		int8
    957 } [packed]
    958 
    959 erspan_md1 {
    960 	base	erspan_base_hdr[1]
    961 	version	const[1, int32]
    962 	index	int32be
    963 } [packed]
    964 
    965 erspan_md2 {
    966 	base		erspan_base_hdr[2]
    967 	version		const[2, int32]
    968 	timestamp	int32be
    969 	sgt		int16be
    970 	hwid_upper	int8:2
    971 	ft		int8:5
    972 	p		int8:1
    973 	o		int8:1
    974 	gra		int8:2
    975 	dir		int8:1
    976 	hwid		int8:1
    977 } [packed]
    978 
    979 ################################################################################
    980 ###################################### ICMP ####################################
    981 ################################################################################
    982 
    983 # https://en.wikipedia.org/wiki/Internet_Control_Message_Protocol#ICMP_datagram_structure
    984 # https://tools.ietf.org/html/rfc792
    985 # https://tools.ietf.org/html/rfc4884#section-4.1
    986 # http://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml
    987 
    988 include <uapi/linux/icmp.h>
    989 
    990 icmp_ipv4_header {
    991 	ihl		bytesize4[parent, int8:4]
    992 	version		const[4, int8:4]
    993 	ecn		int8:2
    994 	dscp		int8:6
    995 	total_len	int16be
    996 	id		icmp_id
    997 	frag_off	int16be
    998 	ttl		int8
    999 	protocol	flags[ipv4_types, int8]
   1000 	csum		int16be
   1001 	src_ip		ipv4_addr
   1002 	dst_ip		ipv4_addr
   1003 	options		ipv4_options
   1004 } [packed]
   1005 
   1006 icmp_echo_reply_packet {
   1007 	type	const[ICMP_ECHOREPLY, int8]
   1008 	code	const[0, int8]
   1009 	csum	csum[parent, inet, int16be]
   1010 	id	icmp_id
   1011 	seq_num	int16be
   1012 	data	array[int8]
   1013 } [packed]
   1014 
   1015 type icmp_id int16be[100:104]
   1016 
   1017 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
   1018 
   1019 icmp_dest_unreach_packet {
   1020 	type	const[ICMP_DEST_UNREACH, int8]
   1021 	code	flags[icmp_dest_unreach_codes, int8]
   1022 	csum	csum[parent, inet, int16be]
   1023 	unused	const[0, int8]
   1024 	length	int8
   1025 	mtu	int16be
   1026 	iph	icmp_ipv4_header
   1027 	data	array[int8, 0:8]
   1028 } [packed]
   1029 
   1030 icmp_source_quench_packet {
   1031 	type	const[ICMP_SOURCE_QUENCH, int8]
   1032 	code	const[0, int8]
   1033 	csum	csum[parent, inet, int16be]
   1034 	unused	const[0, int32]
   1035 	iph	icmp_ipv4_header
   1036 	data	array[int8, 0:8]
   1037 } [packed]
   1038 
   1039 icmp_redirect_codes = ICMP_REDIR_NET, ICMP_REDIR_HOST, ICMP_REDIR_NETTOS, ICMP_REDIR_HOSTTOS
   1040 
   1041 icmp_redirect_packet {
   1042 	type	const[ICMP_REDIRECT, int8]
   1043 	code	flags[icmp_redirect_codes, int8]
   1044 	csum	csum[parent, inet, int16be]
   1045 	ip	ipv4_addr
   1046 	iph	icmp_ipv4_header
   1047 	data	array[int8, 0:8]
   1048 } [packed]
   1049 
   1050 icmp_echo_packet {
   1051 	type	const[ICMP_ECHO, int8]
   1052 	code	const[0, int8]
   1053 	csum	csum[parent, inet, int16be]
   1054 	id	int16be
   1055 	seq_num	int16be
   1056 	data	array[int8]
   1057 } [packed]
   1058 
   1059 icmp_time_exceeded_codes = ICMP_EXC_TTL, ICMP_EXC_FRAGTIME
   1060 
   1061 icmp_time_exceeded_packet {
   1062 	type	const[ICMP_TIME_EXCEEDED, int8]
   1063 	code	flags[icmp_time_exceeded_codes, int8]
   1064 	csum	csum[parent, inet, int16be]
   1065 	unused1	const[0, int8]
   1066 	length	int8
   1067 	unused2	const[0, int16]
   1068 	iph	icmp_ipv4_header
   1069 	data	array[int8, 0:8]
   1070 } [packed]
   1071 
   1072 icmp_parameter_prob_packet {
   1073 	type	const[ICMP_PARAMETERPROB, int8]
   1074 	code	const[0, int8]
   1075 	csum	csum[parent, inet, int16be]
   1076 	pointer	int8
   1077 	length	int8
   1078 	unused	const[0, int16]
   1079 	iph	icmp_ipv4_header
   1080 	data	array[int8, 0:8]
   1081 } [packed]
   1082 
   1083 icmp_timestamp_packet {
   1084 	type		const[ICMP_TIMESTAMP, int8]
   1085 	code		const[0, int8]
   1086 	csum		csum[parent, inet, int16be]
   1087 	id		int16be
   1088 	seq_num		int16be
   1089 	orig_ts		int32be
   1090 	recv_ts		int32be
   1091 	trans_ts	int32be
   1092 } [packed]
   1093 
   1094 icmp_timestamp_reply_packet {
   1095 	type		const[ICMP_TIMESTAMPREPLY, int8]
   1096 	code		const[0, int8]
   1097 	csum		csum[parent, inet, int16be]
   1098 	id		int16be
   1099 	seq_num		int16be
   1100 	orig_ts		int32be
   1101 	recv_ts		int32be
   1102 	trans_ts	int32be
   1103 } [packed]
   1104 
   1105 icmp_info_request_packet {
   1106 	type	const[ICMP_INFO_REQUEST, int8]
   1107 	code	const[0, int8]
   1108 	csum	csum[parent, inet, int16be]
   1109 	id	int16be
   1110 	seq_num	int16be
   1111 } [packed]
   1112 
   1113 icmp_info_reply_packet {
   1114 	type	const[ICMP_INFO_REPLY, int8]
   1115 	code	const[0, int8]
   1116 	csum	csum[parent, inet, int16be]
   1117 	id	int16be
   1118 	seq_num	int16be
   1119 } [packed]
   1120 
   1121 icmp_address_request_packet {
   1122 	type	const[ICMP_ADDRESS, int8]
   1123 	code	const[0, int8]
   1124 	csum	csum[parent, inet, int16be]
   1125 	mask	int32be
   1126 } [packed]
   1127 
   1128 icmp_address_reply_packet {
   1129 	type	const[ICMP_ADDRESSREPLY, int8]
   1130 	code	const[0, int8]
   1131 	csum	csum[parent, inet, int16be]
   1132 	mask	int32be
   1133 } [packed]
   1134 
   1135 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
   1136 
   1137 icmp_packet [
   1138 	echo_reply	icmp_echo_reply_packet
   1139 	dest_unreach	icmp_dest_unreach_packet
   1140 	source_quench	icmp_source_quench_packet
   1141 	redirect	icmp_redirect_packet
   1142 	echo		icmp_echo_packet
   1143 	time_exceeded	icmp_time_exceeded_packet
   1144 	parameter_prob	icmp_parameter_prob_packet
   1145 	timestamp	icmp_timestamp_packet
   1146 	timestamp_reply	icmp_timestamp_reply_packet
   1147 	info_request	icmp_info_request_packet
   1148 	info_reply	icmp_info_reply_packet
   1149 	address_request	icmp_address_request_packet
   1150 	address_reply	icmp_address_reply_packet
   1151 ] [varlen]
   1152 
   1153 ################################################################################
   1154 ##################################### ICMPv6 ###################################
   1155 ################################################################################
   1156 
   1157 # https://tools.ietf.org/html/rfc4443
   1158 # http://www.iana.org/assignments/icmpv6-parameters/icmpv6-parameters.xhtml
   1159 
   1160 include <uapi/linux/icmpv6.h>
   1161 
   1162 icmpv6_ipv6_packet {
   1163 	priority	int8:4
   1164 	version		const[6, int8:4]
   1165 	flow_label	array[int8, 3]
   1166 	length		int16be
   1167 	next_header	flags[ipv6_types, int8]
   1168 	hop_limit	int8
   1169 	src_ip		ipv6_addr
   1170 	dst_ip		ipv6_addr
   1171 	ext_headers	array[ipv6_ext_header]
   1172 	data		array[int8]
   1173 } [packed]
   1174 
   1175 icmpv6_dest_unreach_codes = ICMPV6_NOROUTE, ICMPV6_ADM_PROHIBITED, ICMPV6_NOT_NEIGHBOUR, ICMPV6_ADDR_UNREACH, ICMPV6_PORT_UNREACH, ICMPV6_POLICY_FAIL, ICMPV6_REJECT_ROUTE
   1176 
   1177 icmpv6_dest_unreach_packet {
   1178 	type	const[ICMPV6_DEST_UNREACH, int8]
   1179 	code	flags[icmpv6_dest_unreach_codes, int8]
   1180 	csum	csum[parent, pseudo, IPPROTO_ICMPV6, int16be]
   1181 	length	int8
   1182 	unused	array[const[0, int8], 3]
   1183 	packet	icmpv6_ipv6_packet
   1184 } [packed]
   1185 
   1186 icmpv6_pkt_toobig_packet {
   1187 	type	const[ICMPV6_PKT_TOOBIG, int8]
   1188 	code	const[0, int8]
   1189 	csum	csum[parent, pseudo, IPPROTO_ICMPV6, int16be]
   1190 	mtu	int32be
   1191 	packet	icmpv6_ipv6_packet
   1192 } [packed]
   1193 
   1194 icmpv6_time_exceed_codes = ICMPV6_EXC_HOPLIMIT, ICMPV6_EXC_FRAGTIME
   1195 
   1196 icmpv6_time_exceed_packet {
   1197 	type	const[ICMPV6_TIME_EXCEED, int8]
   1198 	code	flags[icmpv6_time_exceed_codes, int8]
   1199 	csum	csum[parent, pseudo, IPPROTO_ICMPV6, int16be]
   1200 	length	int8
   1201 	unused	array[const[0, int8], 3]
   1202 	packet	icmpv6_ipv6_packet
   1203 } [packed]
   1204 
   1205 icmpv6_param_prob_codes = ICMPV6_HDR_FIELD, ICMPV6_UNK_NEXTHDR, ICMPV6_UNK_OPTION
   1206 
   1207 icmpv6_param_prob_packet {
   1208 	type	const[ICMPV6_PARAMPROB, int8]
   1209 	code	flags[icmpv6_param_prob_codes, int8]
   1210 	csum	csum[parent, pseudo, IPPROTO_ICMPV6, int16be]
   1211 	pointer	int32be
   1212 	packet	icmpv6_ipv6_packet
   1213 } [packed]
   1214 
   1215 icmpv6_echo_request_packet {
   1216 	type	const[ICMPV6_ECHO_REQUEST, int8]
   1217 	code	const[0, int8]
   1218 	csum	csum[parent, pseudo, IPPROTO_ICMPV6, int16be]
   1219 	id	int16be
   1220 	seq_num	int16be
   1221 	data	array[int8]
   1222 } [packed]
   1223 
   1224 icmpv6_echo_reply_packet {
   1225 	type	const[ICMPV6_ECHO_REPLY, int8]
   1226 	code	const[0, int8]
   1227 	csum	csum[parent, pseudo, IPPROTO_ICMPV6, int16be]
   1228 	id	int16be
   1229 	seq_num	int16be
   1230 	data	array[int8]
   1231 } [packed]
   1232 
   1233 icmpv6_mld_types = ICMPV6_MGM_QUERY, ICMPV6_MGM_REPORT, ICMPV6_MGM_REDUCTION
   1234 
   1235 # https://tools.ietf.org/html/rfc2710#section-3
   1236 icmpv6_mld_packet {
   1237 	type	flags[icmpv6_mld_types, int8]
   1238 	code	const[0, int8]
   1239 	csum	csum[parent, pseudo, IPPROTO_ICMPV6, int16be]
   1240 	mrd	int16be
   1241 	unused	int16
   1242 	addr	ipv6_addr
   1243 } [packed]
   1244 
   1245 icmpv6_ni_types = ICMPV6_NI_QUERY, ICMPV6_NI_REPLY
   1246 
   1247 # https://tools.ietf.org/html/rfc4620#section-4
   1248 icmpv6_ni_packet {
   1249 	type	flags[icmpv6_ni_types, int8]
   1250 	code	const[0, int8]
   1251 	csum	csum[parent, pseudo, IPPROTO_ICMPV6, int16be]
   1252 	qtype	int16be
   1253 	flags	int16be
   1254 	nonce	int64be
   1255 	data	array[int8]
   1256 } [packed]
   1257 
   1258 icmpv6_packet [
   1259 	dest_unreach	icmpv6_dest_unreach_packet
   1260 	pkt_toobig	icmpv6_pkt_toobig_packet
   1261 	time_exceed	icmpv6_time_exceed_packet
   1262 	param_prob	icmpv6_param_prob_packet
   1263 	echo_request	icmpv6_echo_request_packet
   1264 	echo_reply	icmpv6_echo_reply_packet
   1265 	mld		icmpv6_mld_packet
   1266 	ni		icmpv6_ni_packet
   1267 # TODO: ICMPV6_MLD2_REPORT
   1268 # TODO: ICMPV6_DHAAD_REQUEST, ICMPV6_DHAAD_REPLY, ICMPV6_MOBILE_PREFIX_SOL, ICMPV6_MOBILE_PREFIX_ADV (with ipv6 ext headers)
   1269 ] [varlen]
   1270 
   1271 ################################################################################
   1272 ###################################### DCCP ####################################
   1273 ################################################################################
   1274 
   1275 # https://tools.ietf.org/html/rfc4340#section-5
   1276 
   1277 include <uapi/linux/dccp.h>
   1278 
   1279 # TODO: describe each type
   1280 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
   1281 
   1282 dccp_header {
   1283 	src_port	sock_port
   1284 	dst_port	sock_port
   1285 	offset		bytesize4[parent, int8]
   1286 	cscov		const[1, int8:4]
   1287 # TODO: cscov might have other values, affects checksummed data
   1288 	ccval		int8:4
   1289 	csum		csum[parent, pseudo, IPPROTO_DCCP, int16be]
   1290 	x		const[0, int8:1]
   1291 	type		flags[dccp_types, int8:4]
   1292 	reserved1	int8:3
   1293 	seq_num		array[int8, 3]
   1294 	reserved2	int8
   1295 	ack_num		array[int8, 3]
   1296 # TODO: seq_num and ack_num might have different size depending on x
   1297 # TODO: options
   1298 } [packed]
   1299 
   1300 dccp_packet {
   1301 	header	dccp_header
   1302 	payload	array[int8]
   1303 } [packed]
   1304 
   1305 ################################################################################
   1306 ###################################### IGMP ####################################
   1307 ################################################################################
   1308 
   1309 # https://tools.ietf.org/html/rfc2236
   1310 # https://tools.ietf.org/html/rfc3376#section-4
   1311 
   1312 include <uapi/linux/igmp.h>
   1313 
   1314 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
   1315 
   1316 igmp_packet {
   1317 	type	flags[igmp_types, int8]
   1318 	mrtime	int8
   1319 	csum	csum[parent, inet, int16be]
   1320 	addr	ipv4_addr
   1321 	data	array[int8]
   1322 } [packed]
   1323 
   1324 # TODO: describe particular IGMP packets
   1325 # TODO: open IGMP sockets from userspace
   1326 
   1327 ################################################################################
   1328 ###################################### MPLS ####################################
   1329 ################################################################################
   1330 
   1331 # https://en.wikipedia.org/wiki/Multiprotocol_Label_Switching
   1332 
   1333 mpls_packet {
   1334 	labels	array[mpls_label]
   1335 	payload	mpls_payload
   1336 } [packed]
   1337 
   1338 # TODO: is it this ordering or reverse?
   1339 mpls_label {
   1340 	ttl	int32be:8
   1341 	s	int32be:1
   1342 	tc	int32be:3
   1343 	label	int32be:20
   1344 }
   1345 
   1346 mpls_payload [
   1347 	generic	array[int8]
   1348 	ipv4	ipv4_packet
   1349 	ipv6	ipv6_packet
   1350 	llc	llc_packet
   1351 ] [varlen]
   1352