aboutsummaryrefslogtreecommitdiffstats
path: root/sys/linux/socket.txt
blob: 0654d577d315994949c7b36d4ebbd9d51243f4d4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
# 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 <asm/ioctls.h>
include <linux/if_tun.h>
include <linux/if_bridge.h>
include <linux/net.h>
include <linux/net_tstamp.h>
include <linux/route.h>
include <linux/socket.h>
include <uapi/linux/in.h>
include <uapi/linux/ethtool.h>
include <uapi/linux/if_ether.h>

resource sock[fd]
type sock_port int16be[20000:20004]

# TODO: describe socketcall syscall

socket(domain flags[socket_domain], type flags[socket_type], proto int8) sock
socketpair(domain flags[socket_domain], type flags[socket_type], proto int8, fds ptr[out, sock_pair])
bind(fd sock, addr ptr[in, sockaddr_storage], addrlen len[addr])
connect(fd sock, addr ptr[in, sockaddr_storage], addrlen len[addr])
accept(fd sock, peer ptr[out, sockaddr_storage, opt], peerlen ptr[inout, len[peer, int32]]) sock
accept4(fd sock, peer ptr[out, sockaddr_storage, opt], peerlen ptr[inout, len[peer, int32]], flags flags[accept_flags]) sock
sendto(fd sock, buf buffer[in], len len[buf], f flags[send_flags], addr ptr[in, sockaddr_storage, opt], addrlen len[addr])
recvfrom(fd sock, buf buffer[out], len len[buf], f flags[recv_flags], addr ptr[in, sockaddr_storage, opt], addrlen len[addr])
getsockname(fd sock, addr ptr[out, sockaddr_storage], addrlen ptr[inout, len[addr, int32]])
getpeername(fd sock, peer ptr[out, sockaddr_storage], peerlen ptr[inout, len[peer, int32]])

sendmsg(fd sock, msg ptr[in, send_msghdr], f flags[send_flags])
sendmmsg(fd sock, mmsg ptr[in, array[send_mmsghdr]], vlen len[mmsg], f flags[send_flags])
recvmsg(fd sock, msg ptr[inout, recv_msghdr], f flags[recv_flags])
recvmmsg(fd sock, mmsg ptr[in, array[recv_mmsghdr]], vlen len[mmsg], f flags[recv_flags], timeout ptr[in, timespec, opt])

listen(fd sock, backlog int32)
shutdown(fd sock, how flags[shutdown_flags])

getsockopt(fd sock, level int32, optname int32, optval buffer[out], optlen ptr[inout, len[optval, int32]])
setsockopt(fd sock, level int32, optname int32, optval buffer[in], optlen len[optval])

socket_domain = AF_UNIX, AF_INET, AF_INET6, AF_IPX, AF_NETLINK, AF_X25, AF_AX25, AF_ATMPVC, AF_APPLETALK, AF_PACKET
socket_type = SOCK_STREAM, SOCK_DGRAM, SOCK_RAW, SOCK_RDM, SOCK_SEQPACKET, SOCK_DCCP, SOCK_PACKET, SOCK_NONBLOCK, SOCK_CLOEXEC
accept_flags = SOCK_NONBLOCK, SOCK_CLOEXEC
shutdown_flags = SHUT_RD, SHUT_WR
send_flags = MSG_CONFIRM, MSG_DONTROUTE, MSG_DONTWAIT, MSG_EOR, MSG_MORE, MSG_NOSIGNAL, MSG_OOB, MSG_PROBE, MSG_BATCH, MSG_FASTOPEN, MSG_ZEROCOPY
recv_flags = MSG_CMSG_CLOEXEC, MSG_DONTWAIT, MSG_ERRQUEUE, MSG_OOB, MSG_PEEK, MSG_TRUNC, MSG_WAITALL, MSG_WAITFORONE
cmsg_levels = SOL_SOCKET, IPPROTO_ICMP, SOL_IP, SOL_TCP, SOL_UDP, SOL_IPV6, SOL_ICMPV6, SOL_SCTP, SOL_UDPLITE, SOL_RAW, SOL_IPX, SOL_AX25, SOL_ATALK, SOL_NETROM, SOL_ROSE, SOL_DECNET, SOL_PACKET, SOL_ATM, SOL_AAL, SOL_IRDA, SOL_NETBEUI, SOL_LLC, SOL_DCCP, SOL_NETLINK, SOL_TIPC, SOL_RXRPC, SOL_PPPOL2TP, SOL_BLUETOOTH, SOL_PNPIPE, SOL_RDS, SOL_IUCV, SOL_CAIF, SOL_ALG, SOL_NFC, SOL_KCM

sock_pair {
	fd0	sock
	fd1	sock
}

# This sockaddr type corresponds to the struct sockaddr and is 16 bytes or less.
# TODO: add AF_APPLETALK, AF_ATMPVC, AF_X25, AF_ROSE, AF_DECnet, AF_ATMSVC, AF_IRDA, AF_IB, AF_TIPC, AF_IUCV, AF_RXRPC, AF_ISDN, AF_PHONET, AF_IEEE802154, AF_CAIF, AF_QIPCRTR
# Note: AF_UNIX, AF_INET6, AF_PACKET, AF_ALG, AF_PPPOX sockaddr is bigger than 16 bytes
# Note: AF_NETROM sockaddr is the same as AF_AX25
sockaddr [
	in		sockaddr_in
	ax25		sockaddr_ax25
	ipx		sockaddr_ipx
	nl		sockaddr_nl
	llc		sockaddr_llc
	can		sockaddr_can
	sco		sockaddr_sco
	l2		sockaddr_l2
	hci		sockaddr_hci
	rc		sockaddr_rc
	nfc		sockaddr_nfc
	vsock		sockaddr_vm
	xdp		sockaddr_xdp
	tipc		sockaddr_tipc
	ethernet	sockaddr_ethernet
	generic		sockaddr_generic
] [size[SOCKADDR_SIZE]]

# This sockaddr type corresponds to the sockaddr_storage type and is 128 bytes size.
sockaddr_storage [
	un		sockaddr_un
	in		sockaddr_in
	x25		sockaddr_x25
	ax25		full_sockaddr_ax25
	ipx		sockaddr_ipx
	in6		sockaddr_in6
	nl		sockaddr_nl
	ll		sockaddr_ll
	pppoe		sockaddr_pppoe
	pppol2tp	sockaddr_pppol2tp
	pppol2tpin6	sockaddr_pppol2tpin6
	pppol2tpv3	sockaddr_pppol2tpv3
	pppol2tpv3in6	sockaddr_pppol2tpv3in6
	pptp		sockaddr_pptp
	llc		sockaddr_llc
	can		sockaddr_can
	sco		sockaddr_sco
	l2		sockaddr_l2
	hci		sockaddr_hci
	rc		sockaddr_rc
	alg		sockaddr_alg
	nfc		sockaddr_nfc
	nfc_llcp	sockaddr_nfc_llcp
	vsock		sockaddr_vm
	xdp		sockaddr_xdp
	tipc		sockaddr_tipc
	caif		sockaddr_caif
	ethernet	sockaddr_ethernet
	generic		sockaddr_storage_generic
] [size[SOCKADDR_STORAGE_SIZE]]

define SOCKADDR_SIZE	sizeof(struct sockaddr)
define SOCKADDR_STORAGE_SIZE	sizeof(struct sockaddr_storage)

sockaddr_generic {
	sa_family	flags[socket_domain, int16]
	sa_data		array[int8, 14]
}

sockaddr_storage_generic {
	sa_family	flags[socket_domain, int16]
	sa_data		array[int8, 126]
}

send_msghdr {
	msg_name	ptr[in, sockaddr_storage, opt]
	msg_namelen	len[msg_name, int32]
	msg_iov		ptr[in, array[iovec_in]]
	msg_iovlen	len[msg_iov, intptr]
	msg_control	ptr[in, array[cmsghdr], opt]
	msg_controllen	bytesize[msg_control, intptr]
	msg_flags	const[0, int32]
}

send_mmsghdr {
	msg_hdr	send_msghdr
	msg_len	int32
}

recv_msghdr {
	msg_name	ptr[out, sockaddr_storage, opt]
	msg_namelen	len[msg_name, int32]
	msg_iov		ptr[in, array[iovec_out]]
	msg_iovlen	len[msg_iov, intptr]
	msg_control	ptr[out, array[int8], opt]
	msg_controllen	bytesize[msg_control, intptr]
	msg_flags	const[0, int32]
}

recv_mmsghdr {
	msg_hdr	recv_msghdr
	msg_len	int32
}

cmsghdr {
	cmsg_len	len[parent, intptr]
	cmsg_level	flags[cmsg_levels, int32]
	cmsg_type	int32
	data		array[int8]
} [align_ptr]

# Socket options

# http://lxr.free-electrons.com/source/include/uapi/asm-generic/socket.h

setsockopt$sock_void(fd sock, level const[SOL_SOCKET], optname flags[sockopt_opt_sock_void], optval const[0], optlen const[0])
getsockopt$sock_int(fd sock, level const[SOL_SOCKET], optname flags[sockopt_opt_sock_int], optval ptr[out, int32], optlen ptr[inout, len[optval, int32]])
setsockopt$sock_int(fd sock, level const[SOL_SOCKET], optname flags[sockopt_opt_sock_int], optval ptr[in, int32], optlen len[optval])
getsockopt$sock_linger(fd sock, level const[SOL_SOCKET], optname const[SO_LINGER], optval ptr[out, linger], optlen ptr[inout, len[optval, int32]])
setsockopt$sock_linger(fd sock, level const[SOL_SOCKET], optname const[SO_LINGER], optval ptr[in, linger], optlen len[optval])
getsockopt$sock_cred(fd sock, level const[SOL_SOCKET], optname const[SO_PEERCRED], optval ptr[out, ucred], optlen ptr[inout, len[optval, int32]])
setsockopt$sock_cred(fd sock, level const[SOL_SOCKET], optname const[SO_PEERCRED], optval ptr[in, ucred], optlen len[optval])
getsockopt$sock_timeval(fd sock, level const[SOL_SOCKET], optname flags[sockopt_opt_sock_timeval], optval ptr[out, timeval], optlen ptr[inout, len[optval, int32]])
setsockopt$sock_timeval(fd sock, level const[SOL_SOCKET], optname flags[sockopt_opt_sock_timeval], optval ptr[in, timeval], optlen len[optval])
setsockopt$sock_attach_bpf(fd sock, level const[SOL_SOCKET], optname const[SO_ATTACH_BPF], optval ptr[in, fd_bpf_prog], optlen len[optval])
setsockopt$SO_TIMESTAMPING(fd sock, level const[SOL_SOCKET], optname const[SO_TIMESTAMPING], optval ptr[in, flags[sockopt_so_timestamping, int32]], optlen len[optval])
getsockopt$SO_TIMESTAMPING(fd sock, level const[SOL_SOCKET], optname const[SO_TIMESTAMPING], optval ptr[out, int32], optlen ptr[inout, len[optval, int32]])
setsockopt$SO_ATTACH_FILTER(fd sock, level const[SOL_SOCKET], optname const[SO_ATTACH_FILTER], optval ptr[in, sock_fprog], optlen len[optval])
setsockopt$SO_BINDTODEVICE(fd sock, level const[SOL_SOCKET], optname const[SO_BINDTODEVICE], optval ptr[in, devname], optlen len[optval])
getsockopt$SO_BINDTODEVICE(fd sock, level const[SOL_SOCKET], optname const[SO_BINDTODEVICE], optval ptr[out, devname], optlen len[optval])
getsockopt$sock_buf(fd sock, level const[SOL_SOCKET], optname flags[sockopt_opt_sock_buf], optval buffer[out], optlen ptr[inout, len[optval, int32]])
getsockopt$SO_COOKIE(fd sock, level const[SOL_SOCKET], optname const[SO_COOKIE], optval ptr[out, int64], optlen ptr[inout, len[optval, int32]])

linger {
	onoff	bool32
	linger	int32
}

sockopt_opt_sock_void = SO_DETACH_FILTER, SO_MARK
sockopt_opt_sock_int = SO_ACCEPTCONN, SO_BROADCAST, SO_DEBUG, SO_DOMAIN, SO_ERROR, SO_DONTROUTE, SO_KEEPALIVE, SO_PEEK_OFF, SO_PRIORITY, SO_PROTOCOL, SO_RCVBUF, SO_RCVBUFFORCE, SO_RCVLOWAT, SO_SNDLOWAT, SO_REUSEADDR, SO_SNDBUF, SO_SNDBUFFORCE, SO_TIMESTAMP, SO_TYPE, SO_REUSEPORT, SO_OOBINLINE, SO_NO_CHECK, SO_PASSCRED, SO_TIMESTAMPNS, SO_LOCK_FILTER, SO_PASSSEC, SO_RXQ_OVFL, SO_WIFI_STATUS, SO_NOFCS, SO_SELECT_ERR_QUEUE, SO_BUSY_POLL, SO_MAX_PACING_RATE, SO_ZEROCOPY
sockopt_opt_sock_timeval = SO_RCVTIMEO, SO_SNDTIMEO
sockopt_opt_sock_buf = SO_PEERNAME, SO_PEERSEC, SO_GET_FILTER, SO_MEMINFO, SO_PEERGROUPS, SO_TXTIME
sockopt_so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE, SOF_TIMESTAMPING_TX_SOFTWARE, SOF_TIMESTAMPING_RX_HARDWARE, SOF_TIMESTAMPING_RX_SOFTWARE, SOF_TIMESTAMPING_SOFTWARE, SOF_TIMESTAMPING_SYS_HARDWARE, SOF_TIMESTAMPING_RAW_HARDWARE, SOF_TIMESTAMPING_OPT_ID, SOF_TIMESTAMPING_TX_SCHED, SOF_TIMESTAMPING_TX_ACK, SOF_TIMESTAMPING_OPT_CMSG, SOF_TIMESTAMPING_OPT_TSONLY

# Socket ioctls

# Since some socket ioctls are forwarded to the network device, adding device ioctls here as well.

# http://lxr.free-electrons.com/source/include/uapi/linux/sockios.h

# http://lxr.free-electrons.com/source/include/uapi/asm-generic/sockios.h

# TODO: add SIOCADDRT, SIOCDELRT, SIOCRTMSG, SIOCDRARP, SIOCGRARP, SIOCSRARP, SIOCGIFVLAN, SIOCSIFVLAN

ioctl$sock_SIOCETHTOOL(fd sock, cmd const[SIOCETHTOOL], arg ptr[inout, ifreq_t[ptr[inout, ethtool_cmd_u]]])

ioctl$sock_SIOCOUTQ(fd sock, cmd const[SIOCOUTQ], arg ptr[out, int32])
ioctl$sock_SIOCINQ(fd sock, cmd const[SIOCINQ], arg ptr[out, int32])

ioctl$sock_SIOCGIFCONF(fd sock, cmd const[SIOCGIFCONF], arg ptr[inout, ifconf])

ifreq_ioctls = SIOCGIFNAME, SIOCSIFLINK, SIOCGIFFLAGS, SIOCSIFFLAGS, SIOCGIFADDR, SIOCSIFADDR, SIOCGIFDSTADDR, SIOCSIFDSTADDR, SIOCGIFBRDADDR, SIOCSIFBRDADDR, SIOCGIFNETMASK, SIOCSIFNETMASK, SIOCGIFMETRIC, SIOCSIFMETRIC, SIOCGIFMEM, SIOCSIFMEM, SIOCGIFMTU, SIOCSIFMTU, SIOCSIFNAME, SIOCSIFHWADDR, SIOCGIFENCAP, SIOCSIFENCAP, SIOCGIFHWADDR, SIOCGIFSLAVE, SIOCSIFSLAVE, SIOCADDMULTI, SIOCDELMULTI, SIOCGIFINDEX, SIOCSIFPFLAGS, SIOCGIFPFLAGS, SIOCDIFADDR, SIOCSIFHWBROADCAST, SIOCGIFCOUNT, SIOCGIFTXQLEN, SIOCSIFTXQLEN, SIOCETHTOOL, SIOCGMIIPHY, SIOCGMIIREG, SIOCSMIIREG, SIOCWANDEV, SIOCGIFMAP, SIOCSIFMAP, SIOCBONDENSLAVE, SIOCBONDRELEASE, SIOCBONDSETHWADDR, SIOCBONDSLAVEINFOQUERY, SIOCBONDINFOQUERY, SIOCBONDCHANGEACTIVE, SIOCBRADDIF, SIOCBRDELIF, SIOCSHWTSTAMP, SIOCGHWTSTAMP

ioctl$sock_ifreq(fd sock, cmd flags[ifreq_ioctls], arg ptr[inout, ifreq])

ioctl$sock_SIOCGIFINDEX(fd sock, cmd const[SIOCGIFINDEX], arg ptr[inout, ifreq_t[ifindex]])

ioctl$sock_SIOCGIFBR(fd sock, cmd const[SIOCGIFBR], arg ptr[inout, brctl_arg])
ioctl$sock_SIOCSIFBR(fd sock, cmd const[SIOCSIFBR], arg ptr[inout, brctl_arg])

ioctl$sock_SIOCOUTQNSD(fd sock, cmd const[SIOCOUTQNSD], arg ptr[out, int32])

ioctl$sock_SIOCGSKNS(fd sock, cmd const[SIOCGSKNS], arg ptr[inout, int32])

ioctl$sock_SIOCADDDLCI(fd sock, cmd const[SIOCADDDLCI], arg ptr[inout, dlci_add])
ioctl$sock_SIOCDELDLCI(fd sock, cmd const[SIOCDELDLCI], arg ptr[in, dlci_add])

ioctl$sock_SIOCBRADDBR(fd sock, cmd const[SIOCBRADDBR], arg ptr[in, devname])
ioctl$sock_SIOCBRDELBR(fd sock, cmd const[SIOCBRDELBR], arg ptr[in, devname])

define SIOCDEVPRIVATE_BEG	(SIOCDEVPRIVATE)
define SIOCDEVPRIVATE_END	(SIOCDEVPRIVATE + 15)

define SIOCPROTOPRIVATE_BEG	(SIOCPROTOPRIVATE)
define SIOCPROTOPRIVATE_END	(SIOCPROTOPRIVATE + 15)

ioctl$sock_netdev_private(fd sock, cmd int16[SIOCDEVPRIVATE_BEG:SIOCDEVPRIVATE_END], arg ptr[in, array[int8]])
ioctl$sock_proto_private(fd sock, cmd int16[SIOCPROTOPRIVATE_BEG:SIOCPROTOPRIVATE_END], arg ptr[in, array[int8]])

ioctl$sock_FIOSETOWN(fd sock, cmd const[FIOSETOWN], arg ptr[in, pid])
ioctl$sock_SIOCSPGRP(fd sock, cmd const[SIOCSPGRP], arg ptr[in, pid])

ioctl$sock_FIOGETOWN(fd sock, cmd const[FIOGETOWN], arg ptr[out, pid])
ioctl$sock_SIOCGPGRP(fd sock, cmd const[SIOCGPGRP], arg ptr[out, pid])

ioctl$sock_TIOCOUTQ(fd sock, cmd const[TIOCOUTQ], arg ptr[out, int32])
ioctl$sock_TIOCINQ(fd sock, cmd const[TIOCINQ], arg ptr[out, int32])
ioctl$SIOCGSTAMP(fd sock, cmd const[SIOCGSTAMP], arg ptr[out, timeval])
ioctl$SIOCGSTAMPNS(fd sock, cmd const[SIOCGSTAMPNS], arg ptr[out, timespec])

resource ifindex[int32]

type ifreq_dev_t[DEVNAME, ELEM] {
	ifr_ifrn	string[DEVNAME, IFNAMSIZ]
	elem		ELEM
} [size[IFREQ_SIZE]]

type ifreq_t[ELEM] ifreq_dev_t[devnames, ELEM]

type ifreq ifreq_t[ifr_ifru]

ifr_ifru [
	ifru_addrs	sockaddr
	ifru_hwaddr	mac_addr
	ifru_flags	flags[ifru_flags, int16]
	ifru_ivalue	int32
	ifru_mtu	int32
	ifru_map	ifmap
	ifru_names	devname
	ifru_data	ptr[in, array[int8, 32]]
	ifru_settings	if_settings
]

define IFREQ_SIZE	sizeof(struct ifreq)

# We could add "eth0" to this list as well, but this will affect the connection
# between fuzzer and manager and produce lots of "no output" crashes
# (actually, this is not true now since all testing is done in a separate
# network namespace, but we still don't mess with eth0).
# Note: lapb0, bpq0 and hwsim0 are only present in init namespace.
# Note: for roseN, nrN and netdevsimN we should use proc type, but for simplicity we currently use N=0.
devnames = "", "lo", "tunl0", "gre0", "gretap0", "ip_vti0", "ip6_vti0", "sit0", "ip6tnl0", "ip6gre0", "ip6gretap0", "bond0", "dummy0", "eql", "ifb0", "ipddp0", "yam0", "bcsf0", "bcsh0", "teql0", "nr0", "rose0", "irlan0", "erspan0", "bpq0", "vlan0", "bridge0", "vcan0", "team0", "syz_tun", "veth0", "veth1", "veth0_to_bridge", "veth1_to_bridge", "veth0_to_bond", "veth1_to_bond", "veth0_to_team", "veth1_to_team", "bridge_slave_0", "bridge_slave_1", "bond_slave_0", "bond_slave_1", "team_slave_0", "team_slave_1", "syzkaller0", "syzkaller1", "lapb0", "hwsim0", "rose0", "nr0", "veth0_to_hsr", "veth1_to_hsr", "hsr0", "ip6erspan0", "nlmon0", "vxcan1", "caif0", "batadv0", "netdevsim0"

type devname string[devnames, IFNAMSIZ]

devname_mask {
	lo	flags[devname_mask_values, int8]
} [size[IFNAMSIZ]]

devname_mask_values = 0, 0xff

ifru_flags = IFF_TUN, IFF_TAP, IFF_NO_PI, IFF_ONE_QUEUE, IFF_VNET_HDR, IFF_TUN_EXCL, IFF_MULTI_QUEUE, IFF_ATTACH_QUEUE, IFF_DETACH_QUEUE, IFF_PERSIST, IFF_NOFILTER

ifmap {
	mem_start	intptr
	mem_end		intptr
	base_addr	int16
	irq		int8
	dma		int8
	port		int8
}

if_settings {
	type		int32
	size		int32
	ifs_ifsu	ifs_ifsu
}

ifs_ifsu [
	raw_hdlc	ptr[in, raw_hdlc_proto]
	cisco		ptr[in, cisco_proto]
	fr		ptr[in, fr_proto]
	fr_pvc		ptr[in, fr_proto_pvc]
	fr_pvc_info	ptr[in, fr_proto_pvc_info]
	sync		ptr[in, sync_serial_settings]
	te1		ptr[in, te1_settings]
]

raw_hdlc_proto {
	encode	int16
	parity	int16
}

cisco_proto {
	val	int32
	timeout	int32
}

fr_proto {
	t391	int32
	t392	int32
	n391	int32
	n392	int32
	n393	int32
	lmi	int16
	dce	int16
}

fr_proto_pvc {
	dlcl	int32
}

fr_proto_pvc_info {
	dlci	int32
	master	devname
}

sync_serial_settings {
	rate	int32
	type	int32
	loop	int16
}

te1_settings {
	rate	int32
	type	int32
	loop	int16
	slot	int32
}

ifconf [
	req	ifconf_req
	buf	ifconf_buf
]

ifconf_buf {
	ifc_len		len[ifcu_buf, int32]
	ifcu_buf	ptr[inout, array[int8], opt]
}

ifconf_req {
	ifc_len		len[ifcu_req, int32]
	ifcu_req	ptr[inout, ifreq, opt]
}

brctl_cmds = BRCTL_GET_VERSION, BRCTL_GET_BRIDGES, BRCTL_ADD_BRIDGE, BRCTL_DEL_BRIDGE

brctl_arg [
	get	brctl_arg_get
	add_del	brctl_arg_add_del
	generic	brctl_arg_generic
]

brctl_arg_get {
	cmd	const[BRCTL_GET_BRIDGES, int64]
	buf	ptr[out, array[int8]]
	indices	int64
}

brctl_arg_add_del {
	cmd	const[BRCTL_ADD_BRIDGE, int64]
	devname	ptr[in, devname]
	pad	const[0, int64]
}

brctl_arg_generic {
	a0	flags[brctl_cmds, int64]
	a1	int64
	a2	int64
}

dlci_add {
	devname	devname
	dlci	int16
}

# ETHTOOL declaration part
# http://elixir.free-electrons.com/linux/latest/source/include/uapi/linux/ethtool.h

ethtool_cmd_flags = ETHTOOL_GSET, ETHTOOL_SSET, ETHTOOL_GDRVINFO, ETHTOOL_GREGS, ETHTOOL_GWOL, ETHTOOL_SWOL, ETHTOOL_GMSGLVL, ETHTOOL_SMSGLVL, ETHTOOL_NWAY_RST, ETHTOOL_GLINK, ETHTOOL_GEEPROM, ETHTOOL_SEEPROM, ETHTOOL_GCOALESCE, ETHTOOL_SCOALESCE, ETHTOOL_GRINGPARAM, ETHTOOL_SRINGPARAM, ETHTOOL_GPAUSEPARAM, ETHTOOL_SPAUSEPARAM, ETHTOOL_GRXCSUM, ETHTOOL_SRXCSUM, ETHTOOL_GTXCSUM, ETHTOOL_STXCSUM, ETHTOOL_GSG, ETHTOOL_SSG, ETHTOOL_TEST, ETHTOOL_GSTRINGS, ETHTOOL_PHYS_ID, ETHTOOL_GSTATS, ETHTOOL_GTSO, ETHTOOL_STSO, ETHTOOL_GPERMADDR, ETHTOOL_GUFO, ETHTOOL_SUFO, ETHTOOL_GGSO, ETHTOOL_SGSO, ETHTOOL_GFLAGS, ETHTOOL_SFLAGS, ETHTOOL_GPFLAGS, ETHTOOL_SPFLAGS, ETHTOOL_GRXFH, ETHTOOL_SRXFH, ETHTOOL_GGRO, ETHTOOL_SGRO, ETHTOOL_GRXRINGS, ETHTOOL_GRXCLSRLCNT, ETHTOOL_GRXCLSRULE, ETHTOOL_GRXCLSRLALL, ETHTOOL_SRXCLSRLDEL, ETHTOOL_SRXCLSRLINS, ETHTOOL_FLASHDEV, ETHTOOL_RESET, ETHTOOL_SRXNTUPLE, ETHTOOL_GRXNTUPLE, ETHTOOL_GSSET_INFO, ETHTOOL_GRXFHINDIR, ETHTOOL_SRXFHINDIR, ETHTOOL_GFEATURES, ETHTOOL_SFEATURES, ETHTOOL_GCHANNELS, ETHTOOL_SCHANNELS, ETHTOOL_SET_DUMP, ETHTOOL_GET_DUMP_FLAG, ETHTOOL_GET_DUMP_DATA, ETHTOOL_GET_TS_INFO, ETHTOOL_GMODULEINFO, ETHTOOL_GMODULEEEPROM, ETHTOOL_GEEE, ETHTOOL_SEEE, ETHTOOL_GRSSH, ETHTOOL_SRSSH, ETHTOOL_GTUNABLE, ETHTOOL_STUNABLE, ETHTOOL_GPHYSTATS, ETHTOOL_PERQUEUE, ETHTOOL_GLINKSETTINGS, ETHTOOL_SLINKSETTINGS, ETHTOOL_PHY_GTUNABLE, ETHTOOL_PHY_STUNABLE

ethtool_cmd_u [
	ethtool_cmd		ethtool_cmd
	ethtool_drvinfo		ethtool_drvinfo
	ethtool_wolinfo		ethtool_wolinfo
	ethtool_regs		ethtool_regs
	ethtool_eeprom		ethtool_eeprom
	ethtool_eee		ethtool_eee
	ethtool_modinfo		ethtool_modinfo
	ethtool_coalesce	ethtool_coalesce
	ethtool_ringparam	ethtool_ringparam
	ethtool_channels	ethtool_channels
	ethtool_pauseparam	ethtool_pauseparam
	ethtool_gstrings	ethtool_gstrings
	ethtool_sset_info	ethtool_sset_info
	ethtool_test		ethtool_test
	ethtool_stats		ethtool_stats
	ethtool_perm_addr	ethtool_perm_addr
	ethtool_rxnfc		ethtool_rxnfc
	ethtool_rxfh_indir	ethtool_rxfh_indir
	ethtool_rxfh		ethtool_rxfh
	ethtool_rx_ntuple	ethtool_rx_ntuple
	ethtool_flash		ethtool_flash
	ethtool_dump		ethtool_dump
	ethtool_gfeatures	ethtool_gfeatures
	ethtool_sfeatures	ethtool_sfeatures
	ethtool_ts_info		ethtool_ts_info
	ethtool_per_queue_op	ethtool_per_queue_op
	ethtool_link_settings	ethtool_link_settings
] [varlen]

ethtool_cmd {
	cmd			flags[ethtool_cmd_flags, int32]
	supported		int32
	advertising		int32
	speed			int16
	duplex			int8
	port			int8
	phy_address		int8
	transceiver		int8
	autoneg			int8
	mdio_support		int8
	maxtxpkt		int32
	maxrxpkt		int32
	speed_hi		int16
	eth_tp_mdix		int8
	eth_tp_mdix_ctrl	int8
	lp_advertising		int32
	reserved		array[int32, 2]
}

ethtool_drvinfo {
	cmd		const[ETHTOOL_GDRVINFO, int32]
	driver		array[int8, 32]
	version		array[int8, 32]
	fw_version	array[int8, ETHTOOL_FWVERS_LEN]
	bus_info	array[int8, ETHTOOL_BUSINFO_LEN]
	erom_version	array[int8, ETHTOOL_EROMVERS_LEN]
	reserved2	array[int8, 12]
	n_priv_flags	int32
	n_stats		int32
	testinfo_len	int32
	eedump_len	int32
	regdump_len	int32
}

ethtool_wolinfo_cmd_flags = ETHTOOL_GWOL, ETHTOOL_SWOL

ethtool_wolinfo {
	cmd		flags[ethtool_wolinfo_cmd_flags, int32]
	supported	int32
	wolopts		int32
	sopass		array[int8, SOPASS_MAX]
}

ethtool_regs {
	cmd	const[ETHTOOL_GREGS, int32]
	version	int32
	len	len[data, int32]
	data	array[int8]
}

ethtool_eeprom_cmd_flags = ETHTOOL_GEEPROM, ETHTOOL_GMODULEEEPROM, ETHTOOL_SEEPROM

ethtool_eeprom {
	cmd	flags[ethtool_eeprom_cmd_flags, int32]
	magic	int32
	offset	int32
	len	len[data, int32]
	data	array[int8]
}

ethtool_eee_cmd_flags = ETHTOOL_GEEE, ETHTOOL_SEEE

ethtool_eee {
	cmd		flags[ethtool_eee_cmd_flags, int32]
	supported	int32
	advertised	int32
	lp_advertised	int32
	eee_active	int32
	eee_enabled	int32
	tx_lpi_enabled	int32
	tx_lpi_timer	int32
	reserved	array[int32, 2]
}

ethtool_modinfo {
	cmd		const[ETHTOOL_GMODULEINFO, int32]
	type		int32
	eeprom_len	int32
	reserved	array[int8, 8]
}

ethtool_coalesce_cmd_flags = ETHTOOL_GCOALESCE, ETHTOOL_SCOALESCE

ethtool_coalesce {
	cmd				flags[ethtool_coalesce_cmd_flags, int32]
	rx_coalesce_usecs		int32
	rx_max_coalesced_frames		int32
	rx_coalesce_usecs_irq		int32
	rx_max_coalesced_frames_irq	int32
	tx_coalesce_usecs		int32
	tx_max_coalesced_frames		int32
	tx_coalesce_usecs_irq		int32
	tx_max_coalesced_frames_irq	int32
	stats_block_coalesce_usecs	int32
	use_adaptive_rx_coalesce	int32
	use_adaptive_tx_coalesce	int32
	pkt_rate_low			int32
	rx_coalesce_usecs_low		int32
	rx_max_coalesced_frames_low	int32
	tx_coalesce_usecs_low		int32
	tx_max_coalesced_frames_low	int32
	pkt_rate_high			int32
	rx_coalesce_usecs_high		int32
	rx_max_coalesced_frames_high	int32
	tx_coalesce_usecs_high		int32
	tx_max_coalesced_frames_high	int32
	rate_sample_interval		int32
}

ethtool_ringparam_cmd_flags = ETHTOOL_GRINGPARAM, ETHTOOL_SRINGPARAM

ethtool_ringparam {
	cmd			flags[ethtool_ringparam_cmd_flags, int32]
	rx_max_pending		int32
	rx_mini_max_pending	int32
	rx_jumbo_max_pending	int32
	tx_max_pending		int32
	rx_pending		int32
	rx_mini_pending		int32
	rx_jumbo_pending	int32
	tx_pending		int32
}

ethtool_channels_cmd_flags = ETHTOOL_GCHANNELS, ETHTOOL_SCHANNELS

ethtool_channels {
	cmd		flags[ethtool_channels_cmd_flags, int32]
	max_rx		int32
	max_tx		int32
	max_other	int32
	max_combined	int32
	rx_count	int32
	tx_count	int32
	other_count	int32
	combined_count	int32
}

ethtool_pauseparam_cmd_flags = ETHTOOL_GPAUSEPARAM, ETHTOOL_SPAUSEPARAM

ethtool_pauseparam {
	cmd		flags[ethtool_pauseparam_cmd_flags, int32]
	autoneg		int32
	rx_pause	int32
	tx_pause	int32
}

ethtool_gstrings {
	cmd		const[ETHTOOL_GSTRINGS, int32]
	string_set	int32
	len		len[data, int32]
	data		array[int8]
}

ethtool_sset_info {
	cmd		const[ETHTOOL_GSSET_INFO, int32]
	reserved	int32
	sset_mask	int64
	data		array[int32]
}

ethtool_test {
	cmd		const[ETHTOOL_TEST, int32]
	flags		int32
	reserved	int32
	len		len[data, int32]
	data		array[int64]
}

ethtool_stats {
	cmd	const[ETHTOOL_GSTATS, int32]
	n_stats	len[data, int32]
	data	array[int64]
}

ethtool_perm_addr {
	cmd	const[ETHTOOL_GPERMADDR, int32]
	size	len[data, int32]
	data	array[int8]
}

# http://elixir.free-electrons.com/linux/latest/source/include/uapi/linux/ethtool.h#L1565
traffic_flow_types = TCP_V4_FLOW, UDP_V4_FLOW, SCTP_V4_FLOW, AH_ESP_V4_FLOW, TCP_V6_FLOW, UDP_V6_FLOW, SCTP_V6_FLOW, AH_ESP_V6_FLOW, AH_V4_FLOW, ESP_V4_FLOW, AH_V6_FLOW, ESP_V6_FLOW, IPV4_USER_FLOW, IP_USER_FLOW, IPV6_USER_FLOW, IPV4_FLOW, IPV6_FLOW, ETHER_FLOW

ethtool_rxnfc_cmd_flags = ETHTOOL_GRXFH, ETHTOOL_SRXFH, ETHTOOL_GRXRINGS, ETHTOOL_GRXCLSRLCNT, ETHTOOL_GRXCLSRULE, ETHTOOL_GRXCLSRLALL, ETHTOOL_SRXCLSRLDEL, ETHTOOL_SRXCLSRLINS

ethtool_rxnfc {
	cmd		flags[ethtool_rxnfc_cmd_flags, int32]
	flow_type	flags[traffic_flow_types, int32]
	data		int64
	fs		ethtool_rx_flow_spec
	rule_cnt	len[rule_locs, int32]
	rule_locs	array[int32]
}

ethtool_rx_flow_spec {
	flow_type	flags[traffic_flow_types, int32]
	h_u		ethtool_flow_union
	h_ext		ethtool_flow_ext
	m_u		ethtool_flow_union
	m_ext		ethtool_flow_ext
	ring_cookie	int64
	location	int32
}

ethtool_flow_union [
	tcp_ip4_spec	ethtool_tcpip4_spec
	udp_ip4_spec	ethtool_tcpip4_spec
	sctp_ip4_spec	ethtool_tcpip4_spec
	ah_ip4_spec	ethtool_ah_espip4_spec
	esp_ip4_spec	ethtool_ah_espip4_spec
	usr_ip4_spec	ethtool_usrip4_spec
	tcp_ip6_spec	ethtool_tcpip6_spec
	udp_ip6_spec	ethtool_tcpip6_spec
	sctp_ip6_spec	ethtool_tcpip6_spec
	ah_ip6_spec	ethtool_ah_espip6_spec
	esp_ip6_spec	ethtool_ah_espip6_spec
	usr_ip6_spec	ethtool_usrip6_spec
	ether_spec	ethhdr
	hdata		array[int8, 52]
]

ethtool_flow_ext {
	padding		const[0, int16]
	h_dest		mac_addr
	vlan_etype	int16be
	vlan_tci	int16be
	data		array[int32be, 2]
}

ethtool_tcpip4_spec {
	ip4src	ipv4_addr
	ip4dst	ipv4_addr
	psrc	sock_port
	pdst	sock_port
	tos	int8
}

ethtool_ah_espip4_spec {
	ip4src	ipv4_addr
	ip4dst	ipv4_addr
	spi	int32be
	tos	int8
}

ethtool_usrip4_spec {
	ip4src		ipv4_addr
	ip4dst		ipv4_addr
	l4_4_bytes	int32be
	tos		int8
	ip_ver		const[ETH_RX_NFC_IP4, int8]
	proto		int8
}

ethtool_tcpip6_spec {
	ip6src	ipv6_addr
	ip6dst	ipv6_addr
	psrc	sock_port
	pdst	sock_port
	tclass	int8
}

ethtool_ah_espip6_spec {
	ip6src	ipv6_addr
	ip6dst	ipv6_addr
	spi	int32be
	tclass	int8
}

ethtool_usrip6_spec {
	ip6src		ipv6_addr
	ip6dst		ipv6_addr
	l4_4_bytes	int32be
	tclass		int8
	l4_proto	int8
}

ethhdr {
	h_dest		mac_addr
	h_source	mac_addr
	h_proto		int16be
} [packed]

ethtool_rxfh_indir_flags = ETHTOOL_GRXFHINDIR, ETHTOOL_SRXFHINDIR

ethtool_rxfh_indir {
	cmd		flags[ethtool_rxfh_indir_flags, int32]
	size		len[ring_index, int32]
	ring_index	array[int32]
}

ethtool_rxfh_cmd_flags = ETHTOOL_GRSSH, ETHTOOL_SRSSH

ethtool_rxfh {
	cmd		flags[ethtool_rxfh_cmd_flags, int32]
	rss_context	int32
	indir_size	int32
	key_size	int32
	hfunc		int8
	rsvd8		array[int8, 3]
	rsvd32		int32
	rss_config	array[int32]
}

ethtool_rx_ntuple {
	cmd	const[ETHTOOL_SRXNTUPLE, int32]
	fs	ethtool_rx_ntuple_flow_spec
}

ethtool_rx_ntuple_flow_spec_action_flags = ETHTOOL_RXNTUPLE_ACTION_DROP, ETHTOOL_RXNTUPLE_ACTION_CLEAR

ethtool_rx_ntuple_flow_spec {
	flow_type	flags[traffic_flow_types, int32]
	h_u		ethtool_rx_ntuple_flow_spec_union
	m_u		ethtool_rx_ntuple_flow_spec_union
	vlan_tag	int16
	vlan_tag_mask	int16
	data		int64
	data_mask	int64
	action		flags[ethtool_rx_ntuple_flow_spec_action_flags, int32]
}

ethtool_rx_ntuple_flow_spec_union [
	tcp_ip4_spec	ethtool_tcpip4_spec
	udp_ip4_spec	ethtool_tcpip4_spec
	sctp_ip4_spec	ethtool_tcpip4_spec
	ah_ip4_spec	ethtool_ah_espip4_spec
	esp_ip4_spec	ethtool_ah_espip4_spec
	usr_ip4_spec	ethtool_usrip4_spec
	ether_spec	ethhdr
	hdata		array[int8, 72]
]

ethtool_flash {
	cmd	const[ETHTOOL_FLASHDEV, int32]
	region	int32
	data	array[int8, ETHTOOL_FLASH_MAX_FILENAME]
}

ethtool_dump_cmd_flags = ETHTOOL_GET_DUMP_FLAG, ETHTOOL_GET_DUMP_DATA, ETHTOOL_SET_DUMP

ethtool_dump {
	cmd	flags[ethtool_dump_cmd_flags, int32]
	version	int32
	flag	int32
	len	len[data, int32]
	data	array[int8]
}

ethtool_gfeatures {
	cmd		const[ETHTOOL_GFEATURES, int32]
	size		len[features, int32]
	features	array[ethtool_get_features_block]
}

ethtool_get_features_block {
	available	int32
	requested	int32
	active		int32
	never_changed	int32
}

ethtool_sfeatures {
	cmd		const[ETHTOOL_SFEATURES, int32]
	size		len[features, int32]
	features	array[ethtool_set_features_block]
}

ethtool_set_features_block {
	valid		int32
	requested	int32
}

ethtool_ts_info {
	cmd		const[ETHTOOL_GET_TS_INFO, int32]
	so_timestamping	int32
	phc_index	int32
	tx_types	int32
	tx_reserved	array[int32, 3]
	rx_filters	int32
	rx_reserved	array[int32, 3]
}

ethtool_per_queue_op {
	cmd		const[ETHTOOL_PERQUEUE, int32]
	sub_command	int32
	queue_mask	array[int32, MAX_NUM_QUEUE]
	data		array[int8]
}

ethtool_link_settings_cmd_flags = ETHTOOL_GLINKSETTINGS, ETHTOOL_SLINKSETTINGS

ethtool_link_settings {
	cmd			flags[ethtool_link_settings_cmd_flags, int32]
	speed			int32
	duplex			int8
	port			int8
	phy_address		int8
	autoneg			int8
	mdio_support		int8
	eth_tp_mdix		int8
	eth_tp_mdix_ctrl	int8
	link_mode_masks_nwords	int8
	reserved		array[int32, 8]
	link_mode_masks		array[int32]
}