adding comments here and there

This commit is contained in:
giomba 2019-12-24 23:41:31 +01:00
parent 5c7b1ffc99
commit 260f537125
6 changed files with 53 additions and 33 deletions

View File

@ -3,6 +3,7 @@
#include "slip.h" #include "slip.h"
#include "udp.h" #include "udp.h"
/* an UDP application, which simply replies HELLO-WORLD-UDP */
int udp_server(char* output_buffer, const char* input_buffer, int len) { int udp_server(char* output_buffer, const char* input_buffer, int len) {
const char msg[] = "HELLO-WORLD-UDP\n"; const char msg[] = "HELLO-WORLD-UDP\n";
digitalWrite(13, !digitalRead(13)); digitalWrite(13, !digitalRead(13));
@ -12,10 +13,25 @@ int udp_server(char* output_buffer, const char* input_buffer, int len) {
void setup() { void setup() {
pinMode(13, OUTPUT); pinMode(13, OUTPUT);
Serial.begin(19200);
memcpy(&coppino::address, "\x20\x01\x04\x70\xc8\x44\x00\x31\x00\x00\x00\x00\x00\x00\xca\xfe", 16);
/* setup serial for Internet connectivity
* attach a SLIP daemon on the other endpoint; a good one is `tunslip6` by Contiki
* $ tunslip6 -s /dev/ttyUSB0 -L -v5 -B 19200 2001:db8:1324::1/64
* Note: the address given is the one on the host it is running on
*/
Serial.begin(19200);
/* set unique identifier of network hardware. It MUST be unique!
* For example, this could be your microcontroller serial number
* Note: pay attention to enter exactly 64 bits / 8 bytes
*/
ipv6::setEUI("\xde\xad\xbe\xef\x12\x34\x56\x78");
/* enable or disable IPv6 Stateless Auto-Configuration (SLAAC) */
ipv6::SLAAC(false);
/* set global address -- will be overwritten if SLAAC is enabled and a Router Advertisement is received */
ipv6::setGlobalAddress("\x20\x01\x04\x70\xc8\x44\x00\x31\x00\x00\x00\x00\x00\x00\xca\xfe");
/* start a server un UDP port 80 */
udp::set_handler(80, udp_server); udp::set_handler(80, udp_server);
} }

View File

@ -5,12 +5,6 @@
namespace coppino { namespace coppino {
const uint8_t LEN = 128; const uint8_t LEN = 128;
extern ipv6::IPv6Addr address;
/* netmask:
* no netmask is needed, because everything is sent over TTL UART
* gateway:
* the same as above
*/
void handler(void); void handler(void);
void hexdump(const char* pointer, int len); void hexdump(const char* pointer, int len);

View File

@ -1,8 +1,6 @@
#include "coppino.h" #include "coppino.h"
namespace coppino { namespace coppino {
ipv6::IPv6Addr address;
void handler() { void handler() {
int r; int r;

24
ipv6.h
View File

@ -2,17 +2,18 @@
#define COPPINO_IPV6_H #define COPPINO_IPV6_H
namespace ipv6 { namespace ipv6 {
/* maximum length for an IPv6 packet */
const uint8_t LEN = 128; const uint8_t LEN = 128;
/* ICMP Types */
const uint8_t ICMP_ECHO_REQUEST_TYPE = 128; const uint8_t ICMP_ECHO_REQUEST_TYPE = 128;
const uint8_t ICMP_ECHO_REPLY_TYPE = 129; const uint8_t ICMP_ECHO_REPLY_TYPE = 129;
const uint8_t ICMP_RADV_TYPE = 134; const uint8_t ICMP_RADV_TYPE = 134;
/* Next-Header Types */
const uint8_t NH_ICMP = 58; const uint8_t NH_ICMP = 58;
const uint8_t NH_UDP = 17; const uint8_t NH_UDP = 17;
extern uint8_t HOP_LIMIT;
class IPv6Addr { class IPv6Addr {
private: private:
char address[16]; char address[16];
@ -21,18 +22,8 @@ namespace ipv6 {
IPv6Addr(const char* address); IPv6Addr(const char* address);
}; };
extern const IPv6Addr LINK_LOCAL_ADDRESS;
extern const IPv6Addr ALL_NODES_ADDRESS; extern const IPv6Addr ALL_NODES_ADDRESS;
struct ipv6_packet_header {
char field[4];
char len[2];
char next_header;
char hop_limit;
IPv6Addr src_addr;
IPv6Addr dst_addr;
}__attribute__((packed));
class IPv6Packet { class IPv6Packet {
private: private:
char packet[LEN]; char packet[LEN];
@ -53,6 +44,7 @@ namespace ipv6 {
void doAction(); void doAction();
}; };
/* incoming and outgoing packets buffer */
extern IPv6Packet packetin; extern IPv6Packet packetin;
extern IPv6Packet packetout; extern IPv6Packet packetout;
@ -69,6 +61,7 @@ namespace ipv6 {
int len /* IPv6 payload length */ int len /* IPv6 payload length */
); );
/* RFC 4861 -- begin */
struct ICMPv6_RADV { struct ICMPv6_RADV {
uint8_t type; uint8_t type;
uint8_t code; uint8_t code;
@ -95,6 +88,11 @@ namespace ipv6 {
uint32_t reserved2; uint32_t reserved2;
char prefix[16]; char prefix[16];
}; };
/* RFC 4861 -- end */
void setEUI(const char* eui); /* 64bit Extended Unique Identifier */
void SLAAC(bool enable); /* enable IPv6 automatic prefix configuration (listens for RADV) */
void setGlobalAddress(const char* address); /* global IPv6 address, manually configured */
} }
#endif #endif

View File

@ -4,16 +4,30 @@
namespace ipv6 { namespace ipv6 {
/******** costants ********/ /******** costants ********/
const IPv6Addr ALL_NODES_ADDRESS("\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"); /* ff02::1 */ const IPv6Addr ALL_NODES_ADDRESS("\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"); /* ff02::1 */
const IPv6Addr LINK_LOCAL_ADDRESS("\xfe\x80\x00\x00\x00\x00\x00\x00\xde\xad\xbe\xef\x12\x34\x56\x78"); /* fe80::dead:beef:1234:5678 */ /* TODO */
/******** variables ********/ /******** variables ********/
uint8_t HOP_LIMIT = 64; uint8_t HOP_LIMIT = 64;
IPv6Addr LINK_LOCAL_ADDRESS;
IPv6Addr GLOBAL_ADDRESS;
bool slaac_enable;
/******** buffer ********/ /******** buffers ********/
IPv6Packet packetin; IPv6Packet packetin;
IPv6Packet packetout; IPv6Packet packetout;
/******** FUNCTIONS *******/ /******** FUNCTIONS *******/
void setEUI(const char* eui) {
memset(&LINK_LOCAL_ADDRESS, 0, 16);
memcpy(&LINK_LOCAL_ADDRESS, "\xfe\x80", 2);
memcpy( ((char*)&LINK_LOCAL_ADDRESS) + 8 , eui, 8);
}
void SLAAC(bool enable) {
slaac_enable = enable;
}
void setGlobalAddress(const char* address) {
memcpy(&GLOBAL_ADDRESS, address, 16);
}
uint16_t compute_checksum(const IPv6Addr* src_addr, const IPv6Addr* dst_addr, uint8_t next_header, int upper_len, const char* payload, int len) { uint16_t compute_checksum(const IPv6Addr* src_addr, const IPv6Addr* dst_addr, uint8_t next_header, int upper_len, const char* payload, int len) {
char buffer[LEN]; char buffer[LEN];
uint32_t total; uint32_t total;
@ -120,7 +134,7 @@ void IPv6Packet::doAction() {
if ( if (
(memcmp(&(ALL_NODES_ADDRESS), packet + 24, 16) == 0) || (memcmp(&(ALL_NODES_ADDRESS), packet + 24, 16) == 0) ||
(memcmp(&(LINK_LOCAL_ADDRESS), packet + 24, 16) == 0) || (memcmp(&(LINK_LOCAL_ADDRESS), packet + 24, 16) == 0) ||
(memcmp(&(coppino::address), packet + 24, 16) == 0)) { (memcmp(&(GLOBAL_ADDRESS), packet + 24, 16) == 0)) {
int ilen = this->getLen(); /* input payload length */ int ilen = this->getLen(); /* input payload length */
int olen; /* output payload length */ int olen; /* output payload length */
@ -149,9 +163,12 @@ void IPv6Packet::doAction() {
/* no other protocols are known here, sorry :-) */ /* no other protocols are known here, sorry :-) */
break; break;
} }
} } /* ...else discard packet */
} }
/* handles ICMP and (possibly) generate a reply
* returns length of generated packet (written to output_buffer), or -1 if there is no reply packet
*/
int handleICMP(char* output_buffer, const char* input_buffer, int len) { int handleICMP(char* output_buffer, const char* input_buffer, int len) {
uint8_t type = *(input_buffer); uint8_t type = *(input_buffer);
@ -190,7 +207,7 @@ int handleICMP(char* output_buffer, const char* input_buffer, int len) {
memcpy(output_buffer + 2, &checksum, 2); memcpy(output_buffer + 2, &checksum, 2);
return len; return len;
} else if (type == ICMP_RADV_TYPE) { /* if it is IVMPc6 Router Advertisement, then... */ } else if (type == ICMP_RADV_TYPE && slaac_enable) { /* if it is IVMPc6 Router Advertisement, then... */
ICMPv6_RADV* radv = (ICMPv6_RADV*)input_buffer; ICMPv6_RADV* radv = (ICMPv6_RADV*)input_buffer;
HOP_LIMIT = (radv->cur_hop_limit != 0) ? radv->cur_hop_limit : 64; HOP_LIMIT = (radv->cur_hop_limit != 0) ? radv->cur_hop_limit : 64;
@ -198,13 +215,12 @@ int handleICMP(char* output_buffer, const char* input_buffer, int len) {
ICMPv6_RADV_Option* option = (ICMPv6_RADV_Option*) (radv + 1); ICMPv6_RADV_Option* option = (ICMPv6_RADV_Option*) (radv + 1);
option != input_buffer + len; option != input_buffer + len;
option = (ICMPv6_RADV_Option*) ( ((char*)(option)) + option->len )) { option = (ICMPv6_RADV_Option*) ( ((char*)(option)) + option->len )) {
digitalWrite(13, !digitalRead(13));
if (option->type == 3 && option->len == 4) { /* if it is a ICMPv6 Prefix Information, then... */ if (option->type == 3 && option->len == 4) { /* if it is a ICMPv6 Prefix Information, then... */
ICMPv6_RADV_PrefixInformation* p = (ICMPv6_RADV_PrefixInformation*) option; ICMPv6_RADV_PrefixInformation* p = (ICMPv6_RADV_PrefixInformation*) option;
if (p->prefix_length != 64) continue; /* only /64 prefix is supported */ if (p->prefix_length != 64) continue; /* only /64 prefix is supported */
if (! (p->la_flags & 0x40)) continue; /* only SLAAC is supported */ if (! (p->la_flags & 0x40)) continue; /* only SLAAC is supported */
memcpy(&coppino::address, p->prefix, 8); /* set prefix -- leave host bits unchanged */ memcpy(&GLOBAL_ADDRESS, p->prefix, 8); /* set prefix -- leave host bits unchanged */
break; break;
} }
} }

View File

@ -49,8 +49,6 @@ namespace slip {
} }
} }
} }
return i; return i;
} }