void tcp_packet_handler(void) { msg_t m_recv_ip, m_send_ip; ipv6_hdr_t *ipv6_header; tcp_hdr_t *tcp_header; uint8_t *payload; socket_internal_t *tcp_socket = NULL; uint16_t chksum; while (1) { msg_receive(&m_recv_ip); ipv6_header = ((ipv6_hdr_t *)m_recv_ip.content.ptr); tcp_header = ((tcp_hdr_t *)(m_recv_ip.content.ptr + IPV6_HDR_LEN)); #ifdef TCP_HC tcp_socket = decompress_tcp_packet(ipv6_header); #else switch_tcp_packet_byte_order(tcp_header); tcp_socket = get_tcp_socket(ipv6_header, tcp_header); #endif chksum = tcp_csum(ipv6_header, tcp_header); payload = (uint8_t *)(m_recv_ip.content.ptr + IPV6_HDR_LEN + tcp_header->data_offset * 4); if ((chksum == 0xffff) && (tcp_socket != NULL)) { #ifdef TCP_HC update_tcp_hc_context(true, tcp_socket, tcp_header); #endif /* Remove reserved bits from tcp flags field */ uint8_t tcp_flags = tcp_header->reserved_flags; switch (tcp_flags) { case TCP_ACK: { /* only ACK Bit set */ uint8_t tcp_payload_len = NTOHS(ipv6_header->length) - TCP_HDR_LEN; uint8_t state = tcp_socket->socket_values.tcp_control.state; if ((tcp_payload_len > 0) && (state == TCP_ESTABLISHED)) { /* handle data segments only when the connection was established successfully */ handle_tcp_no_flags_packet(ipv6_header, tcp_header, tcp_socket, payload, tcp_payload_len); } else if (tcp_payload_len == 0 && (state == TCP_ESTABLISHED || state == TCP_SYN_RCVD || state == TCP_CLOSING || state == TCP_LAST_ACK)) { /* no payload, acknowledging data only */ handle_tcp_ack_packet(ipv6_header, tcp_header, tcp_socket); } break; } case TCP_RST: { printf("RST Bit set!\n"); /* only RST Bit set */ handle_tcp_rst_packet(ipv6_header, tcp_header, tcp_socket); break; } case TCP_SYN: { /* only SYN Bit set, look for matching, listening socket * and request new queued socket */ printf("SYN Bit set!\n"); handle_tcp_syn_packet(ipv6_header, tcp_header, tcp_socket); break; } case TCP_SYN_ACK: { /* only SYN and ACK Bit set, complete three way handshake * when socket in state TCP_SYN_SENT */ handle_tcp_syn_ack_packet(ipv6_header, tcp_header, tcp_socket); break; } case TCP_FIN_ACK: { if (tcp_socket->socket_values.tcp_control.state == TCP_ESTABLISHED) { /* this is the first FIN */ printf("FIN ACK Bit set!\n"); handle_tcp_fin_packet(ipv6_header, tcp_header, tcp_socket); } else { /* this is the response to FIN */ handle_tcp_fin_ack_packet(ipv6_header, tcp_header, tcp_socket); } break; } default: { printf("Unable to process the incoming segment!\n"); } } } else { printf("Wrong checksum (%x) or no corresponding socket found!\n", chksum); printArrayRange(((uint8_t *)ipv6_header), IPV6_HDR_LEN + NTOHS(ipv6_header->length), "Incoming"); print_tcp_status(INC_PACKET, ipv6_header, tcp_header, &tcp_socket->socket_values); } msg_reply(&m_recv_ip, &m_send_ip); } }
void tcp_packet_handler(void) { msg_t m_recv_ip, m_send_ip; ipv6_hdr_t *ipv6_header; tcp_hdr_t *tcp_header; uint8_t *payload; socket_internal_t *tcp_socket = NULL; uint16_t chksum; while (1) { msg_receive(&m_recv_ip); ipv6_header = ((ipv6_hdr_t *)m_recv_ip.content.ptr); tcp_header = ((tcp_hdr_t *)(m_recv_ip.content.ptr + IPV6_HDR_LEN)); #ifdef TCP_HC tcp_socket = decompress_tcp_packet(ipv6_header); #else switch_tcp_packet_byte_order(tcp_header); tcp_socket = get_tcp_socket(ipv6_header, tcp_header); #endif chksum = tcp_csum(ipv6_header, tcp_header); payload = (uint8_t *)(m_recv_ip.content.ptr + IPV6_HDR_LEN + tcp_header->dataOffset_reserved * 4); if ((chksum == 0xffff) && (tcp_socket != NULL)) { #ifdef TCP_HC update_tcp_hc_context(true, tcp_socket, tcp_header); #endif /* Remove reserved bits from tcp flags field */ uint8_t tcp_flags = tcp_header->reserved_flags & REMOVE_RESERVED; switch(tcp_flags) { case TCP_ACK: { /* only ACK Bit set */ handle_tcp_ack_packet(ipv6_header, tcp_header, tcp_socket); break; } case TCP_RST: { printf("RST Bit set!\n"); /* only RST Bit set */ handle_tcp_rst_packet(ipv6_header, tcp_header, tcp_socket); break; } case TCP_SYN: { /* only SYN Bit set, look for matching, listening socket * and request new queued socket */ printf("SYN Bit set!\n"); handle_tcp_syn_packet(ipv6_header, tcp_header, tcp_socket); break; } case TCP_SYN_ACK: { /* only SYN and ACK Bit set, complete three way handshake * when socket in state SYN_SENT */ handle_tcp_syn_ack_packet(ipv6_header, tcp_header, tcp_socket); break; } case TCP_FIN: { printf("FIN Bit set!\n"); /* only FIN Bit set */ handle_tcp_fin_packet(ipv6_header, tcp_header, tcp_socket); break; } case TCP_FIN_ACK: { printf("FIN ACK Bit set!\n"); /* only FIN and ACK Bit set */ handle_tcp_fin_ack_packet(ipv6_header, tcp_header, tcp_socket); break; } default: { handle_tcp_no_flags_packet(ipv6_header, tcp_header, tcp_socket, payload); } } } else { printf("Wrong checksum (%x) or no corresponding socket found!\n", chksum); printArrayRange(((uint8_t *)ipv6_header), IPV6_HDR_LEN + ipv6_header->length, "Incoming"); print_tcp_status(INC_PACKET, ipv6_header, tcp_header, &tcp_socket->socket_values); } msg_reply(&m_recv_ip, &m_send_ip); } }