From 260f5371253d031cce58a1ffadf83b46e95777a2 Mon Sep 17 00:00:00 2001 From: giomba Date: Tue, 24 Dec 2019 23:41:31 +0100 Subject: [PATCH] adding comments here and there --- coppino-main.ino | 22 +++++++++++++++++++--- coppino.h | 6 ------ coppino.ino | 2 -- ipv6.h | 24 +++++++++++------------- ipv6.ino | 30 +++++++++++++++++++++++------- slip.ino | 2 -- 6 files changed, 53 insertions(+), 33 deletions(-) diff --git a/coppino-main.ino b/coppino-main.ino index 1090997..b719db1 100644 --- a/coppino-main.ino +++ b/coppino-main.ino @@ -3,6 +3,7 @@ #include "slip.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) { const char msg[] = "HELLO-WORLD-UDP\n"; digitalWrite(13, !digitalRead(13)); @@ -12,10 +13,25 @@ int udp_server(char* output_buffer, const char* input_buffer, int len) { void setup() { 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); } diff --git a/coppino.h b/coppino.h index badf8aa..e917fd8 100644 --- a/coppino.h +++ b/coppino.h @@ -5,12 +5,6 @@ namespace coppino { 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 hexdump(const char* pointer, int len); diff --git a/coppino.ino b/coppino.ino index 144050f..9f96e6e 100644 --- a/coppino.ino +++ b/coppino.ino @@ -1,8 +1,6 @@ #include "coppino.h" namespace coppino { - ipv6::IPv6Addr address; - void handler() { int r; diff --git a/ipv6.h b/ipv6.h index 2bf1f46..8a271b4 100644 --- a/ipv6.h +++ b/ipv6.h @@ -2,17 +2,18 @@ #define COPPINO_IPV6_H namespace ipv6 { - + /* maximum length for an IPv6 packet */ const uint8_t LEN = 128; + + /* ICMP Types */ const uint8_t ICMP_ECHO_REQUEST_TYPE = 128; const uint8_t ICMP_ECHO_REPLY_TYPE = 129; const uint8_t ICMP_RADV_TYPE = 134; + /* Next-Header Types */ const uint8_t NH_ICMP = 58; const uint8_t NH_UDP = 17; - extern uint8_t HOP_LIMIT; - class IPv6Addr { private: char address[16]; @@ -21,18 +22,8 @@ namespace ipv6 { IPv6Addr(const char* address); }; - extern const IPv6Addr LINK_LOCAL_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 { private: char packet[LEN]; @@ -53,6 +44,7 @@ namespace ipv6 { void doAction(); }; + /* incoming and outgoing packets buffer */ extern IPv6Packet packetin; extern IPv6Packet packetout; @@ -69,6 +61,7 @@ namespace ipv6 { int len /* IPv6 payload length */ ); + /* RFC 4861 -- begin */ struct ICMPv6_RADV { uint8_t type; uint8_t code; @@ -95,6 +88,11 @@ namespace ipv6 { uint32_t reserved2; 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 diff --git a/ipv6.ino b/ipv6.ino index 61c32f2..e4df658 100644 --- a/ipv6.ino +++ b/ipv6.ino @@ -4,16 +4,30 @@ namespace ipv6 { /******** 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 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 ********/ uint8_t HOP_LIMIT = 64; +IPv6Addr LINK_LOCAL_ADDRESS; +IPv6Addr GLOBAL_ADDRESS; +bool slaac_enable; -/******** buffer ********/ +/******** buffers ********/ IPv6Packet packetin; IPv6Packet packetout; /******** 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) { char buffer[LEN]; uint32_t total; @@ -120,7 +134,7 @@ void IPv6Packet::doAction() { if ( (memcmp(&(ALL_NODES_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 olen; /* output payload length */ @@ -149,9 +163,12 @@ void IPv6Packet::doAction() { /* no other protocols are known here, sorry :-) */ 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) { 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); 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; 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); option != input_buffer + 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... */ ICMPv6_RADV_PrefixInformation* p = (ICMPv6_RADV_PrefixInformation*) option; if (p->prefix_length != 64) continue; /* only /64 prefix 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; } } diff --git a/slip.ino b/slip.ino index bdf674a..5866f79 100644 --- a/slip.ino +++ b/slip.ino @@ -49,8 +49,6 @@ namespace slip { } } } - - return i; }