Packet decoder

Packet decoder

#include <stdlib.h> // exit
#include <unistd.h> // exit
#include <arpa/inet.h> // inet_ntoa
#include <netinet/if_ether.h> // ETHER_ADDR_LEN

struct ip_header { // Internet Protocol header
    #if BYTE_ORDER == LITTLE_ENDIAN
    u_int ip_hl:4, ip_v:4;
    #endif
    #if BYTE_ORDER == BIG_ENDIAN
    u_int ip_v:4, ip_hl:4;
    #endif
    u_char  ip_tos;            // type of service
    u_short ip_len;            // total length
    u_short ip_id;             // identification
    u_short ip_off;            // fragment offset field
    #define IP_RF 0x8000       // reserved fragment flag
    #define IP_DF 0x4000       // dont fragment flag
    #define IP_MF 0x2000       // more fragments flag
    #define IP_OFFMASK 0x1fff  // mask for fragmenting bits
    u_char  ip_ttl;            // time to live
    u_char  ip_p;              // protocol
    u_short ip_sum;            // checksum
    // source and destination address
    struct in_addr ip_src, ip_dst;
};

struct tcp_header { // Transport Control Protocol header
    u_short th_sport;  // source port
    u_short th_dport;  // destination port
    int th_seq;    // sequence number – 32 bits
    int th_ack;    // ack number – 32 bits
    // unused and …. data offset !
    #if BYTE_ORDER == LITTLE_ENDIAN
    u_int th_x2:4, th_off:4;
    #endif
    #if BYTE_ORDER == BIG_ENDIAN
    u_int th_off:4, th_x2:4;
    #endif
    // Control bits, 6 bits [from left to right]
    u_char  th_flags;
    #define TH_FIN   0x01
    #define TH_SYN   0x02
    #define TH_RST   0x04
    #define TH_PUSH  0x08
    #define TH_ACK   0x10
    #define TH_URG   0x20
    #define TH_ECE   0x40
    #define TH_CWR   0x80
    #define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR)
    u_short th_win;  // window
    u_short th_sum;  // checksum
    u_short th_urp;  // urgent pointer
};

struct udp_header { // Transport Control Protocol header
    u_short th_sport; // source port
    u_short th_dport; // destination port
    u_short th_len;   // length
    u_short th_sum;   // checksum
};

struct ethernet_header { // Ethernet Header
    u_char ether_dhost[ETHER_ADDR_LEN]; // destination address
    u_char ether_shost[ETHER_ADDR_LEN]; // source address
    u_short ether_type; // type of packet
};

void decode_packet (const u_char *packet) {
    const struct ethernet_header *ethernet;
    const struct ip_header *ip;
    const struct tcp_header *tcp;
    const struct udp_header *udp;
    const char   *payload = NULL;
    int port = 0;

    // Define data position
    ethernet = (struct ethernet_header *)(packet);
    ip       = (struct ip_header*)(packet + sizeof(struct ethernet_header));

    if (ip->ip_p == IPPROTO_TCP) {
        tcp      = (struct tcp_header*)(packet + sizeof(struct ethernet_header) + sizeof(struct ip_header));
        payload  = (const char*)(packet + sizeof(struct ethernet_header) + sizeof(struct ip_header) + sizeof(struct tcp_header));
        port = ntohs(udp->th_dport);
        printf(“TCP:%s:%d > %s:%d = %sn”, inet_ntoa(ip->ip_src), ntohs(tcp->th_sport), inet_ntoa(ip->ip_dst), ntohs(tcp->th_dport), payload);

    } else if (ip->ip_p == IPPROTO_UDP) {
        udp      = (struct udp_header*)(packet + sizeof(struct ethernet_header) + sizeof(struct ip_header));
        payload  = (const char*)(packet + sizeof(struct ethernet_header) + sizeof(struct ip_header) + sizeof(struct udp_header));
        port = ntohs(udp->th_dport);
        printf(“UDP:%s:%d > %s:%d = %sn”, inet_ntoa(ip->ip_src), ntohs(udp->th_sport), inet_ntoa(ip->ip_dst), ntohs(udp->th_dport), payload);
    }
}

int main(void) {
     u_char c[10000] = {0x00, 0xA0, 0xCC, 0x63, 0x08, 0x1B,0x00, 0xA0, 0xCC, 0x63, 0x08, 0xDD, 0x08, 0x00, 0x45, 0x00,
         0x00, 0x3C, 0x82, 0x47, 0x00, 0x00, 0xff, 0x11, 0xa6, 0xdf, 0x02, 0x01, 0x01, 0x03, 0x02, 0x01, 0x01, 0x05, 0x06,

         0xa5, 0x06, 0xa5, 0x00, 0x1e, 0x00printf(“n c=%s”,c);

     decode_packet(c);

}

Comments