1/*
2 * Copyright (c) 2017, ETH Zurich.
3 * All rights reserved.
4 *
5 * This file is distributed under the terms in the attached LICENSE file.
6 * If you do not find this file, copies can be found by writing to:
7 * ETH Zurich D-INFK, CAB F.78, Universitaetstrasse 6, CH-8092 Zurich.
8 * Attn: Systems Group.
9 */
10
11#ifndef HEADERS_IMPL_H
12#define HEADERS_IMPL_H
13
14#define ETH_HWADDR_LEN     6
15
16#define PACK_STRUCT_FIELD(x) x
17#define PACK_STRUCT_STRUCT __attribute__((packed))
18#define PACK_STRUCT_BEGIN
19#define PACK_STRUCT_END
20
21PACK_STRUCT_BEGIN
22/** Ethernet header */
23struct eth_hdr {
24  PACK_STRUCT_FIELD(struct eth_addr dest);
25  PACK_STRUCT_FIELD(struct eth_addr src);
26  PACK_STRUCT_FIELD(uint16_t type);
27} PACK_STRUCT_STRUCT;
28PACK_STRUCT_END
29
30#define ETH_HLEN 14
31
32#define ETHTYPE_IP        0x0800U
33
34PACK_STRUCT_BEGIN
35struct ip_hdr {
36  /* version / header length */
37  PACK_STRUCT_FIELD(uint8_t _v_hl);
38  /* type of service */
39  PACK_STRUCT_FIELD(uint8_t _tos);
40  /* total length */
41  PACK_STRUCT_FIELD(uint16_t _len);
42  /* identification */
43  PACK_STRUCT_FIELD(uint16_t _id);
44  /* fragment offset field */
45  PACK_STRUCT_FIELD(uint16_t _offset);
46#define IP_RF 0x8000U        /* reserved fragment flag */
47#define IP_DF 0x4000U        /* dont fragment flag */
48#define IP_MF 0x2000U        /* more fragments flag */
49#define IP_OFFMASK 0x1fffU   /* mask for fragmenting bits */
50  /* time to live */
51  PACK_STRUCT_FIELD(uint8_t _ttl);
52  /* protocol*/
53  PACK_STRUCT_FIELD(uint8_t _proto);
54  /* checksum */
55  PACK_STRUCT_FIELD(uint16_t _chksum);
56  /* source and destination IP addresses */
57  PACK_STRUCT_FIELD(uint32_t src);
58  PACK_STRUCT_FIELD(uint32_t dest);
59} PACK_STRUCT_STRUCT;
60PACK_STRUCT_END
61
62#define IPH_V(hdr)  ((hdr)->_v_hl >> 4)
63#define IPH_HL(hdr) ((hdr)->_v_hl & 0x0f)
64#define IPH_TOS(hdr) ((hdr)->_tos)
65#define IPH_LEN(hdr) ((hdr)->_len)
66#define IPH_ID(hdr) ((hdr)->_id)
67#define IPH_OFFSET(hdr) ((hdr)->_offset)
68#define IPH_TTL(hdr) ((hdr)->_ttl)
69#define IPH_PROTO(hdr) ((hdr)->_proto)
70#define IPH_CHKSUM(hdr) ((hdr)->_chksum)
71
72#define IPH_VHL_SET(hdr, v, hl) (hdr)->_v_hl = (((v) << 4) | (hl))
73#define IPH_TOS_SET(hdr, tos) (hdr)->_tos = (tos)
74#define IPH_LEN_SET(hdr, len) (hdr)->_len = (len)
75#define IPH_ID_SET(hdr, id) (hdr)->_id = (id)
76#define IPH_OFFSET_SET(hdr, off) (hdr)->_offset = (off)
77#define IPH_TTL_SET(hdr, ttl) (hdr)->_ttl = (uint8_t)(ttl)
78#define IPH_PROTO_SET(hdr, proto) (hdr)->_proto = (uint8_t)(proto)
79#define IPH_CHKSUM_SET(hdr, chksum) (hdr)->_chksum = (chksum)
80
81#define IP_HLEN 20
82
83#define IP_PROTO_IP      0
84#define IP_PROTO_UDP     17
85
86#define UDP_HLEN 8
87
88PACK_STRUCT_BEGIN
89struct udp_hdr {
90  PACK_STRUCT_FIELD(uint16_t src);
91  PACK_STRUCT_FIELD(uint16_t dest);  /* src/dest UDP ports */
92  PACK_STRUCT_FIELD(uint16_t len);
93  PACK_STRUCT_FIELD(uint16_t chksum);
94} PACK_STRUCT_STRUCT;
95PACK_STRUCT_END
96
97#endif
98