* Copyright 2005, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
* Copyright 2010, Andreas FΓ€rber <andreas.faerber@web.de>
* All rights reserved. Distributed under the terms of the MIT License.
*/
#ifndef _BOOT_NET_DEFS_H
#define _BOOT_NET_DEFS_H
#include <string.h>
#include <ByteOrder.h>
#include <SupportDefs.h>
#include <util/kernel_cpp.h>
#ifndef htonl
# define htonl(x) B_HOST_TO_BENDIAN_INT32(x)
# define ntohl(x) B_BENDIAN_TO_HOST_INT32(x)
# define htons(x) B_HOST_TO_BENDIAN_INT16(x)
# define ntohs(x) B_BENDIAN_TO_HOST_INT16(x)
#endif
#define ETH_ALEN 6
#define ETHERTYPE_IP 0x0800 // IP
#define ETHERTYPE_ARP 0x0806 // Address resolution
#define ETHER_MIN_TRANSFER_UNIT 46
#define ETHER_MAX_TRANSFER_UNIT 1500
struct mac_addr_t {
mac_addr_t() {}
mac_addr_t(uint8 *address)
{
memcpy(this->address, address, ETH_ALEN);
}
mac_addr_t(const mac_addr_t& other)
{
memcpy(address, other.address, sizeof(address));
}
uint64 ToUInt64() const
{
return ((uint64)address[0] << 40)
| ((uint64)address[1] << 32)
| ((uint64)address[2] << 24)
| ((uint64)address[3] << 16)
| ((uint64)address[4] << 8)
| (uint64)address[5];
}
uint8 operator[](int index)
{
return address[index];
}
mac_addr_t& operator=(const mac_addr_t& other)
{
memcpy(address, other.address, sizeof(address));
return *this;
}
bool operator==(const mac_addr_t& other) const
{
return memcmp(address, other.address, sizeof(address)) == 0;
}
bool operator!=(const mac_addr_t& other) const
{
return !(*this == other);
}
uint8 address[ETH_ALEN];
} __attribute__ ((__packed__));
extern const mac_addr_t kBroadcastMACAddress;
extern const mac_addr_t kNoMACAddress;
struct ether_header {
mac_addr_t destination;
mac_addr_t source;
uint16 type;
} __attribute__ ((__packed__));
typedef uint32 ip_addr_t;
#define ARPOP_REQUEST 1 /* ARP request. */
#define ARPOP_REPLY 2 /* ARP reply. */
#define ARPOP_RREQUEST 3 /* RARP request. */
#define ARPOP_RREPLY 4 /* RARP reply. */
#define ARPOP_InREQUEST 8 /* InARP request. */
#define ARPOP_InREPLY 9 /* InARP reply. */
#define ARPOP_NAK 10 /* (ATM)ARP NAK. */
struct arp_header {
uint16 hardware_format;
uint16 protocol_format;
uint8 hardware_length;
uint8 protocol_length;
uint16 opcode;
mac_addr_t sender_mac;
ip_addr_t sender_ip;
mac_addr_t target_mac;
ip_addr_t target_ip;
} __attribute__ ((__packed__));
#define ARPHRD_ETHER 1 /* Ethernet 10/100Mbps. */
#define INADDR_ANY ((ip_addr_t) 0x00000000)
#define INADDR_BROADCAST ((ip_addr_t) 0xffffffff)
#define INADDR_NONE ((ip_addr_t) 0xffffffff)
struct ip_header {
#if __BYTE_ORDER == __LITTLE_ENDIAN
uint8 header_length:4;
uint8 version:4;
#endif
#if __BYTE_ORDER == __BIG_ENDIAN
uint8 version:4;
uint8 header_length:4;
#endif
uint8 type_of_service;
uint16 total_length;
uint16 identifier;
uint16 fragment_offset;
uint8 time_to_live;
uint8 protocol;
uint16 checksum;
ip_addr_t source;
ip_addr_t destination;
} __attribute__ ((__packed__));
#define IP_PROTOCOL_VERSION_4 4
#define IP_DONT_FRAGMENT 0x4000 /* dont fragment flag */
#define IP_FRAGMENT_OFFSET_MASK 0x1fff /* mask for fragment offset */
#define IP_MAX_TIME_TO_LIVE 255 /* maximum time to live */
#define IP_DEFAULT_TIME_TO_LIVE 64 /* default ttl, from RFC 1340 */
#define IPPROTO_TCP 6
#define IPPROTO_UDP 17
struct udp_header {
uint16 source;
uint16 destination;
uint16 length;
uint16 checksum;
} __attribute__ ((__packed__));
struct tcp_header {
uint16 source;
uint16 destination;
uint32 seqNumber;
uint32 ackNumber;
#if __BYTE_ORDER == __BIG_ENDIAN
uint8 dataOffset : 4;
uint8 reserved : 4;
#elif __BYTE_ORDER == __LITTLE_ENDIAN
uint8 reserved : 4;
uint8 dataOffset : 4;
#endif
uint8 flags;
uint16 window;
uint16 checksum;
uint16 urgentPointer;
} __attribute__ ((__packed__));
#define TCP_FIN (1 << 0)
#define TCP_SYN (1 << 1)
#define TCP_RST (1 << 2)
#define TCP_PSH (1 << 3)
#define TCP_ACK (1 << 4)
#define TCP_URG (1 << 5)
#define TCP_ECE (1 << 6) // RFC 3168
#define TCP_CWR (1 << 7) // RFC 3168
extern const char *const kEthernetServiceName;
extern const char *const kARPServiceName;
extern const char *const kIPServiceName;
extern const char *const kUDPServiceName;
extern const char *const kTCPServiceName;
class NetService {
public:
NetService(const char *name);
virtual ~NetService();
const char *NetServiceName();
virtual int CountSubNetServices() const;
virtual NetService *SubNetServiceAt(int index) const;
virtual NetService *FindSubNetService(const char *name) const;
template<typename ServiceType>
ServiceType *FindSubNetService(const char *name) const
{
if (NetService *service = FindSubNetService(name))
return static_cast<ServiceType*>(service);
return NULL;
}
private:
const char *fName;
};
#endif