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 "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() {

4
ipv6.h
View File

@ -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();
};

View File

@ -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 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... */

7
udp.h
View File

@ -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

48
udp.ino
View File

@ -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;
}
}