/* PRETTY PRINT TCP PACKET HEADER */ void print_tcp_load(const uint8_t *packet, unsigned int len) { unsigned int data_offset = sizeof(eth_hdr) + sizeof(ip_hdr); unsigned int data_len = len - data_offset; const uint8_t *data = packet + data_offset; indent(2); printf("\nTCP PACKET in HEX (%d bytes)\n", data_len); nat_tcp_hdr *tcp = get_nat_tcp_hdr(packet, len); indent(3); printf("Src Port = %d\n", ntohs(tcp->tcp_sport)); indent(3); printf("Dst Port = %d\n", ntohs(tcp->tcp_dport)); indent(3); printf("Seq # = %X\n", ntohl(tcp->tcp_seq)); indent(3); printf("Acq # = %X\n", ntohl(tcp->tcp_ack)); indent(3); printf("Unused = %X %X %X %X\n", tcp->unused1[0], tcp->unused1[1], tcp->unused1[2], tcp->unused1[3]); indent(3); printf("Sum = %X\n", tcp->tcp_sum); indent(3); printf("Unused = %X %X\n", tcp->unused2[0], tcp->unused2[1]); printf("\n"); int i; for(i=0; i<data_len; i++){ printf("%X ", data[i]); } printf("\n\n"); }
/* * Overwrite the ip and port of a packet for nat */ void populate_nat_packet(ip_hdr *ip, const uint8_t *packet, unsigned int len, nat_entry *ne, int nat_type) { nat_tcp_hdr *tcp = NULL; nat_udp_hdr *udp = NULL; nat_icmp_hdr *icmp = NULL; /* rewrite the ip address */ if(nat_type == NAT_EXTERNAL) { ip->ip_src.s_addr = ne->nat_ext.ip.s_addr; } else if(nat_type == NAT_INTERNAL) { ip->ip_dst.s_addr = ne->nat_int.ip.s_addr; } switch(ip->ip_p) { case IP_PROTO_TCP: tcp = get_nat_tcp_hdr(packet, len); if(nat_type == NAT_EXTERNAL) { tcp->tcp_sport = ne->nat_ext.port; } else if(nat_type == NAT_INTERNAL) { tcp->tcp_dport = ne->nat_int.port; } break; case IP_PROTO_UDP: udp = get_nat_udp_hdr(packet, len); if(nat_type == NAT_EXTERNAL) { udp->udp_sport = ne->nat_ext.port; } else if(nat_type == NAT_INTERNAL) { udp->udp_dport = ne->nat_int.port; } break; case IP_PROTO_ICMP: icmp = get_nat_icmp_hdr(packet, len); if( (icmp->icmp_type == ICMP_TYPE_ECHO_REQUEST) || (icmp->icmp_type == ICMP_TYPE_ECHO_REPLY) ) { /* overwrite the identifier */ if(nat_type == NAT_EXTERNAL) { icmp->icmp_opt1 = ne->nat_ext.port; } else if(nat_type == NAT_INTERNAL) { icmp->icmp_opt1 = ne->nat_int.port; } } else if( (icmp->icmp_type == ICMP_TYPE_TIME_EXCEEDED) || (icmp->icmp_type == ICMP_TYPE_DESTINATION_UNREACHABLE) ) { /* overwrite the ip and ip sum inside the icmp data */ uint16_t checksum = 0; ip_hdr *data_ip = get_ip_hdr_from_icmp_data(packet, len); if(nat_type == NAT_EXTERNAL) { data_ip->ip_dst.s_addr = ne->nat_ext.ip.s_addr; checksum = nat_checksum(data_ip->ip_sum, ne->nat_ext.checksum_ip, ne->nat_int.checksum_ip); } else if(nat_type == NAT_INTERNAL) { data_ip->ip_src.s_addr = ne->nat_int.ip.s_addr; checksum = nat_checksum(data_ip->ip_sum, ne->nat_int.checksum_ip, ne->nat_ext.checksum_ip); } bzero(&ip->ip_sum, sizeof(uint16_t)); data_ip->ip_sum = checksum; if( (data_ip->ip_p == IP_PROTO_TCP) || (data_ip->ip_p == IP_PROTO_UDP) ) { /* overwrite the port inside the icmp data */ uint16_t *ports = get_nat_port_list_from_icmp_data(packet, len); if(nat_type == NAT_EXTERNAL) { *(ports+1) = ne->nat_ext.port; } else if(nat_type == NAT_INTERNAL) { *ports = ne->nat_int.port; } } else if( data_ip->ip_p == IP_PROTO_ICMP ) { nat_icmp_hdr *icmp_data = get_icmp_hdr_from_icmp_data(packet, len); /* overwrite the id and checksum of the original echo packet */ if( (icmp_data->icmp_type == ICMP_TYPE_ECHO_REQUEST) || (icmp_data->icmp_type == ICMP_TYPE_ECHO_REPLY) ) { if(nat_type == NAT_EXTERNAL) { icmp_data->icmp_opt1 = ne->nat_ext.port; checksum = nat_checksum(icmp_data->icmp_sum, ne->nat_ext.checksum_port, ne->nat_int.checksum_port); } else if(nat_type == NAT_INTERNAL) { icmp_data->icmp_opt1 = ne->nat_int.port; checksum = nat_checksum(icmp_data->icmp_sum, ne->nat_int.checksum_port, ne->nat_ext.checksum_port); } bzero(&icmp_data->icmp_sum, sizeof(uint16_t)); icmp_data->icmp_sum = checksum; } } } break; default: printf("Invalid IP protocol found in the ip header while overwriting the packet with nat entries\n"); break; } }