adding comments here and there
This commit is contained in:
parent
5c7b1ffc99
commit
260f537125
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -1,8 +1,6 @@
|
||||
#include "coppino.h"
|
||||
|
||||
namespace coppino {
|
||||
ipv6::IPv6Addr address;
|
||||
|
||||
void handler() {
|
||||
int r;
|
||||
|
||||
|
24
ipv6.h
24
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
|
||||
|
30
ipv6.ino
30
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;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user