1/*
2 * Copyright 2005, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
3 * Copyright 2010, Andreas F��rber <andreas.faerber@web.de>
4 * All rights reserved. Distributed under the terms of the MIT License.
5 */
6#ifndef _BOOT_NET_DEFS_H
7#define _BOOT_NET_DEFS_H
8
9
10#include <string.h>
11
12#include <ByteOrder.h>
13#include <SupportDefs.h>
14
15#include <util/kernel_cpp.h>
16
17
18// Network endianness
19#ifndef htonl
20#	define htonl(x) B_HOST_TO_BENDIAN_INT32(x)
21#	define ntohl(x) B_BENDIAN_TO_HOST_INT32(x)
22#	define htons(x) B_HOST_TO_BENDIAN_INT16(x)
23#	define ntohs(x) B_BENDIAN_TO_HOST_INT16(x)
24#endif
25
26
27// Ethernet
28
29#define ETH_ALEN			6
30#define ETHERTYPE_IP		0x0800	// IP
31#define ETHERTYPE_ARP		0x0806	// Address resolution
32
33#define ETHER_MIN_TRANSFER_UNIT	46
34#define ETHER_MAX_TRANSFER_UNIT	1500
35
36struct mac_addr_t {
37	mac_addr_t() {}
38
39	mac_addr_t(uint8 *address)
40	{
41		memcpy(this->address, address, ETH_ALEN);
42	}
43
44	mac_addr_t(const mac_addr_t& other)
45	{
46		memcpy(address, other.address, sizeof(address));
47	}
48
49	uint64 ToUInt64() const
50	{
51		return ((uint64)address[0] << 40)
52			| ((uint64)address[1] << 32)
53			| ((uint64)address[2] << 24)
54			| ((uint64)address[3] << 16)
55			| ((uint64)address[4] << 8)
56			| (uint64)address[5];
57	}
58
59	uint8 operator[](int index)
60	{
61		return address[index];
62	}
63
64	mac_addr_t& operator=(const mac_addr_t& other)
65	{
66		memcpy(address, other.address, sizeof(address));
67		return *this;
68	}
69
70	bool operator==(const mac_addr_t& other) const
71	{
72		return memcmp(address, other.address, sizeof(address)) == 0;
73	}
74
75	bool operator!=(const mac_addr_t& other) const
76	{
77		return !(*this == other);
78	}
79
80	uint8 address[ETH_ALEN];
81} __attribute__ ((__packed__));
82
83extern const mac_addr_t kBroadcastMACAddress;
84extern const mac_addr_t kNoMACAddress;
85
86// 10/100 Mb/s ethernet header
87struct ether_header {
88	mac_addr_t	destination;	/* destination eth addr */
89	mac_addr_t	source;			/* source ether addr    */
90	uint16		type;			/* packet type ID field */
91} __attribute__ ((__packed__));
92
93
94// #pragma mark -
95
96// Address Resolution Protocol (ARP)
97
98typedef uint32 ip_addr_t;
99
100// ARP protocol opcodes
101#define ARPOP_REQUEST   1               /* ARP request.  */
102#define ARPOP_REPLY     2               /* ARP reply.  */
103#define ARPOP_RREQUEST  3               /* RARP request.  */
104#define ARPOP_RREPLY    4               /* RARP reply.  */
105#define ARPOP_InREQUEST 8               /* InARP request.  */
106#define ARPOP_InREPLY   9               /* InARP reply.  */
107#define ARPOP_NAK       10              /* (ATM)ARP NAK.  */
108
109// ARP header for IP over ethernet (RFC 826)
110struct arp_header {
111	uint16	hardware_format;	/* Format of hardware address.  */
112	uint16	protocol_format;	/* Format of protocol address.  */
113	uint8	hardware_length;	/* Length of hardware address.  */
114	uint8	protocol_length;	/* Length of protocol address.  */
115	uint16	opcode;				/* ARP opcode (command).  */
116
117	// IP over ethernet
118	mac_addr_t	sender_mac;		/* Sender hardware address.  */
119    ip_addr_t	sender_ip;		/* Sender IP address.  */
120	mac_addr_t	target_mac;		/* Target hardware address.  */
121    ip_addr_t	target_ip;		/* Target IP address.  */
122} __attribute__ ((__packed__));
123
124// ARP protocol HARDWARE identifiers.
125#define ARPHRD_ETHER    1               /* Ethernet 10/100Mbps.  */
126
127
128// #pragma mark -
129
130// Internet Protocol (IP)
131
132#define INADDR_ANY              ((ip_addr_t) 0x00000000)
133	/* Address to send to all hosts.  */
134#define INADDR_BROADCAST        ((ip_addr_t) 0xffffffff)
135	/* Address indicating an error return.  */
136#define INADDR_NONE             ((ip_addr_t) 0xffffffff)
137
138// IP packet header (no options
139struct ip_header {
140#if __BYTE_ORDER == __LITTLE_ENDIAN
141	uint8 		header_length:4;	// header length
142	uint8		version:4;			// IP protocol version
143#endif
144#if __BYTE_ORDER == __BIG_ENDIAN
145	uint8		version:4;			// IP protocol version
146	uint8 		header_length:4;	// header length
147#endif
148	uint8		type_of_service;	// type of service
149	uint16		total_length;		// total IP packet length
150	uint16		identifier;			// fragment identification
151	uint16		fragment_offset;	// fragment offset and flags (0xe000)
152	uint8		time_to_live;		// time to live
153	uint8		protocol;			// protocol
154	uint16		checksum;			// checksum (header)
155	ip_addr_t	source;				// source IP address
156	ip_addr_t	destination;		// destination IP address
157} __attribute__ ((__packed__));
158
159// IP protocol version 4
160#define	IP_PROTOCOL_VERSION_4		4
161
162// fragment flags/offset mask
163#define IP_DONT_FRAGMENT			0x4000	/* dont fragment flag */
164#define IP_FRAGMENT_OFFSET_MASK		0x1fff	/* mask for fragment offset */
165
166// Internet implementation parameters.
167#define IP_MAX_TIME_TO_LIVE			255		/* maximum time to live */
168#define IP_DEFAULT_TIME_TO_LIVE		64		/* default ttl, from RFC 1340 */
169
170// IP protocols
171#define IPPROTO_TCP					6
172#define IPPROTO_UDP					17
173
174
175// #pragma mark -
176
177// User Datagram Protocol (UDP)
178
179// UDP header (RFC 768)
180struct udp_header {
181	uint16	source;			// source port
182	uint16	destination;	// destination port
183	uint16	length;			// length of UDP packet (header + data)
184	uint16	checksum;		// checksum
185} __attribute__ ((__packed__));
186
187
188// Transmission Control Protocol (TCP)
189
190// TCP header (RFC 793, RFC 3168)
191struct tcp_header {
192	uint16	source;			// source port
193	uint16	destination;	// destination port
194	uint32	seqNumber;		// sequence number
195	uint32	ackNumber;		// acknowledgment number
196#if __BYTE_ORDER == __BIG_ENDIAN
197	uint8	dataOffset : 4;	// data offset
198	uint8	reserved : 4;	// reserved
199#elif __BYTE_ORDER == __LITTLE_ENDIAN
200	uint8	reserved : 4;
201	uint8	dataOffset : 4;
202#endif
203	uint8	flags;			// ACK, SYN, FIN, etc.
204	uint16	window;			// window size
205	uint16	checksum;		// checksum
206	uint16	urgentPointer;	// urgent pointer
207} __attribute__ ((__packed__));
208
209#define TCP_FIN		(1 << 0)
210#define TCP_SYN		(1 << 1)
211#define TCP_RST		(1 << 2)
212#define TCP_PSH		(1 << 3)
213#define TCP_ACK		(1 << 4)
214#define TCP_URG		(1 << 5)
215#define TCP_ECE		(1 << 6)	// RFC 3168
216#define TCP_CWR		(1 << 7)	// RFC 3168
217
218
219// #pragma mark -
220
221// NetService
222
223// net service names
224extern const char *const kEthernetServiceName;
225extern const char *const kARPServiceName;
226extern const char *const kIPServiceName;
227extern const char *const kUDPServiceName;
228extern const char *const kTCPServiceName;
229
230class NetService {
231public:
232	NetService(const char *name);
233	virtual ~NetService();
234
235	const char *NetServiceName();
236
237	virtual int CountSubNetServices() const;
238	virtual NetService *SubNetServiceAt(int index) const;
239	virtual NetService *FindSubNetService(const char *name) const;
240
241	template<typename ServiceType>
242	ServiceType *FindSubNetService(const char *name) const
243	{
244		// We should actually use dynamic_cast<>(), but we better spare us the
245		// RTTI stuff.
246		if (NetService *service = FindSubNetService(name))
247			return static_cast<ServiceType*>(service);
248		return NULL;
249	}
250
251private:
252	const char	*fName;
253};
254
255
256#endif	// _BOOT_NET_DEFS_H
257