Example #1
0
/*-----------------------------------------------------------------------------
 * Method: void makeip(struct ip* ipHdr, unsigned int len, unsigned char ttl,
 *                      unsigned char proto, in_addr* src, in_addr* dst)
 *
 * makes an ip header out of the given info, assumes everything is in host
 * byte order
 *---------------------------------------------------------------------------*/
void makeip(
        struct ip* ipHdr,
        unsigned int len,
        uint16_t off,
        unsigned char ttl,
        unsigned char proto,
        uint32_t src,
        uint32_t dst )
{
    uint32_t sbuf, dbuf;
    uint8_t* p = (uint8_t*) ipHdr;
    *p = 0x45;                      // set ip version and header length
    ipHdr->ip_tos = 0;
    ipHdr->ip_len = htons(len);
    ipHdr->ip_id = 0;               // what should this be?
    ipHdr->ip_off = htons(off);
    ipHdr->ip_ttl = ttl;
    ipHdr->ip_p = proto;

    // read into buffers in case we are overwriting in place
    sbuf = src;
    dbuf = dst;
    ipHdr->ip_src.s_addr = sbuf;
    ipHdr->ip_dst.s_addr = dbuf;

    ipHdr->ip_sum = 0x0000;
    ipHdr->ip_sum = in_checksum((uint16_t*)ipHdr, 20);
}
Example #2
0
int do_checksum(u_char *buf, int protocol, int len)
        /* len = protocol header length + payload length */
{
        struct ip *ip;
        int iplen, sum = 0;

        if (len == 0) {
                fprintf(stderr, "header length can't be zero");
                return -1;
        }

        ip = (struct ip *)buf;
        if (ip->ip_v != 4) {
                fprintf(stderr, "Unsupported IP protocol: %d", ip->ip_v);
                return -1;
        }
        iplen = ip->ip_hl << 2;

        switch (protocol) {
                case IPPROTO_TCP:
                {
                        struct tcphdr *tcp = (struct tcphdr *)(buf + iplen);
                        tcp->th_sum = 0;
                        sum = in_checksum((uint16_t *)&ip->ip_src, 8);
                        sum += ntohs(IPPROTO_TCP+len);
                        sum += in_checksum((uint16_t *)tcp, len);
                        tcp->th_sum = CKSUM_CARRY(sum);
                        break;
                }
                case IPPROTO_UDP:
                {
                        struct udphdr *udp = (struct udphdr *)(buf + iplen);
                        udp->uh_sum = 0;
                        sum = in_checksum((uint16_t *)&ip->ip_src, 8);
                        sum += ntohs(IPPROTO_UDP+len);
                        sum += in_checksum((uint16_t *)udp, len);
                        udp->uh_sum = CKSUM_CARRY(sum);
                        break;
                }
                case IPPROTO_ICMP:
                {
                        struct icmp *icmp = (struct icmp *)(buf + iplen);
                        icmp->icmp_cksum = 0;
                        sum = in_checksum((uint16_t *)icmp, len);
                        icmp->icmp_cksum = CKSUM_CARRY(sum);
                        break;
                }
                case IPPROTO_IP:
                {
                        ip->ip_sum = 0;
                        sum = in_checksum((uint16_t *)ip, ip->ip_hl);
                        ip->ip_sum = CKSUM_CARRY(sum);
                        break;
                }
                default:
                {
                        fprintf(stderr, "Unsupported protocol: %d", protocol);
                        return -1;
                }
        }
#ifdef _DEBUG
        printf("\nProtocol: %d: %x\n", protocol, CKSUM_CARRY(sum));
#endif
        return 0;
}
Example #3
0
int main(int argc, char** argv) {
    if(argc < 2) {
        std::cerr << "Specify destination ip address" << std::endl;
        exit(EXIT_FAILURE);
    }
    
    std::string dest_addr = argv[1];

    uint32_t my_time = get_time();

    icmp_timestamp_mgs msg;
    msg.hdr.type = ICMP_TIMESTAMP;
    msg.hdr.code = 0;
    msg.hdr.checksum = 0;
    msg.hdr.un.echo.id = 0;
    msg.hdr.un.echo.sequence = 0;
    msg.originate = htonl(my_time);
    msg.receive = 0;
    msg.transmit = 0;
    msg.hdr.checksum = in_checksum((uint16_t*)&msg, sizeof(msg)); 

    int sockfd;
    if ((sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) == -1) {
        perror("socket");
        exit(EXIT_FAILURE);
    }

    sockaddr_in dest;
    dest.sin_family = AF_INET;
    dest.sin_addr.s_addr = inet_addr(dest_addr.c_str());

    int send_cnt = sendto(sockfd, &msg, sizeof(msg), 0, (sockaddr*)&dest, sizeof(sockaddr));
    if(send_cnt == -1) {
        perror("send");
        exit(EXIT_FAILURE);
    }

    if(send_cnt != sizeof(msg)) {
        fprintf(stderr, "failed to send full packet\n");
        exit(EXIT_FAILURE);
    }

    // set timeout
    timeval tv;
    tv.tv_sec = 5;
    tv.tv_usec = 0;
    setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
    
    char buffer[sizeof(iphdr) + sizeof(icmp_timestamp_mgs)];
    socklen_t addrlen = sizeof(dest);

    int recv_cnt = recvfrom(sockfd, &buffer, sizeof(buffer), 0, (sockaddr*)&dest, &addrlen);
    uint32_t receive_time = get_time();

    if(recv_cnt == -1) {
        perror("recv");
        exit(EXIT_FAILURE);
    }

    if(recv_cnt != sizeof(buffer)) {
        fprintf(stderr, "failed to receive full packet\n");
        exit(EXIT_FAILURE);
    }

    icmp_timestamp_mgs &answer = *(icmp_timestamp_mgs*)(buffer + sizeof(iphdr)); 

    if(answer.hdr.type != ICMP_TIMESTAMPREPLY) {
        fprintf(stderr, "received wrong message\n");
        exit(EXIT_FAILURE);
    }

    int64_t delta = calc_delta(answer, receive_time);
    std::cout << "Time delta: " << delta / 1000 << "s " << abs(delta) % 1000 << "ms" << std::endl;

    close(sockfd);
    return 0;
}