added proper IPv6 flow reply for ICMP packets
This commit is contained in:
parent
895206a046
commit
fb79e3d371
3
ipv6.h
3
ipv6.h
@ -38,6 +38,7 @@ namespace ipv6 {
|
|||||||
void setSrcAddress(IPv6Addr& address);
|
void setSrcAddress(IPv6Addr& address);
|
||||||
void setDstAddress(IPv6Addr& address);
|
void setDstAddress(IPv6Addr& address);
|
||||||
void setNextHeader(uint8_t next_header);
|
void setNextHeader(uint8_t next_header);
|
||||||
|
void setFlow(const char* flow);
|
||||||
void setPayload(char* payload, int len);
|
void setPayload(char* payload, int len);
|
||||||
|
|
||||||
char* serialize();
|
char* serialize();
|
||||||
@ -47,7 +48,7 @@ namespace ipv6 {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Note: content of message may be changed */
|
/* Note: content of message may be changed */
|
||||||
void handleICMP(const char* src, const char* dst, char* message, int len);
|
void handleICMP(const char* src, const char* dst, const char* flow, char* message, int len);
|
||||||
|
|
||||||
uint16_t compute_checksum(const char* src_addr, const char* dst_addr, uint8_t next_header, const char* payload, int len);
|
uint16_t compute_checksum(const char* src_addr, const char* dst_addr, uint8_t next_header, const char* payload, int len);
|
||||||
}
|
}
|
||||||
|
21
ipv6.ino
21
ipv6.ino
@ -79,6 +79,14 @@ void IPv6Packet::setDstAddress(IPv6Addr& address) {
|
|||||||
memcpy(packet + 24, (void*)&address, 16);
|
memcpy(packet + 24, (void*)&address, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IPv6Packet::setFlow(const char* flow) {
|
||||||
|
/* three bytes
|
||||||
|
4 most significant bits are ignored
|
||||||
|
because only 20 bits can be used */
|
||||||
|
*(packet + 1) = (*(packet + 1)) | (flow[0] & 0x0f); /* pay attention to TC field */
|
||||||
|
memcpy(packet + 2, flow + 1, 2);
|
||||||
|
}
|
||||||
|
|
||||||
void IPv6Packet::setPayload(char* payload, int len) {
|
void IPv6Packet::setPayload(char* payload, int len) {
|
||||||
memset(packet, 0, LEN);
|
memset(packet, 0, LEN);
|
||||||
|
|
||||||
@ -96,7 +104,7 @@ void IPv6Packet::setPayload(char* payload, int len) {
|
|||||||
|
|
||||||
switch(*(packet + 6)) { /* next header */
|
switch(*(packet + 6)) { /* next header */
|
||||||
case NH_ICMP:
|
case NH_ICMP:
|
||||||
handleICMP(packet + 8, packet + 24, packet + 40, len);
|
handleICMP(packet + 8, packet + 24, packet + 1, packet + 40, len);
|
||||||
break;
|
break;
|
||||||
case NH_UDP:
|
case NH_UDP:
|
||||||
// handleUDP(packet + 40, len);
|
// handleUDP(packet + 40, len);
|
||||||
@ -108,7 +116,7 @@ void IPv6Packet::setPayload(char* payload, int len) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleICMP(const char* src_addr, const char* dst_addr, char* packet, int len) {
|
void handleICMP(const char* src_addr, const char* dst_addr, const char* flow, char* packet, int len) {
|
||||||
uint8_t type = *(packet);
|
uint8_t type = *(packet);
|
||||||
|
|
||||||
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... */
|
||||||
@ -119,7 +127,7 @@ void handleICMP(const char* src_addr, const char* dst_addr, char* packet, int le
|
|||||||
memset(packet + 2, 0, 2); /* zero-checksum */
|
memset(packet + 2, 0, 2); /* zero-checksum */
|
||||||
uint16_t computed_checksum = compute_checksum(src_addr, dst_addr, NH_ICMP, packet, len);
|
uint16_t computed_checksum = compute_checksum(src_addr, dst_addr, NH_ICMP, packet, len);
|
||||||
|
|
||||||
if (memcmp(&computed_checksum, received_checksum, 2) == 0) { /* if checksum is valid, then... */
|
//if (memcmp(&computed_checksum, received_checksum, 2) == 0) { /* if checksum is valid, then... */
|
||||||
/* Build an echo reply:
|
/* Build an echo reply:
|
||||||
* the reply has the same exact format of the request,
|
* the reply has the same exact format of the request,
|
||||||
* except for Type and Checksum */
|
* except for Type and Checksum */
|
||||||
@ -131,15 +139,16 @@ void handleICMP(const char* src_addr, const char* dst_addr, char* packet, int le
|
|||||||
|
|
||||||
IPv6Packet reply_packet;
|
IPv6Packet reply_packet;
|
||||||
reply_packet.setPayload(packet, len);
|
reply_packet.setPayload(packet, len);
|
||||||
|
reply_packet.setFlow(flow);
|
||||||
|
|
||||||
IPv6Addr tmp_addr;
|
IPv6Addr tmp_addr;
|
||||||
tmp_addr.deserialize(dst_addr);
|
memcpy(&tmp_addr, dst_addr, 16);
|
||||||
reply_packet.setSrcAddress(tmp_addr);
|
reply_packet.setSrcAddress(tmp_addr);
|
||||||
tmp_addr.deserialize(src_addr);
|
memcpy(&tmp_addr, src_addr, 16);
|
||||||
reply_packet.setDstAddress(tmp_addr);
|
reply_packet.setDstAddress(tmp_addr);
|
||||||
reply_packet.setNextHeader(NH_ICMP);
|
reply_packet.setNextHeader(NH_ICMP);
|
||||||
slip::send((void*)&reply_packet, 40 + len);
|
slip::send((void*)&reply_packet, 40 + len);
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user