User Tools

Site Tools


Differences

This shows you the differences between two versions of the page.

Link to this comparison view

c:traceroute [2019-02-22 21:53]
ziggi created
c:traceroute [2020-02-15 00:57]
Line 1: Line 1:
- 
- 
-<code c pingw3.c>​ 
- 
-# cat Ping/​pingw3.c 
- 
-/* $Id: ping.c,v 1.1 2019/02/20 13:01:37 ziggi Exp ziggi $ */ 
- 
-#ifdef __WINNT__ 
-#define __WINNT 1 
-#endif 
- 
-#include <​stdio.h>​ 
-#include <​stdlib.h>​ 
-#include <​string.h>​ 
-#include <​stdint.h>​ 
-#include <​limits.h>​ 
-#include <​unistd.h>​ 
- 
-#ifdef __WINNT__ 
- 
-#include <​sys/​types.h>​ 
-#include <​sys/​stat.h>​ 
-#define _WIN32_WINNT 0x0501 
-#include <​winsock2.h>​ 
-#include <​ws2tcpip.h>​ 
-#include <​pshpack1.h>​ 
- 
-#else 
- 
-#include <​sys/​socket.h>​ 
-#include <​arpa/​inet.h>​ 
-#include <​netinet/​in.h>​ 
-#include <​netinet/​ip.h>​ 
-#include <​netinet/​ip_icmp.h>​ 
-#include <​netdb.h>​ 
- 
-#endif 
- 
-#ifdef __WINNT__ 
-struct ip { 
-    u_char ip_hl:​4; ​            /* header length */ 
-    u_char ip_v:​4; ​             /* version */ 
-    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 */ 
-    u_char ip_ttl; ​             /* time to live */ 
-    u_char ip_p;                /* protocol */ 
-    u_short ip_sum; ​            /* checksum */ 
-    struct in_addr ip_src; 
-    struct in_addr ip_dst; ​     /* source and dest address */ 
-} __packed; 
- 
-struct icmp { 
-    u_char icmp_type; 
-    u_char icmp_code; 
-    u_short icmp_cksum; 
- 
-    u_short icmp_id; 
-    u_short icmp_seq; 
-}; 
-#endif 
- 
-typedef struct ip ip_hdr_t; 
-typedef struct icmp icmp_hdr_t; 
- 
-#define HOST "​v5.unix7.org"​ 
- 
-uint16_t icmpv4_checksum(const uint16_t * const data, const size_t byte_sz) { 
-    if (0 != (byte_sz & 1)) { 
-        fprintf(stderr,​ "# wrong number of bytes %u must be even", (int)byte_sz);​ 
-    } 
-    uint32_t accu = 0; 
-    for (size_t i = 0; i < (byte_sz >> 1); ++i) { 
-        accu = accu + data[i]; 
-    } 
-    while (accu >> 16) { 
-        accu = (accu & 0xffff) + (accu >> 16); 
-    } 
-    const uint16_t checksum = ~accu; 
-    return checksum; 
-} 
- 
-int __exit(void) { 
-#ifdef __WINNT__ 
-    WSACleanup();​ 
-#endif 
-    exit(1); 
-} 
- 
- 
-int main(int argc, char **argv) { 
- 
-#ifdef __WINNT__ 
-    WSADATA wsaData; 
- 
-#define WSVERSION 0x0202 
-    int iResult = WSAStartup(WSVERSION,​ &​wsaData);​ 
-    if (iResult != 0) { 
-        printf("#​ wsastartup() failed: %d\n", iResult); 
-        __exit(); 
-    } 
-#endif 
- 
-    struct addrinfo hints; 
-    memset(&​hints,​ 0, sizeof(hints));​ 
- 
-    hints.ai_family = AF_UNSPEC; 
-    hints.ai_socktype = SOCK_STREAM;​ 
-    hints.ai_protocol = IPPROTO_TCP;​ 
- 
-    struct addrinfo *result = NULL; 
- 
-    int retval; 
-    if ((retval = getaddrinfo(HOST,​ NULL, &hints, &​result)) != 0) { 
-        printf("#​ getaddrinfo() failed with error: %d\n", retval); 
-        __exit(); 
-    } 
- 
-    struct sockaddr_in *sockaddr = NULL; 
- 
-    for (struct addrinfo * ptr = result; ptr != NULL; ptr = ptr->​ai_next) { 
-        switch (ptr->​ai_family) { 
-            case AF_INET: 
-                sockaddr = (struct sockaddr_in *)ptr->​ai_addr;​ 
-                printf("#​ host %s have ipv4 address %s\n", HOST, inet_ntoa(sockaddr->​sin_addr));​ 
-                break; 
-            default: 
-                break; 
-        } 
-        if (sockaddr != NULL) { 
-            break; 
-        } 
-    } 
- 
-    struct sockaddr_in dest_sockaddr;​ 
-    memcpy(&​dest_sockaddr,​ sockaddr, sizeof(dest_sockaddr));​ 
-    freeaddrinfo(result);​ 
- 
-#define SOCKET_ERROR (-1) 
- 
-#define PAYLOAD_LEN 4 
-#define OBUFFER_SIZE sizeof(icmp_hdr_t) + PAYLOAD_LEN 
- 
-#define ICMP_ECHOREPLY 0 
-#define ICMP_ECHO 8 
-#define ICMP_CODE 0 
- 
- 
-    int ttl; 
-#define MAX_TTL 12 
- 
-    for (ttl = 1; ttl < MAX_TTL; ttl++) { 
- 
-        int sock; 
-        if ((sock = socket(AF_INET,​ SOCK_RAW, IPPROTO_ICMP)) < 0) { 
-            printf("#​ socket creation failed\n"​);​ 
-            __exit(); 
-        } 
- 
-#ifdef __WINNT__ 
-        if (setsockopt(sock,​ IPPROTO_IP, IP_TTL, (char *)&ttl, sizeof(ttl)) < 0) { 
-            fprintf(stderr,​ "# setting ttl setsockopt failed\n"​);​ 
-            __exit(); 
-        } 
-#else 
-        if (setsockopt(sock,​ IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl)) < 0) { 
-            fprintf(stderr,​ "# setting ttl setsockopt failed\n"​);​ 
-            __exit(); 
-        } 
-#endif 
- 
-        char obuffer[OBUFFER_SIZE];​ 
- 
-        icmp_hdr_t *icmp_hdr; 
-        icmp_hdr = (icmp_hdr_t *) obuffer; 
- 
-        icmp_hdr->​icmp_type = ICMP_ECHO; 
-        icmp_hdr->​icmp_code = ICMP_CODE; 
-        icmp_hdr->​icmp_id = htons(1234);​ 
-        icmp_hdr->​icmp_cksum = 0; 
-        icmp_hdr->​icmp_seq = htons(4567);​ 
- 
-        char *payload = obuffer + sizeof(icmp_hdr_t);​ 
-        memset(payload,​ '<',​ PAYLOAD_LEN);​ 
- 
-        icmp_hdr->​icmp_cksum = icmpv4_checksum((uint16_t *) obuffer, OBUFFER_SIZE);​ 
- 
-        if (sendto(sock,​ (char *)obuffer, OBUFFER_SIZE,​ 0, (struct sockaddr *)&​dest_sockaddr,​ sizeof(dest_sockaddr)) < 0) { 
-            fprintf(stderr,​ "# sendto failed\n"​);​ 
-            __exit(); 
-        } 
- 
-#define IBUFFER_SIZE 204 
-#define SLEEP_TIME 1                  // 1 ms 
-#define DELAY_TIME 2 * 1000    // 2 sec 
-#define MAX_COUNT DELAY_TIME / SLEEP_TIME 
- 
-        char ibuffer[IBUFFER_SIZE];​ 
-        memset(ibuffer,​ 0, IBUFFER_SIZE);​ 
- 
-        struct sockaddr_in src_sockaddr;​ 
-        memset(&​src_sockaddr,​ 0, sizeof(src_sockaddr));​ 
-        socklen_t src_sockaddr_size = sizeof(src_sockaddr);​ 
- 
-        int i = 0; 
- 
-        while (i < MAX_COUNT) { 
-            i++; 
- 
- 
-            ssize_t res_count = recvfrom(sock,​ (char *)ibuffer, IBUFFER_SIZE,​ MSG_DONTWAIT,​ 
-                                         ​(struct sockaddr *)&​src_sockaddr,​ &​src_sockaddr_size);​ 
- 
- 
-            if (res_count > 0) { 
-                //​printf("#​ received %d bytes\n",​ (int)res_count);​ 
- 
-                ip_hdr_t *ip_hdr = (struct ip *)ibuffer; 
-                //​printf("# ​  ​responce ttl %d\n", ip_hdr->​ip_ttl);​ 
-                size_t ip_header_len = ip_hdr->​ip_hl >> 2; 
-                struct icmp *icmp_header = (struct icmp *)(ip_hdr + ip_header_len);​ 
- 
-                printf("#​ ttl= %d icmp type %d from %s\n", ttl, 
-                       ​icmp_header->​icmp_type,​ inet_ntoa(src_sockaddr.sin_addr));​ 
- 
-                if (icmp_header->​icmp_type == ICMP_ECHOREPLY) { 
-                    printf("# ​  type ICMP_ECHOREPLY\n"​);​ 
-                    printf("# ​  icmp id %d\n", ntohs(icmp_header->​icmp_id));​ 
-                    printf("# ​  icmp seq %d\n", ntohs(icmp_header->​icmp_seq));​ 
-                    exit(0); 
-                } 
-                break; 
-            } 
- 
-            if (i == MAX_COUNT) { 
-                printf("#​ ttl %d icmp timeout\n",​ ttl); 
-                break; 
-            } 
- 
-#ifdef __WINNT__ 
-            Sleep(SLEEP_TIME);​ 
-#else 
-            usleep(SLEEP_TIME * 1000); 
-#endif 
- 
- 
- 
-        } 
-        close(sock);​ 
- 
-    } 
- 
-#ifdef __WINNT__ 
-    WSACleanup();​ 
-#endif 
-} 
-</​code>​ 
- 
- 
-====Out==== 
- 
-<​file>​ 
-$ cc -o pingw3 pingw3.c && sudo ./pingw3 
-# host v5.unix7.org have ipv4 address 93.171.216.21 
-# ttl= 1 icmp type 11 from 192.168.56.1 
-# ttl= 2 icmp type 11 from 212.48.195.247 
-# ttl= 3 icmp type 11 from 212.48.198.234 
-# ttl= 4 icmp type 11 from 87.226.133.237 
-# ttl 5 icmp timeout 
-# ttl= 6 icmp type 11 from 4.69.137.90 
-# ttl= 7 icmp type 11 from 212.73.241.250 
-# ttl 8 icmp timeout 
-# ttl= 9 icmp type 0 from 93.171.216.21 
-#   type ICMP_ECHOREPLY 
-#   icmp id 1234 
-#   icmp seq 4567 
-</​file>​ 
- 
- 
-