From 9beb97fdba320d91f43186a9b25900fa932e5ab6 Mon Sep 17 00:00:00 2001 From: giomba Date: Tue, 24 Dec 2019 19:33:07 +0100 Subject: [PATCH] software engeneering for better resrouce management now reproduced also in UDP, not only ICMP This patch also allows for a better ISO/OSI layer separation between IPv6 and upper layers, and upper layers can use the same common interface --- coppino-main.ino | 6 ++++-- ipv6.h | 4 +++- ipv6.ino | 26 ++++++++++++++++++++------ udp.h | 7 ++++--- udp.ino | 48 +++++++++++++++++++++++++----------------------- 5 files changed, 56 insertions(+), 35 deletions(-) diff --git a/coppino-main.ino b/coppino-main.ino index fcfb44b..1090997 100644 --- a/coppino-main.ino +++ b/coppino-main.ino @@ -3,9 +3,11 @@ #include "slip.h" #include "udp.h" -void udp_server(const char* buffer, int len) { +int udp_server(char* output_buffer, const char* input_buffer, int len) { + const char msg[] = "HELLO-WORLD-UDP\n"; digitalWrite(13, !digitalRead(13)); - + memcpy(output_buffer, msg, strlen(msg)); + return strlen(msg); } void setup() { diff --git a/ipv6.h b/ipv6.h index 15764d5..30d5b83 100644 --- a/ipv6.h +++ b/ipv6.h @@ -35,7 +35,8 @@ namespace ipv6 { public: IPv6Packet(); IPv6Packet(const char* buffer, int len); - void IPv6Packet::setLen(int len); + void setLen(int len); + int getLen(); void setSrcAddress(const IPv6Addr* address); const IPv6Addr* getSrcAddress(); void setDstAddress(const IPv6Addr* address); @@ -43,6 +44,7 @@ namespace ipv6 { void setNextHeader(uint8_t next_header); void setFlow(const char* flow); void setPayload(char* payload, int len); + void send(); void doAction(); }; diff --git a/ipv6.ino b/ipv6.ino index 74ae7c3..ad4865f 100644 --- a/ipv6.ino +++ b/ipv6.ino @@ -75,6 +75,9 @@ void IPv6Packet::setLen(int len) { *(packet + 4) = len >> 8; *(packet + 5) = len & 0xff; } +int IPv6Packet::getLen() { + return ((*(packet + 4)) << 8) + (*(packet + 5)); +} void IPv6Packet::setSrcAddress(const IPv6Addr* address) { memcpy(packet + 8, address, 16); @@ -104,25 +107,36 @@ void IPv6Packet::setPayload(char* payload, int len) { memcpy(packet + 40, payload, len); /* payload */ } +void IPv6Packet::send() { + slip::send(packet, 40 + this->getLen()); +} + void IPv6Packet::doAction() { /* if destination is my address, or destination is "all nodes" address, then... */ if ((memcmp(&(ALL_NODES_ADDRESS), packet + 24, 16) == 0) || (memcmp(&(coppino::address), packet + 24, 16) == 0)) { - int ilen = ((*(packet + 4)) << 8) + (*(packet + 5)); /* input payload length */ - int olen; /* output payload length */ + int ilen = this->getLen(); /* input payload length */ + int olen; /* output payload length */ switch(*(packet + 6)) { /* next header */ case NH_ICMP: if ((olen = handleICMP((char*)&packetout + 40, packet + 40, ilen)) != -1) { packetout.setLen(olen); - packetout.setFlow((char*)&packetin + 1); + packetout.setFlow(((char*)(&packetin)) + 1); packetout.setSrcAddress(packetin.getDstAddress()); packetout.setDstAddress(packetin.getSrcAddress()); packetout.setNextHeader(NH_ICMP); - slip::send((void*)&packetout, 40 + olen); + packetout.send(); } break; case NH_UDP: - //udp::handleUDP((IPv6Addr*)(packet + 8), (IPv6Addr*)(packet + 24), packet + 1, packet + 40, len); + if ((olen = udp::handleUDP((char*)&packetout + 40, packet + 40, ilen)) != -1) { + packetout.setLen(olen); + packetout.setFlow(((char*)(&packetin)) + 1); + packetout.setSrcAddress(packetin.getDstAddress()); + packetout.setDstAddress(packetin.getSrcAddress()); + packetout.setNextHeader(NH_UDP); + packetout.send(); + } break; default: /* no other protocols are known here, sorry :-) */ @@ -131,7 +145,7 @@ void IPv6Packet::doAction() { } } -int handleICMP(char* output_buffer, const char* input_buffer, int len) { //const IPv6Addr* src_addr, const IPv6Addr* dst_addr, const char* flow, char* packet, int len) { +int handleICMP(char* output_buffer, const char* input_buffer, int len) { uint8_t type = *(input_buffer); if (type == ICMP_ECHO_REQUEST_TYPE) { /* if it is ICMPv6 Echo Request, then... */ diff --git a/udp.h b/udp.h index e7eb9ec..fefee76 100644 --- a/udp.h +++ b/udp.h @@ -16,16 +16,17 @@ namespace udp { uint16_t getSrcPort(); void setDstPort(uint16_t port); uint16_t getDstPort(); + const char* UDPPacket::getPayload(); void setPayload(const char* payload, int len); void computeChecksum(const ipv6::IPv6Addr* src_addr, const ipv6::IPv6Addr* dst_addr, int len); }; - void handleUDP(const ipv6::IPv6Addr* src_addr, const ipv6::IPv6Addr* dst_addr, const char* flow, char* packet, int len); + int handleUDP(char* output_buffer, const char* input_buffer, int len); - extern void(*server_handler) (const char* buffer, int size); + extern int(*server_handler) (char* output_buffer, const char* buffer, int size); extern uint16_t server_port; - void set_handler(uint16_t port, void(* handler) (const char* buffer, int size)); + void set_handler(uint16_t port, int(* handler) (char* output_buffer, const char* input_buffer, int size)); } #endif diff --git a/udp.ino b/udp.ino index f473b85..3e8c650 100644 --- a/udp.ino +++ b/udp.ino @@ -2,7 +2,7 @@ namespace udp { -void(*server_handler) (const char* buffer, int size) = NULL; +int(*server_handler) (char* output_buffer, const char* input_buffer, int size) = NULL; uint16_t server_port = 0; UDPPacket::UDPPacket() { @@ -35,6 +35,9 @@ void UDPPacket::setPayload(const char* payload, int len) { *(packet + 4) = (len + 8) >> 8; *(packet + 5) = (len + 8) & 0xff; } +const char* UDPPacket::getPayload() { + return packet + 8; +} void UDPPacket::computeChecksum(const ipv6::IPv6Addr* src_addr, const ipv6::IPv6Addr* dst_addr, int len) { memset(packet + 6, 0, 2); @@ -42,37 +45,36 @@ void UDPPacket::computeChecksum(const ipv6::IPv6Addr* src_addr, const ipv6::IPv6 memcpy(packet + 6, &checksum, 2); } -void set_handler(uint16_t port, void(* server_handler) (const char* buffer, int size)) { +void set_handler(uint16_t port, int(* server_handler) (char* output_buffer, const char* input_buffer, int size)) { udp::server_port = port; udp::server_handler = server_handler; } -void handleUDP(const ipv6::IPv6Addr* src_addr, const ipv6::IPv6Addr* dst_addr, const char* flow, char* packet, int len) { - UDPPacket udp_packet(packet, len); +int handleUDP(char* output_buffer, const char* input_buffer, int ilen) { + UDPPacket* incoming_packet = (UDPPacket*)input_buffer; + UDPPacket* outgoing_packet = (UDPPacket*)output_buffer; + int olen; - if (udp_packet.getDstPort() == server_port) { /* call user-defined server handler */ + if (incoming_packet->getDstPort() == server_port) { /* call user-defined server handler */ if (server_port != 0 && server_handler != NULL) { - server_handler(packet + 8, len - 8); + olen = server_handler(outgoing_packet->getPayload(), incoming_packet->getPayload(), ilen - 8); + + outgoing_packet->setSrcPort(incoming_packet->getDstPort()); + outgoing_packet->setDstPort(incoming_packet->getSrcPort()); + outgoing_packet->setPayload(outgoing_packet->getPayload(), olen); + //outgoing_packet->setLen(olen); + outgoing_packet->computeChecksum(ipv6::packetin.getDstAddress(), ipv6::packetin.getSrcAddress(), olen + 8); + return olen + 8; } } else { /* echo default UDP application handler */ - /* swap ports */ - uint16_t tmp; - tmp = udp_packet.getSrcPort(); - udp_packet.setSrcPort(udp_packet.getDstPort()); - udp_packet.setDstPort(tmp); - - udp_packet.computeChecksum(src_addr, dst_addr, len); - - /* prepare IPv6 packet */ - ipv6::IPv6Packet reply_packet; - reply_packet.setPayload((char*)&udp_packet, len); - reply_packet.setFlow(flow); - - reply_packet.setSrcAddress(dst_addr); - reply_packet.setDstAddress(src_addr); - reply_packet.setNextHeader(ipv6::NH_UDP); - slip::send((void*)&reply_packet, 40 + len); + outgoing_packet->setSrcPort(incoming_packet->getDstPort()); + outgoing_packet->setDstPort(incoming_packet->getSrcPort()); + outgoing_packet->setPayload(incoming_packet->getPayload(), ilen - 8); + outgoing_packet->computeChecksum(ipv6::packetin.getSrcAddress(), ipv6::packetin.getDstAddress(), ilen); + return ilen; } + + return -1; } }