1 /*
2  * Packet Headers
3  * Copyright (C) 2003, 2004, 2005 Mondru AB.
4  * Copyright (c) 2007 David Bird <david@coova.com>
5  *
6  * The contents of this file may be used under the terms of the GNU
7  * General Public License Version 2, provided that the above copyright
8  * notice and this permission notice is included in all copies or
9  * substantial portions of the software.
10  *
11  * The initial developer of the original code is
12  * Jens Jakobsen <jj@chillispot.org>
13  *
14  */
15 
16 
17 #ifndef _PKT_H
18 #define _PKT_H
19 
20 #define PKT_ETH_ALEN              6 /* Ethernet Address Length */
21 #define PKT_ETH_HLEN             14 /* Ethernet Header Length */
22 
23 #define PKT_ETH_PROTO_IP     0x0800
24 #define PKT_ETH_PROTO_ARP    0x0806
25 #define PKT_ETH_PROTO_EAPOL  0x888e
26 
27 #define PKT_IP_PLEN            1500 /* IP Payload Length */
28 #define PKT_IP_VER_HLEN        0x45
29 #define PKT_IP_ALEN               4
30 #define PKT_IP_HLEN              20
31 
32 #define PKT_IP_PROTO_ICMP         1 /* ICMP Protocol number */
33 #define PKT_IP_PROTO_TCP          6 /* TCP Protocol number */
34 #define PKT_IP_PROTO_UDP         17 /* UDP Protocol number */
35 #define PKT_IP_PROTO_GRE         47 /* GRE Protocol number */
36 
37 #define PKT_UDP_HLEN              8
38 
39 #define PKT_EAP_PLEN           1500 /* Dot1x Payload length */
40 
41 #define DHCP_TAG_VLEN           255 /* Tag value always shorter than this */
42 #define EAPOL_TAG_VLEN          255 /* Tag value always shorter than this */
43 
44 #define DHCP_HTYPE_ETH            1
45 #define DHCP_CHADDR_LEN          16 /* Length of client hardware address */
46 #define DHCP_SNAME_LEN           64 /* Length of server host name */
47 #define DHCP_FILE_LEN           128 /* Length of boot file name*/
48 #define DHCP_OPTIONS_LEN        312 /* Length of optional parameters field */
49 #define DHCP_MIN_LEN   28+16+64+128 /* Length of packet excluding options */
50 #define DHCP_LEN  DHCP_MIN_LEN + DHCP_OPTIONS_LEN
51 
52 
53 struct pkt_ethhdr_t {
54   uint8_t  dst[PKT_ETH_ALEN];
55   uint8_t  src[PKT_ETH_ALEN];
56   uint16_t prot;
57 } __attribute__((packed));
58 
59 
60 struct pkt_iphdr_t {
61   uint8_t  version_ihl;
62   uint8_t  tos;
63   uint16_t tot_len;
64   uint16_t id;
65   uint16_t frag_off;
66   uint8_t  ttl;
67   uint8_t  protocol;
68   uint16_t check;
69   uint32_t saddr;
70   uint32_t daddr;
71 } __attribute__((packed));
72 
73 
74 struct pkt_ipphdr_t {
75   /* Convenience structure:
76      Same as pkt_iphdr_t, but also
77      with ports (UDP and TCP packets) */
78   uint8_t  version_ihl;
79   uint8_t  tos;
80   uint16_t tot_len;
81   uint16_t id;
82   uint16_t frag_off;
83   uint8_t  ttl;
84   uint8_t  protocol;
85   uint16_t check;
86   uint32_t saddr;
87   uint32_t daddr;
88   uint16_t sport;
89   uint16_t dport;
90 } __attribute__((packed));
91 
92 
93 struct pkt_ippacket_t {
94   struct pkt_ethhdr_t ethh;
95   struct pkt_iphdr_t  iph;
96   uint8_t payload[PKT_IP_PLEN];
97 } __attribute__((packed));
98 
99 /*
100   0      7 8     15 16    23 24    31
101   +--------+--------+--------+--------+
102   |     Source      |   Destination   |
103   |      Port       |      Port       |
104   +--------+--------+--------+--------+
105   |                 |                 |
106   |     Length      |    Checksum     |
107   +--------+--------+--------+--------+
108   |
109   |          data octets ...
110   +---------------- ...
111 
112   User Datagram Header Format
113 */
114 
115 struct pkt_udphdr_t {
116   uint16_t src;
117   uint16_t dst;
118   uint16_t len;
119   uint16_t check;
120 } __attribute__((packed));
121 
122 /*
123   TCP Header Format
124 
125     0                   1                   2                   3
126     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
127    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
128    |          Source Port          |       Destination Port        |
129    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
130    |                        Sequence Number                        |
131    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
132    |                    Acknowledgment Number                      |
133    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
134    |  Data |           |U|A|P|R|S|F|                               |
135    | Offset| Reserved  |R|C|S|S|Y|I|            Window             |
136    |       |           |G|K|H|T|N|N|                               |
137    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
138    |           Checksum            |         Urgent Pointer        |
139    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
140    |                    Options                    |    Padding    |
141    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
142    |                             data                              |
143    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
144 */
145 
146 struct pkt_tcphdr_t {
147   uint16_t src;
148   uint16_t dst;
149   uint32_t seq;
150   uint32_t ack;
151   uint16_t flags;
152   uint16_t win;
153   uint16_t check;
154   uint16_t urgent;
155   uint32_t options;
156 } __attribute__((packed));
157 
158 
159 /*
160   0                   1                   2                   3
161    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
162    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
163    |     op (1)    |   htype (1)   |   hlen (1)    |   hops (1)    |
164    +---------------+---------------+---------------+---------------+
165    |                            xid (4)                            |
166    +-------------------------------+-------------------------------+
167    |           secs (2)            |           flags (2)           |
168    +-------------------------------+-------------------------------+
169    |                          ciaddr  (4)                          |
170    +---------------------------------------------------------------+
171    |                          yiaddr  (4)                          |
172    +---------------------------------------------------------------+
173    |                          siaddr  (4)                          |
174    +---------------------------------------------------------------+
175    |                          giaddr  (4)                          |
176    +---------------------------------------------------------------+
177    |                                                               |
178    |                          chaddr  (16)                         |
179    |                                                               |
180    |                                                               |
181    +---------------------------------------------------------------+
182    |                                                               |
183    |                          sname   (64)                         |
184    +---------------------------------------------------------------+
185    |                                                               |
186    |                          file    (128)                        |
187    +---------------------------------------------------------------+
188    |                                                               |
189    |                          options (variable)                   |
190    +---------------------------------------------------------------+
191 */
192 
193 struct dhcp_packet_t { /* From RFC 2131 */
194   uint8_t op;       /* 1 Message op code / message type.  1 = BOOTREQUEST, 2 = BOOTREPLY */
195   uint8_t htype;    /* 1 Hardware address type, see ARP section in "Assigned Numbers" RFC */
196   uint8_t hlen;     /* 1 Hardware address length (e.g. '6' for 10mb ethernet).*/
197   uint8_t hops;     /* 1 Client sets to zero, optionally used by relay agents when booting via a relay agent.*/
198   uint32_t xid;     /* 4 Transaction ID, a random number chosen by the client, used by the client and
199 		       server to associate messages and responses between a client and a server. */
200   uint16_t secs;    /* 2 Filled in by client, seconds elapsed since client began address acquisition or renewal process.*/
201   uint8_t flags[2]; /* 2  Flags (see figure 2).*/
202   uint32_t ciaddr;  /* 4 Client IP address; only filled in if client is in BOUND, RENEW or REBINDING state
203 		       and can respond to ARP requests.*/
204   uint32_t yiaddr;  /* 4 'your' (client) IP address.*/
205   uint32_t siaddr;  /* 4 IP address of next server to use in bootstrap; returned in DHCPOFFER, DHCPACK by server.*/
206   uint32_t giaddr;  /* 4 Relay agent IP address, used in booting via a relay agent.*/
207   uint8_t chaddr[DHCP_CHADDR_LEN];   /* 16 Client hardware address.*/
208   uint8_t sname[DHCP_SNAME_LEN];     /* 64 Optional server host name, null terminated string.*/
209   uint8_t file[DHCP_FILE_LEN];       /* 128 Boot file name, null terminated string; "generic" name or null in
210 					DHCPDISCOVER, fully qualified directory-path name in DHCPOFFER.*/
211   uint8_t options[DHCP_OPTIONS_LEN]; /* var Optional parameters field.  See the options documents for a list
212 					of defined options.*/
213 } __attribute__((packed));
214 
215 
216 struct dhcp_fullpacket_t {
217   struct pkt_ethhdr_t  ethh;
218   struct pkt_iphdr_t   iph;
219   struct pkt_udphdr_t  udph;
220   struct dhcp_packet_t dhcp;
221 } __attribute__((packed));
222 
223 
224 struct dhcp_tag_t {
225   uint8_t t;
226   uint8_t l;
227   uint8_t v[DHCP_TAG_VLEN];
228 } __attribute__((packed));
229 
230 
231 struct arp_packet_t { /* From RFC 826 */
232   uint16_t hrd; /* 16.bit: (ar$hrd) Hardware address space (e.g.,
233 		    Ethernet, Packet Radio Net.) */
234   uint16_t pro; /* 16.bit: (ar$pro) Protocol address space.  For
235 		    Ethernet hardware, this is from the set of type
236 		    fields ether_typ$<protocol>. */
237   uint8_t hln;  /* 8.bit: (ar$hln) byte length of each hardware address */
238   uint8_t pln;  /* 8.bit: (ar$pln) byte length of each protocol address */
239   uint16_t op;  /* 16.bit: (ar$op)  opcode (ares_op$REQUEST | ares_op$REPLY) */
240   uint8_t sha[PKT_ETH_ALEN]; /* nbytes: (ar$sha) Hardware address of
241 		    sender of this packet, n from the ar$hln field. */
242   uint8_t spa[PKT_IP_ALEN];  /* mbytes: (ar$spa) Protocol address of
243 		    sender of this packet, m from the ar$pln field. */
244   uint8_t tha[PKT_ETH_ALEN]; /* nbytes: (ar$tha) Hardware address of
245 		  target of this packet (if known). */
246   uint8_t tpa[PKT_IP_ALEN]; /* mbytes: (ar$tpa) Protocol address of
247 				 target.*/
248 } __attribute__((packed));
249 
250 
251 struct arp_fullpacket_t {
252   struct pkt_ethhdr_t ethh;
253   struct arp_packet_t arp;
254 } __attribute__((packed));
255 
256 
257 struct dns_packet_t { /* From RFC 1035 */
258   uint16_t id;      /* 16 bit: Generated by requester. Copied in reply */
259   uint16_t flags;   /* 16 bit: Flags */
260   uint16_t qdcount; /* 16 bit: Number of questions */
261   uint16_t ancount; /* 16 bit: Number of answer records */
262   uint16_t nscount; /* 16 bit: Number of name servers */
263   uint16_t arcount; /* 16 bit: Number of additional records */
264   uint8_t  records[PKT_IP_PLEN];
265 } __attribute__((packed));
266 
267 
268 struct dns_fullpacket_t {
269   struct pkt_ethhdr_t ethh;
270   struct pkt_iphdr_t iph;
271   struct pkt_udphdr_t udph;
272   struct dns_packet_t dns;
273 } __attribute__((packed));
274 
275 
276 struct pkt_dot1xhdr_t {
277   uint8_t  ver;
278   uint8_t  type;
279   uint16_t len;
280 } __attribute__((packed));
281 
282 
283 struct eap_packet_t {
284   uint8_t  code;
285   uint8_t  id;
286   uint16_t length;
287   uint8_t  type;
288   uint8_t  payload[PKT_EAP_PLEN];
289 } __attribute__((packed));
290 
291 
292 struct dot1xpacket_t {
293   struct pkt_ethhdr_t   ethh;
294   struct pkt_dot1xhdr_t dot1x;
295   struct eap_packet_t   eap;
296 } __attribute__((packed));
297 
298 
299 struct eapol_tag_t {
300   uint8_t t;
301   uint8_t l;
302   uint8_t v[EAPOL_TAG_VLEN];
303 } __attribute__((packed));
304 
305 int chksum(struct pkt_iphdr_t *iph);
306 
307 #endif
308