/* * Process a packet on the transport layer. * * @param recvsize: size of the captured data * @param packet: packet capture data target structure * @param raw: packet data at layer 4 entry */ bool process_transport_layer(size_t recvsize, struct packet* packet, byte* raw) { // switch over layer 4 protocol switch( packet->transport_layer_code ) { break;case PRO_ICMP: if( recvsize < sizeof(struct icmphdr) ) { printf("ERROR Received data indicates an ICMP header but it is incomplete\n"); return false; } extract_icmp_header( packet, raw ); print_icmp_header( packet ); break;case PRO_TCP: if( recvsize < sizeof(struct tcphdr) ) { printf("ERROR Received data indicates a TCP header but it is incomplete\n"); return false; } extract_tcp_header( packet, raw ); print_tcp_header( packet ); break;case PRO_UDP: if( recvsize < sizeof(struct udphdr) ) { printf("ERROR Received data indicates an UDP header but it is incomplete\n"); return false; } extract_udp_header( packet, raw ); print_udp_header( packet ); break;case UNKNOWN_TRANSPORT_PROTOCOL: printf("Unknown transport layer protocol.\n"); return false; } return true; }
int main() { char buff[MAX_SIZE]; int sock_fd; int protocol; if ((sock_fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) == -1) { perror("socket()"); exit(-1); } while(1) { if(recvfrom(sock_fd, buff, MAX_SIZE, 0, NULL, NULL) == -1) { perror("recvfrom()"); exit(-1); } print_eth_header((ethernet_header_p)buff); protocol = print_ip_header((ip_header_p)(buff + sizeof(ethernet_header_t))); if (protocol == 0x6) { print_tcp_header((tcp_header_p)(buff + sizeof(ethernet_header_t) + sizeof(ip_header_t))); } else if(protocol == 0x11) { print_udp_header((udp_header_p)(buff + sizeof(ethernet_header_t) + sizeof(ip_header_t))); } } return 0; }
void print_ip4_packet(u8 *ip_pkt) { struct iphdr *iph = (struct iphdr *)ip_pkt; u8 *pkt = ip_pkt + (iph->ihl << 2); u16 flags = (ntohs(iph->frag_off) & 0xE000); u16 frag_off = (ntohs(iph->frag_off) & 0x1FFF); pr_err("-----------------------------------------------------------\n"); /*--------------------------------------------------------------------------- IPv4 Header Format +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |Version| IHL |Type of Service| Total Length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Identification |C|D|M| Fragment Offset | | |E|F|F| | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Time to Live | Protocol | Header Checksum | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Source Address | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Destination Address | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Options | Padding | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ IHL - Header Length Flags - Consist of 3 bits The 1st bit is "Congestion" bit. The 2nd bit is "Dont Fragment" bit. The 3rd bit is "More Fragments" bit. ---------------------------------------------------------------------------*/ memset(ip_flags, 0, sizeof(ip_flags)); if (flags & IP_CE) strcat(ip_flags, "CE "); if (flags & IP_DF) strcat(ip_flags, "DF "); if (flags & IP_MF) strcat(ip_flags, "MF "); pr_err("IP4:: Version = %u, Header Length = %u, TOS = %u, Length = %u\n", iph->version, (iph->ihl << 2), iph->tos, ntohs(iph->tot_len)); pr_err("IP4:: ID = %u, Fragment Offset = %u\n", ntohs(iph->id), frag_off); pr_err("IP4:: Flags = %s\n", ip_flags); pr_err("IP4:: TTL = %u, Protocol = %u, Header Checksum = 0x%04X\n", iph->ttl, iph->protocol, ntohs(iph->check)); pr_err("IP4:: Src IP Addr = %u.%u.%u.%u, Dst IP Addr = %u.%u.%u.%u\n", ip_pkt[12], ip_pkt[13], ip_pkt[14], ip_pkt[15], ip_pkt[16], ip_pkt[17], ip_pkt[18], ip_pkt[19]); switch (iph->protocol) { case 6: /* TCP */ print_tcp_header(pkt); break; case 17: /* UDP */ print_udp_header(pkt); break; default: break; } pr_err("-----------------------------------------------------------\n"); }