added proper IPv6 flow reply for ICMP packets

This commit is contained in:
giomba 2019-12-23 21:47:25 +01:00
parent 895206a046
commit fb79e3d371
2 changed files with 18 additions and 8 deletions

3
ipv6.h
View File

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

View File

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