1/* 2 * Copyright (c) 2014, University of Washington. 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, Universitaetstr. 6, CH-8092 Zurich. 8 * Attn: Systems Group. 9 */ 10 11#ifndef ARRANET_IMPL_H 12#define ARRANET_IMPL_H 13 14#ifndef ETHARP_HWADDR_LEN 15#define ETHARP_HWADDR_LEN 6 16#endif 17 18PACK_STRUCT_BEGIN 19struct eth_addr { 20 PACK_STRUCT_FIELD(u8_t addr[ETHARP_HWADDR_LEN]); 21} PACK_STRUCT_STRUCT; 22PACK_STRUCT_END 23 24PACK_STRUCT_BEGIN 25/** Ethernet header */ 26struct eth_hdr { 27#if ETH_PAD_SIZE 28 PACK_STRUCT_FIELD(u8_t padding[ETH_PAD_SIZE]); 29#endif 30 PACK_STRUCT_FIELD(struct eth_addr dest); 31 PACK_STRUCT_FIELD(struct eth_addr src); 32 PACK_STRUCT_FIELD(u16_t type); 33} PACK_STRUCT_STRUCT; 34PACK_STRUCT_END 35 36#define SIZEOF_ETH_HDR (14 + ETH_PAD_SIZE) 37 38PACK_STRUCT_BEGIN 39/** the ARP message, see RFC 826 ("Packet format") */ 40struct etharp_hdr { 41 PACK_STRUCT_FIELD(u16_t hwtype); 42 PACK_STRUCT_FIELD(u16_t proto); 43 PACK_STRUCT_FIELD(u8_t hwlen); 44 PACK_STRUCT_FIELD(u8_t protolen); 45 PACK_STRUCT_FIELD(u16_t opcode); 46 PACK_STRUCT_FIELD(struct eth_addr shwaddr); 47 PACK_STRUCT_FIELD(struct ip_addr2 sipaddr); 48 PACK_STRUCT_FIELD(struct eth_addr dhwaddr); 49 PACK_STRUCT_FIELD(struct ip_addr2 dipaddr); 50} PACK_STRUCT_STRUCT; 51PACK_STRUCT_END 52 53#define SIZEOF_ETHARP_HDR 28 54#define SIZEOF_ETHARP_PACKET (SIZEOF_ETH_HDR + SIZEOF_ETHARP_HDR) 55 56#define ETHTYPE_ARP 0x0806U 57#define ETHTYPE_IP 0x0800U 58#define ETHTYPE_VLAN 0x8100U 59#define ETHTYPE_PPPOEDISC 0x8863U /* PPP Over Ethernet Discovery Stage */ 60#define ETHTYPE_PPPOE 0x8864U /* PPP Over Ethernet Session Stage */ 61 62#define ETH_PAD_SIZE 0 63 64/** ARP message types (opcodes) */ 65#define ARP_REQUEST 1 66#define ARP_REPLY 2 67 68PACK_STRUCT_BEGIN 69struct ip_hdr { 70 /* version / header length */ 71 PACK_STRUCT_FIELD(u8_t _v_hl); 72 /* type of service */ 73 PACK_STRUCT_FIELD(u8_t _tos); 74 /* total length */ 75 PACK_STRUCT_FIELD(u16_t _len); 76 /* identification */ 77 PACK_STRUCT_FIELD(u16_t _id); 78 /* fragment offset field */ 79 PACK_STRUCT_FIELD(u16_t _offset); 80#define IP_RF 0x8000U /* reserved fragment flag */ 81#define IP_DF 0x4000U /* dont fragment flag */ 82#define IP_MF 0x2000U /* more fragments flag */ 83#define IP_OFFMASK 0x1fffU /* mask for fragmenting bits */ 84 /* time to live */ 85 PACK_STRUCT_FIELD(u8_t _ttl); 86 /* protocol*/ 87 PACK_STRUCT_FIELD(u8_t _proto); 88 /* checksum */ 89 PACK_STRUCT_FIELD(u16_t _chksum); 90 /* source and destination IP addresses */ 91 PACK_STRUCT_FIELD(ip_addr_p_t src); 92 PACK_STRUCT_FIELD(ip_addr_p_t dest); 93} PACK_STRUCT_STRUCT; 94PACK_STRUCT_END 95 96#define IPH_V(hdr) ((hdr)->_v_hl >> 4) 97#define IPH_HL(hdr) ((hdr)->_v_hl & 0x0f) 98#define IPH_TOS(hdr) ((hdr)->_tos) 99#define IPH_LEN(hdr) ((hdr)->_len) 100#define IPH_ID(hdr) ((hdr)->_id) 101#define IPH_OFFSET(hdr) ((hdr)->_offset) 102#define IPH_TTL(hdr) ((hdr)->_ttl) 103#define IPH_PROTO(hdr) ((hdr)->_proto) 104#define IPH_CHKSUM(hdr) ((hdr)->_chksum) 105 106#define IPH_VHL_SET(hdr, v, hl) (hdr)->_v_hl = (((v) << 4) | (hl)) 107#define IPH_TOS_SET(hdr, tos) (hdr)->_tos = (tos) 108#define IPH_LEN_SET(hdr, len) (hdr)->_len = (len) 109#define IPH_ID_SET(hdr, id) (hdr)->_id = (id) 110#define IPH_OFFSET_SET(hdr, off) (hdr)->_offset = (off) 111#define IPH_TTL_SET(hdr, ttl) (hdr)->_ttl = (u8_t)(ttl) 112#define IPH_PROTO_SET(hdr, proto) (hdr)->_proto = (u8_t)(proto) 113#define IPH_CHKSUM_SET(hdr, chksum) (hdr)->_chksum = (chksum) 114 115#define IP_HLEN 20 116 117#define IP_PROTO_IP 0 118#define IP_PROTO_ICMP 1 119#define IP_PROTO_IGMP 2 120#define IP_PROTO_IPENCAP 4 121#define IP_PROTO_UDP 17 122#define IP_PROTO_UDPLITE 136 123#define IP_PROTO_TCP 6 124 125PACK_STRUCT_BEGIN 126struct udp_hdr { 127 PACK_STRUCT_FIELD(u16_t src); 128 PACK_STRUCT_FIELD(u16_t dest); /* src/dest UDP ports */ 129 PACK_STRUCT_FIELD(u16_t len); 130 PACK_STRUCT_FIELD(u16_t chksum); 131} PACK_STRUCT_STRUCT; 132PACK_STRUCT_END 133 134PACK_STRUCT_BEGIN 135struct tcp_hdr { 136 PACK_STRUCT_FIELD(u16_t src); 137 PACK_STRUCT_FIELD(u16_t dest); 138 PACK_STRUCT_FIELD(u32_t seqno); 139 PACK_STRUCT_FIELD(u32_t ackno); 140 PACK_STRUCT_FIELD(u16_t _hdrlen_rsvd_flags); 141 PACK_STRUCT_FIELD(u16_t wnd); 142 PACK_STRUCT_FIELD(u16_t chksum); 143 PACK_STRUCT_FIELD(u16_t urgp); 144} PACK_STRUCT_STRUCT; 145PACK_STRUCT_END 146 147#define TCP_FIN 0x01U 148#define TCP_SYN 0x02U 149#define TCP_RST 0x04U 150#define TCP_PSH 0x08U 151#define TCP_ACK 0x10U 152#define TCP_URG 0x20U 153#define TCP_ECE 0x40U 154#define TCP_CWR 0x80U 155 156#define TCP_FLAGS 0x3fU 157 158/* Length of the TCP header, excluding options. */ 159#define TCP_HLEN 20 160 161#define TCPH_HDRLEN(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) >> 12) 162#define TCPH_FLAGS(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) & TCP_FLAGS) 163 164#define TCPH_HDRLEN_SET(phdr, len) (phdr)->_hdrlen_rsvd_flags = htons(((len) << 12) | TCPH_FLAGS(phdr)) 165#define TCPH_FLAGS_SET(phdr, flags) (phdr)->_hdrlen_rsvd_flags = (((phdr)->_hdrlen_rsvd_flags & PP_HTONS((u16_t)(~(u16_t)(TCP_FLAGS)))) | htons(flags)) 166#define TCPH_HDRLEN_FLAGS_SET(phdr, len, flags) (phdr)->_hdrlen_rsvd_flags = htons(((len) << 12) | (flags)) 167 168#define TCPH_SET_FLAG(phdr, flags ) (phdr)->_hdrlen_rsvd_flags = ((phdr)->_hdrlen_rsvd_flags | htons(flags)) 169#define TCPH_UNSET_FLAG(phdr, flags) (phdr)->_hdrlen_rsvd_flags = htons(ntohs((phdr)->_hdrlen_rsvd_flags) | (TCPH_FLAGS(phdr) & ~(flags)) ) 170 171#define TCP_TCPLEN(seg) ((seg)->len + ((TCPH_FLAGS((seg)->tcphdr) & (TCP_FIN | TCP_SYN)) != 0)) 172 173/** This returns a TCP header option for MSS in an u32_t */ 174#define TCP_BUILD_MSS_OPTION(mss) htonl(0x02040000 | ((mss) & 0xFFFF)) 175 176void lwip_mutex_lock(void); 177void lwip_mutex_unlock(void); 178 179// XXX: These assume a little-endian system! 180/* These macros should be calculated by the preprocessor and are used 181 with compile-time constants only (so that there is no little-endian 182 overhead at runtime). */ 183#define PP_HTONS(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8)) 184#define PP_NTOHS(x) PP_HTONS(x) 185#define PP_HTONL(x) ((((x) & 0xff) << 24) | \ 186 (((x) & 0xff00) << 8) | \ 187 (((x) & 0xff0000UL) >> 8) | \ 188 (((x) & 0xff000000UL) >> 24)) 189#define PP_NTOHL(x) PP_HTONL(x) 190 191#define lwip_htons(x) LWIP_PLATFORM_HTONS(x) 192#define lwip_ntohs(x) LWIP_PLATFORM_HTONS(x) 193#define lwip_htonl(x) LWIP_PLATFORM_HTONL(x) 194#define lwip_ntohl(x) LWIP_PLATFORM_HTONL(x) 195 196#define ip_addr_isbroadcast(ipaddr, netif) ip4_addr_isbroadcast((ipaddr)->addr, (netif)) 197u8_t ip4_addr_isbroadcast(u32_t addr, const struct netif *netif); 198 199#define ip_addr_netmask_valid(netmask) ip4_addr_netmask_valid((netmask)->addr) 200u8_t ip4_addr_netmask_valid(u32_t netmask); 201 202u32_t ipaddr_addr(const char *cp); 203int ipaddr_aton(const char *cp, ip_addr_t *addr); 204/** returns ptr to static buffer; not reentrant! */ 205char *ipaddr_ntoa(const ip_addr_t *addr); 206char *ipaddr_ntoa_r(const ip_addr_t *addr, char *buf, int buflen); 207 208#endif 209