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
This commit is contained in:
giomba 2019-12-24 19:33:07 +01:00
parent 339de9322f
commit 9beb97fdba
5 changed files with 56 additions and 35 deletions

View File

@ -3,9 +3,11 @@
#include "slip.h" #include "slip.h"
#include "udp.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)); digitalWrite(13, !digitalRead(13));
memcpy(output_buffer, msg, strlen(msg));
return strlen(msg);
} }
void setup() { void setup() {

4
ipv6.h
View File

@ -35,7 +35,8 @@ namespace ipv6 {
public: public:
IPv6Packet(); IPv6Packet();
IPv6Packet(const char* buffer, int len); IPv6Packet(const char* buffer, int len);
void IPv6Packet::setLen(int len); void setLen(int len);
int getLen();
void setSrcAddress(const IPv6Addr* address); void setSrcAddress(const IPv6Addr* address);
const IPv6Addr* getSrcAddress(); const IPv6Addr* getSrcAddress();
void setDstAddress(const IPv6Addr* address); void setDstAddress(const IPv6Addr* address);
@ -43,6 +44,7 @@ namespace ipv6 {
void setNextHeader(uint8_t next_header); void setNextHeader(uint8_t next_header);
void setFlow(const char* flow); void setFlow(const char* flow);
void setPayload(char* payload, int len); void setPayload(char* payload, int len);
void send();
void doAction(); void doAction();
}; };

View File

@ -75,6 +75,9 @@ void IPv6Packet::setLen(int len) {
*(packet + 4) = len >> 8; *(packet + 4) = len >> 8;
*(packet + 5) = len & 0xff; *(packet + 5) = len & 0xff;
} }
int IPv6Packet::getLen() {
return ((*(packet + 4)) << 8) + (*(packet + 5));
}
void IPv6Packet::setSrcAddress(const IPv6Addr* address) { void IPv6Packet::setSrcAddress(const IPv6Addr* address) {
memcpy(packet + 8, address, 16); memcpy(packet + 8, address, 16);
@ -104,25 +107,36 @@ void IPv6Packet::setPayload(char* payload, int len) {
memcpy(packet + 40, payload, len); /* payload */ memcpy(packet + 40, payload, len); /* payload */
} }
void IPv6Packet::send() {
slip::send(packet, 40 + this->getLen());
}
void IPv6Packet::doAction() { void IPv6Packet::doAction() {
/* if destination is my address, or destination is "all nodes" address, then... */ /* 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)) { 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 ilen = this->getLen(); /* input payload length */
int olen; /* output payload length */ int olen; /* output payload length */
switch(*(packet + 6)) { /* next header */ switch(*(packet + 6)) { /* next header */
case NH_ICMP: case NH_ICMP:
if ((olen = handleICMP((char*)&packetout + 40, packet + 40, ilen)) != -1) { if ((olen = handleICMP((char*)&packetout + 40, packet + 40, ilen)) != -1) {
packetout.setLen(olen); packetout.setLen(olen);
packetout.setFlow((char*)&packetin + 1); packetout.setFlow(((char*)(&packetin)) + 1);
packetout.setSrcAddress(packetin.getDstAddress()); packetout.setSrcAddress(packetin.getDstAddress());
packetout.setDstAddress(packetin.getSrcAddress()); packetout.setDstAddress(packetin.getSrcAddress());
packetout.setNextHeader(NH_ICMP); packetout.setNextHeader(NH_ICMP);
slip::send((void*)&packetout, 40 + olen); packetout.send();
} }
break; break;
case NH_UDP: 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; break;
default: default:
/* no other protocols are known here, sorry :-) */ /* 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); uint8_t type = *(input_buffer);
if (type == ICMP_ECHO_REQUEST_TYPE) { /* if it is ICMPv6 Echo Request, then... */ if (type == ICMP_ECHO_REQUEST_TYPE) { /* if it is ICMPv6 Echo Request, then... */

7
udp.h
View File

@ -16,16 +16,17 @@ namespace udp {
uint16_t getSrcPort(); uint16_t getSrcPort();
void setDstPort(uint16_t port); void setDstPort(uint16_t port);
uint16_t getDstPort(); uint16_t getDstPort();
const char* UDPPacket::getPayload();
void setPayload(const char* payload, int len); void setPayload(const char* payload, int len);
void computeChecksum(const ipv6::IPv6Addr* src_addr, const ipv6::IPv6Addr* dst_addr, 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; 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 #endif

48
udp.ino
View File

@ -2,7 +2,7 @@
namespace udp { 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; uint16_t server_port = 0;
UDPPacket::UDPPacket() { UDPPacket::UDPPacket() {
@ -35,6 +35,9 @@ void UDPPacket::setPayload(const char* payload, int len) {
*(packet + 4) = (len + 8) >> 8; *(packet + 4) = (len + 8) >> 8;
*(packet + 5) = (len + 8) & 0xff; *(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) { void UDPPacket::computeChecksum(const ipv6::IPv6Addr* src_addr, const ipv6::IPv6Addr* dst_addr, int len) {
memset(packet + 6, 0, 2); 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); 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_port = port;
udp::server_handler = server_handler; udp::server_handler = server_handler;
} }
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 ilen) {
UDPPacket udp_packet(packet, len); 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) { 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 */ } else { /* echo default UDP application handler */
/* swap ports */ outgoing_packet->setSrcPort(incoming_packet->getDstPort());
uint16_t tmp; outgoing_packet->setDstPort(incoming_packet->getSrcPort());
tmp = udp_packet.getSrcPort(); outgoing_packet->setPayload(incoming_packet->getPayload(), ilen - 8);
udp_packet.setSrcPort(udp_packet.getDstPort()); outgoing_packet->computeChecksum(ipv6::packetin.getSrcAddress(), ipv6::packetin.getDstAddress(), ilen);
udp_packet.setDstPort(tmp); return ilen;
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);
} }
return -1;
} }
} }