1 //Written in the D programming language
2 
3 /++
4     D header file for Linux's linux/if_packet.h.
5 
6     Copyright: Copyright 2023
7     License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
8     Authors:   $(HTTP jmdavisprog.com, Jonathan M Davis)
9  +/
10 module core.sys.linux.linux.if_packet;
11 
12 version (linux):
13 extern(C):
14 @nogc:
15 nothrow:
16 
17 import core.stdc.config : c_ulong;
18 import core.sys.posix.sys.socket : sa_family_t;
19 
20 struct sockaddr_pkt
21 {
22     sa_family_t spkt_family;
23     ubyte[14]   spkt_device;
24     ushort      spkt_protocol;
25 }
26 
27 struct sockaddr_ll
28 {
29     sa_family_t sll_family;
30     ushort      sll_protocol;
31     int         sll_ifindex;
32     ushort      sll_hatype;
33     ubyte       sll_pkttype;
34     ubyte       sll_halen;
35     ubyte[8]    sll_addr;
36 }
37 
38 enum : ubyte
39 {
40     PACKET_HOST      = 0,
41     PACKET_BROADCAST = 1,
42     PACKET_MULTICAST = 2,
43     PACKET_OTHERHOST = 3,
44     PACKET_OUTGOING  = 4,
45     PACKET_LOOPBACK  = 5,
46     PACKET_USER      = 6,
47     PACKET_KERNEL    = 7,
48 }
49 
50 enum
51 {
52     PACKET_ADD_MEMBERSHIP  = 1,
53     PACKET_DROP_MEMBERSHIP = 2,
54     PACKET_RECV_OUTPUT     = 3,
55 
56     PACKET_RX_RING         = 5,
57     PACKET_STATISTICS      = 6,
58     PACKET_COPY_THRESH     = 7,
59     PACKET_AUXDATA         = 8,
60     PACKET_ORIGDEV         = 9,
61     PACKET_VERSION         = 10,
62     PACKET_HDRLEN          = 11,
63     PACKET_RESERVE         = 12,
64     PACKET_TX_RING         = 13,
65     PACKET_LOSS            = 14,
66     PACKET_VNET_HDR        = 15,
67     PACKET_TX_TIMESTAMP    = 16,
68     PACKET_TIMESTAMP       = 17,
69     PACKET_FANOUT          = 18,
70     PACKET_TX_HAS_OFF      = 19,
71     PACKET_QDISC_BYPASS    = 20,
72     PACKET_ROLLOVER_STATS  = 21,
73     PACKET_FANOUT_DATA     = 22,
74     PACKET_IGNORE_OUTGOING = 23,
75     PACKET_VNET_HDR_SZ     = 24,
76 
77     PACKET_FANOUT_HASH     = 0,
78     PACKET_FANOUT_LB       = 1,
79     PACKET_FANOUT_CPU      = 2,
80     PACKET_FANOUT_ROLLOVER = 3,
81     PACKET_FANOUT_RND      = 4,
82     PACKET_FANOUT_QM       = 5,
83     PACKET_FANOUT_CBPF     = 6,
84     PACKET_FANOUT_EBPF     = 7,
85 
86     PACKET_FANOUT_FLAG_ROLLOVER        = 0x1000,
87     PACKET_FANOUT_FLAG_UNIQUEID        = 0x2000,
88     PACKET_FANOUT_FLAG_IGNORE_OUTGOING = 0x4000,
89     PACKET_FANOUT_FLAG_DEFRAG          = 0x8000,
90 }
91 
92 struct tpacket_stats
93 {
94     uint tp_packets;
95     uint tp_drops;
96 }
97 
98 struct tpacket_stats_v3
99 {
100     uint tp_packets;
101     uint tp_drops;
102     uint tp_freeze_q_cnt;
103 }
104 
105 struct tpacket_rollover_stats
106 {
107     align(8):
108     ulong tp_all;
109     ulong tp_huge;
110     ulong tp_failed;
111 }
112 
113 union tpacket_stats_u
114 {
115     tpacket_stats    stats1;
116     tpacket_stats_v3 stats3;
117 }
118 
119 struct tpacket_auxdata
120 {
121     uint   tp_status;
122     uint   tp_len;
123     uint   tp_snaplen;
124     ushort tp_mac;
125     ushort tp_net;
126     ushort tp_vlan_tci;
127     ushort tp_vlan_tpid;
128 }
129 
130 enum : uint
131 {
132     TP_STATUS_KERNEL          = 0,
133     TP_STATUS_USER            = 1 << 0,
134     TP_STATUS_COPY            = 1 << 1,
135     TP_STATUS_LOSING          = 1 << 2,
136     TP_STATUS_CSUMNOTREADY    = 1 << 3,
137     TP_STATUS_VLAN_VALID      = 1 << 4,
138     TP_STATUS_BLK_TMO         = 1 << 5,
139     TP_STATUS_VLAN_TPID_VALID = 1 << 6,
140     TP_STATUS_CSUM_VALID      = 1 << 7,
141     TP_STATUS_GSO_TCP         = 1 << 8,
142 }
143 
144 enum : uint
145 {
146     TP_STATUS_AVAILABLE    = 0,
147     TP_STATUS_SEND_REQUEST = 1 << 0,
148     TP_STATUS_SENDING      = 1 << 1,
149     TP_STATUS_WRONG_FORMAT = 1 << 2,
150 }
151 
152 enum : uint
153 {
154     TP_STATUS_TS_SOFTWARE     = 1 << 29,
155     TP_STATUS_TS_RAW_HARDWARE = 1U << 31,
156 }
157 
158 enum uint TP_FT_REQ_FILL_RXHASH = 0x1;
159 
160 struct tpacket_hdr
161 {
162     c_ulong tp_status;
163     uint    tp_len;
164     uint    tp_snaplen;
165     ushort  tp_mac;
166     ushort  tp_net;
167     uint    tp_sec;
168     uint    tp_usec;
169 }
170 
171 enum TPACKET_ALIGNMENT = 16;
172 size_t TPACKET_ALIGN(size_t x) { return (x + TPACKET_ALIGNMENT - 1) &~ (TPACKET_ALIGNMENT - 1); }
173 enum TPACKET_HDRLEN = TPACKET_ALIGN(tpacket_hdr.sizeof) + sockaddr_ll.sizeof;
174 
175 struct tpacket2_hdr
176 {
177     uint     tp_status;
178     uint     tp_len;
179     uint     tp_snaplen;
180     ushort   tp_mac;
181     ushort   tp_net;
182     uint     tp_sec;
183     uint     tp_nsec;
184     ushort   tp_vlan_tci;
185     ushort   tp_vlan_tpid;
186     ubyte[4] tp_padding;
187 }
188 
189 struct tpacket_hdr_variant1
190 {
191     uint   tp_rxhash;
192     uint   tp_vlan_tci;
193     ushort tp_vlan_tpid;
194     ushort tp_padding;
195 }
196 
197 struct tpacket3_hdr
198 {
199     uint   tp_next_offset;
200     uint   tp_sec;
201     uint   tp_nsec;
202     uint   tp_snaplen;
203     uint   tp_len;
204     uint   tp_status;
205     ushort tp_mac;
206     ushort tp_net;
207 
208     union
209     {
210         tpacket_hdr_variant1 hv1;
211     }
212 
213     ubyte[8] tp_padding;
214 }
215 
216 struct tpacket_bd_ts
217 {
218     uint ts_sec;
219 
220     union
221     {
222         uint ts_usec;
223         uint ts_nsec;
224     }
225 }
226 
227 struct tpacket_hdr_v1
228 {
229     uint block_status;
230     uint num_pkts;
231     uint offset_to_first_pkt;
232     uint blk_len;
233     align(8) ulong seq_num;
234     tpacket_bd_ts ts_first_pkt;
235     tpacket_bd_ts ts_last_pkt;
236 }
237 
238 union tpacket_bd_header_u
239 {
240     tpacket_hdr_v1 bh1;
241 }
242 
243 struct tpacket_block_desc
244 {
245     uint version_;
246     uint offset_to_priv;
247     tpacket_bd_header_u hdr;
248 }
249 
250 enum TPACKET2_HDRLEN = TPACKET_ALIGN(tpacket2_hdr.sizeof) + sockaddr_ll.sizeof;
251 enum TPACKET3_HDRLEN = TPACKET_ALIGN(tpacket3_hdr.sizeof) + sockaddr_ll.sizeof;
252 
253 enum tpacket_versions
254 {
255     TPACKET_V1,
256     TPACKET_V2,
257     TPACKET_V3
258 }
259 
260 struct tpacket_req
261 {
262     uint tp_block_size;
263     uint tp_block_nr;
264     uint tp_frame_size;
265     uint tp_frame_nr;
266 }
267 
268 struct tpacket_req3
269 {
270     uint tp_block_size;
271     uint tp_block_nr;
272     uint tp_frame_size;
273     uint tp_frame_nr;
274     uint tp_retire_blk_tov;
275     uint tp_sizeof_priv;
276     uint tp_feature_req_word;
277 }
278 
279 union tpacket_req_u
280 {
281     tpacket_req  req;
282     tpacket_req3 req3;
283 }
284 
285 struct packet_mreq
286 {
287     int      mr_ifindex;
288     ushort   mr_type;
289     ushort   mr_alen;
290     ubyte[8] mr_address;
291 }
292 
293 struct fanout_args
294 {
295     version(LittleEndian)
296     {
297         ushort id;
298         ushort type_flags;
299     }
300     else
301     {
302         ushort type_flags;
303         ushort id;
304     }
305 
306     uint max_num_members;
307 }
308 
309 enum
310 {
311     PACKET_MR_MULTICAST = 0,
312     PACKET_MR_PROMISC   = 1,
313     PACKET_MR_ALLMULTI  = 2,
314     PACKET_MR_UNICAST   = 3,
315 }