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:
parent
339de9322f
commit
9beb97fdba
@ -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
4
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();
|
||||
};
|
||||
|
24
ipv6.ino
24
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 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
7
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
|
||||
|
48
udp.ino
48
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user