simple reliable networking over ethernet. Provides IPv4 ARP, ICMP echo reply, and UDP unicast. Does NOT provide TCP, that's not simple :-).

Committer:
altasoul
Date:
Tue Mar 31 22:27:25 2015 +0000
Revision:
2:397316d97354
Parent:
1:9c211ac06a12
Child:
3:59f3c806f127
Before first publication

Who changed what in which revision?

UserRevisionLine numberNew contents of line
altasoul 2:397316d97354 1 /*
altasoul 2:397316d97354 2 The MIT License (MIT)
altasoul 2:397316d97354 3
altasoul 2:397316d97354 4 Copyright (c) 2015 Tom Soulanille
altasoul 2:397316d97354 5
altasoul 2:397316d97354 6 Permission is hereby granted, free of charge, to any person obtaining a copy
altasoul 2:397316d97354 7 of this software and associated documentation files (the "Software"), to deal
altasoul 2:397316d97354 8 in the Software without restriction, including without limitation the rights
altasoul 2:397316d97354 9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
altasoul 2:397316d97354 10 copies of the Software, and to permit persons to whom the Software is
altasoul 2:397316d97354 11 furnished to do so, subject to the following conditions:
altasoul 2:397316d97354 12
altasoul 2:397316d97354 13 The above copyright notice and this permission notice shall be included in
altasoul 2:397316d97354 14 all copies or substantial portions of the Software.
altasoul 2:397316d97354 15
altasoul 2:397316d97354 16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
altasoul 2:397316d97354 17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
altasoul 2:397316d97354 18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
altasoul 2:397316d97354 19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
altasoul 2:397316d97354 20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
altasoul 2:397316d97354 21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
altasoul 2:397316d97354 22 THE SOFTWARE.
altasoul 2:397316d97354 23
altasoul 2:397316d97354 24 @file snet.h
altasoul 2:397316d97354 25 @purpose simple networking
altasoul 2:397316d97354 26 @version 0.1
altasoul 2:397316d97354 27 @date 31 March 2015
altasoul 2:397316d97354 28 @author Tom Soulanille
altasoul 2:397316d97354 29 */
altasoul 2:397316d97354 30
altasoul 0:6df0a6ed91d4 31 #ifndef _SNET_H_
altasoul 0:6df0a6ed91d4 32 #define _SNET_H_
altasoul 0:6df0a6ed91d4 33
altasoul 0:6df0a6ed91d4 34 #include "mbed.h"
altasoul 0:6df0a6ed91d4 35
altasoul 0:6df0a6ed91d4 36 #define ETH_RxOverrunInt (1 << 0)
altasoul 0:6df0a6ed91d4 37 #define ETH_RxErrorInt (1 << 1)
altasoul 0:6df0a6ed91d4 38 #define ETH_RxFinishedInt (1 << 2)
altasoul 0:6df0a6ed91d4 39 #define ETH_RxDoneInt (1 << 3)
altasoul 0:6df0a6ed91d4 40 #define ETH_TxUnderrunInt (1 << 4)
altasoul 0:6df0a6ed91d4 41 #define ETH_TxErrorInt (1 << 5)
altasoul 0:6df0a6ed91d4 42 #define ETH_TxFinishedInt (1 << 6)
altasoul 0:6df0a6ed91d4 43 #define ETH_TxDoneInt (1 << 7)
altasoul 0:6df0a6ed91d4 44
altasoul 0:6df0a6ed91d4 45 #define ETH_RxStatus (1 << 0)
altasoul 0:6df0a6ed91d4 46 #define ETH_TxStatus (1 << 1)
altasoul 0:6df0a6ed91d4 47
altasoul 0:6df0a6ed91d4 48 // offsets into an ethernet packet
altasoul 0:6df0a6ed91d4 49 #define ENET_DMAC_O 0
altasoul 0:6df0a6ed91d4 50 #define ENET_SMAC_O 6
altasoul 0:6df0a6ed91d4 51 #define ENET_ETHERTYPE_O 12
altasoul 0:6df0a6ed91d4 52 #define ENET_PAYLOAD_O 14
altasoul 0:6df0a6ed91d4 53
altasoul 0:6df0a6ed91d4 54 // ARP offsets
altasoul 0:6df0a6ed91d4 55 #define ENET_ARP_HTYPE_O (ENET_PAYLOAD + 0)
altasoul 0:6df0a6ed91d4 56 #define ENET_ARP_PTYPE_O (ENET_PAYLOAD + 2)
altasoul 0:6df0a6ed91d4 57 #define ENET_ARP_HLEN_O (ENET_PAYLOAD + 4)
altasoul 0:6df0a6ed91d4 58 #define ENET_ARP_PLEN_O (ENET_PAYLOAD + 5)
altasoul 0:6df0a6ed91d4 59 #define ENET_ARP_OPER_O (ENET_PAYLOAD_O + 6)
altasoul 0:6df0a6ed91d4 60 #define ENET_ARP_SHA_O (ENET_PAYLOAD_O + 8)
altasoul 0:6df0a6ed91d4 61 #define ENET_ARP_SPA_O (ENET_PAYLOAD_O + 14)
altasoul 0:6df0a6ed91d4 62 #define ENET_ARP_THA_O (ENET_PAYLOAD_O + 18)
altasoul 0:6df0a6ed91d4 63 #define ENET_ARP_TPA_O (ENET_PAYLOAD_O + 24)
altasoul 0:6df0a6ed91d4 64
altasoul 0:6df0a6ed91d4 65 // IP offsets
altasoul 0:6df0a6ed91d4 66 #define IP_HEADER_O ENET_PAYLOAD_O
altasoul 0:6df0a6ed91d4 67 #define IP_VIHL_O (ENET_PAYLOAD_O + 0)
altasoul 0:6df0a6ed91d4 68 #define IP_DSCP_ECN_O (ENET_PAYLOAD_O + 1)
altasoul 0:6df0a6ed91d4 69 #define IP_TOTAL_LENGTH_O (ENET_PAYLOAD_O + 2) // Total Length
altasoul 0:6df0a6ed91d4 70 #define IP_ID_O (ENET_PAYLOAD_O + 4)
altasoul 0:6df0a6ed91d4 71 #define IP_FLAGS_FRAGOFF_O (ENET_PAYLOAD_O + 6)
altasoul 0:6df0a6ed91d4 72 #define IP_TTL_O (ENET_PAYLOAD_O + 8)
altasoul 0:6df0a6ed91d4 73 #define IP_PROTO_O (ENET_PAYLOAD_O + 9)
altasoul 0:6df0a6ed91d4 74 #define IP_CHKSUM_O (ENET_PAYLOAD_O + 10)
altasoul 0:6df0a6ed91d4 75 #define IP_SADDR_O (ENET_PAYLOAD_O + 12)
altasoul 0:6df0a6ed91d4 76 #define IP_DADDR_O (ENET_PAYLOAD_O + 16)
altasoul 0:6df0a6ed91d4 77 #define IP_PAYLOAD_O (ENET_PAYLOAD_O + 20)
altasoul 0:6df0a6ed91d4 78 #define IP_HEADER_LEN (IP_PAYLOAD_O - ENET_PAYLOAD_O)
altasoul 0:6df0a6ed91d4 79
altasoul 0:6df0a6ed91d4 80 // ICMP offsets
altasoul 0:6df0a6ed91d4 81 #define ICMP_HEADER_O IP_PAYLOAD_O
altasoul 0:6df0a6ed91d4 82 #define ICMP_TYPE_O (ICMP_HEADER_O + 0)
altasoul 0:6df0a6ed91d4 83 #define ICMP_CODE_O (ICMP_HEADER_O + 1)
altasoul 0:6df0a6ed91d4 84 #define ICMP_CHECKSUM_O (ICMP_HEADER_O + 2)
altasoul 0:6df0a6ed91d4 85 #define ICMP_REST_OF_HEADER_O (ICMP_HEADER_O + 4)
altasoul 0:6df0a6ed91d4 86 #define ICMP_PAYLOAD_O (ICMP_HEADER_O + 8)
altasoul 0:6df0a6ed91d4 87 #define ICMP_HEADER_LEN (ICMP_PAYLOAD_O - ICMP_HEADER_O)
altasoul 0:6df0a6ed91d4 88
altasoul 0:6df0a6ed91d4 89 // UDP offsets
altasoul 0:6df0a6ed91d4 90 #define UDP_HEADER_O IP_PAYLOAD_O
altasoul 0:6df0a6ed91d4 91 #define UDP_SRC_PORT_O (UDP_HEADER_O + 0)
altasoul 0:6df0a6ed91d4 92 #define UDP_DST_PORT_O (UDP_HEADER_O + 2)
altasoul 0:6df0a6ed91d4 93 #define UDP_LENGTH_O (UDP_HEADER_O + 4)
altasoul 0:6df0a6ed91d4 94 #define UDP_CHECKSUM_O (UDP_HEADER_O + 6)
altasoul 0:6df0a6ed91d4 95 #define UDP_PAYLOAD_O (UDP_HEADER_O + 8)
altasoul 0:6df0a6ed91d4 96 #define UDP_HEADER_LEN (UDP_PAYLOAD_O - UDP_HEADER_O)
altasoul 0:6df0a6ed91d4 97
altasoul 2:397316d97354 98 /** Simple network class.
altasoul 2:397316d97354 99 * Very simple ARP, ICMP echo reply (ping), and UDP
altasoul 2:397316d97354 100 *
altasoul 2:397316d97354 101 * @author Tom Soulanille
altasoul 2:397316d97354 102 *
altasoul 2:397316d97354 103 * Typically you make a singleton instance of the Snet class.
altasoul 2:397316d97354 104 *
altasoul 2:397316d97354 105 * @code
altasoul 2:397316d97354 106 * //Example TBS
altasoul 2:397316d97354 107 * @endcode
altasoul 2:397316d97354 108 */
altasoul 0:6df0a6ed91d4 109 class Snet {
altasoul 0:6df0a6ed91d4 110 private:
altasoul 0:6df0a6ed91d4 111 static const uint8_t broadcast_mac[];// = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
altasoul 0:6df0a6ed91d4 112 static const uint8_t ipEtherType[];// = { 0x08, 0x00 };
altasoul 0:6df0a6ed91d4 113 static const uint8_t arp_req_payload_prefix[];// = { 0x0, 0x1, 0x8, 0x0, 0x6, 0x4, 0x0, 0x1 };
altasoul 0:6df0a6ed91d4 114 Ethernet eth;
altasoul 0:6df0a6ed91d4 115
altasoul 0:6df0a6ed91d4 116 uint8_t correspondent_facing_packet_header[UDP_PAYLOAD_O];
altasoul 0:6df0a6ed91d4 117
altasoul 0:6df0a6ed91d4 118 void got_broadcast(uint8_t *buf, int len);
altasoul 0:6df0a6ed91d4 119 void got_unicast(uint8_t *buf, int len);
altasoul 0:6df0a6ed91d4 120 void handle_arp_request(uint8_t *buf, int len);
altasoul 0:6df0a6ed91d4 121 uint16_t ones_complement_sum(const uint8_t *buf, int len, int sum);
altasoul 0:6df0a6ed91d4 122 uint16_t ip_checksum_of(const uint8_t *buf, const int len);
altasoul 0:6df0a6ed91d4 123 void turn_ip_packet_around(uint8_t *buf);
altasoul 0:6df0a6ed91d4 124 void handle_icmp_packet(uint8_t *buf, int len);
altasoul 0:6df0a6ed91d4 125 void interpret_inet_packet(uint8_t *buf, int len);
altasoul 0:6df0a6ed91d4 126 void turn_udp_packet_around(uint8_t *buf);
altasoul 2:397316d97354 127 /**
altasoul 2:397316d97354 128 * Send a UDP packet addressed as in buf, with specified payload
altasoul 2:397316d97354 129 */
altasoul 0:6df0a6ed91d4 130 void send_udp_packet(uint8_t *buf, const uint8_t *payload, int payload_len);
altasoul 0:6df0a6ed91d4 131 void handle_udp_packet(uint8_t *buf, int len);
altasoul 1:9c211ac06a12 132
altasoul 0:6df0a6ed91d4 133 public:
altasoul 2:397316d97354 134
altasoul 2:397316d97354 135 /** Constructor
altasoul 2:397316d97354 136 */
altasoul 0:6df0a6ed91d4 137 Snet();
altasoul 2:397316d97354 138
altasoul 2:397316d97354 139 /** Constructor
altasoul 2:397316d97354 140 * @param <my_ip> The IP address to use for me, pointer to array of four bytes
altasoul 2:397316d97354 141 */
altasoul 0:6df0a6ed91d4 142 Snet(const uint8_t *my_ip);
altasoul 2:397316d97354 143
altasoul 0:6df0a6ed91d4 144 uint8_t my_mac[6];
altasoul 0:6df0a6ed91d4 145 uint8_t my_ip[4];
altasoul 0:6df0a6ed91d4 146 volatile uint32_t enet_rx_cnt;
altasoul 0:6df0a6ed91d4 147 uint8_t correspondent_mac[6]; // correspondent's MAC
altasoul 2:397316d97354 148
altasoul 2:397316d97354 149 /**
altasoul 2:397316d97354 150 * Receive and process packets until none available
altasoul 2:397316d97354 151 */
altasoul 1:9c211ac06a12 152 int rx_and_process_available_packets();
altasoul 2:397316d97354 153
altasoul 2:397316d97354 154 /** UDP handler function pointer
altasoul 2:397316d97354 155 */
altasoul 1:9c211ac06a12 156 void (*registered_udp_handler)(uint8_t *buf, int len);
altasoul 2:397316d97354 157
altasoul 2:397316d97354 158 /**
altasoul 2:397316d97354 159 * Set the correspondent to whom we will send UDP packets
altasoul 2:397316d97354 160 */
altasoul 1:9c211ac06a12 161 void set_udp_correspondent(uint8_t *buf, int len);
altasoul 2:397316d97354 162
altasoul 2:397316d97354 163 /**
altasoul 2:397316d97354 164 * Send UDP packet to correspondent
altasoul 2:397316d97354 165 *
altasoul 2:397316d97354 166 * @param <what>
altasoul 2:397316d97354 167 */
altasoul 0:6df0a6ed91d4 168 void send_to_correspondent(const uint8_t *what, int what_len);
altasoul 2:397316d97354 169
altasoul 2:397316d97354 170 /**
altasoul 2:397316d97354 171 * Send string to correspondent
altasoul 2:397316d97354 172 * @param <s> string to send
altasoul 2:397316d97354 173 */
altasoul 2:397316d97354 174 void tell_udp_correspondent(char *s);
altasoul 2:397316d97354 175
altasoul 2:397316d97354 176 /**
altasoul 2:397316d97354 177 * Send a UDP packet to the sender of this one
altasoul 2:397316d97354 178 *
altasoul 2:397316d97354 179 * @param <buf> The UDP packet to which we are replying
altasoul 2:397316d97354 180 * @param <payload> The UDP payload to use for this packet
altasoul 2:397316d97354 181 */
altasoul 1:9c211ac06a12 182 void return_udp_packet(uint8_t *buf, const uint8_t *payload, int payload_len);
altasoul 0:6df0a6ed91d4 183 };
altasoul 0:6df0a6ed91d4 184
altasoul 0:6df0a6ed91d4 185 #endif