⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ping.c

📁 一个简单的ISOS模块代码。A simple ISOS module code
💻 C
📖 第 1 页 / 共 2 页
字号:
            if (inet_ntop(family,                           (family == AF_INET)                          ? (const void *)                                (&(((struct sockaddr_in *)&from)->sin_addr))                          : (const void *)                                (&(((struct sockaddr_in6 *)&from)->sin6_addr)),                          from_str, sizeof(from_str)) == NULL)            {                PRINTF("Could not convert source address.\n");                err = -1;                break;            }            /*             * Interpret the ICMP status and output response accordingly.             * Extend to suit requirements. For example, a lookup table             * would be a far more efficient and extensible approach -             * this codes implemented here are just for reference and             * represent some likely outcomes for a failed ping.             * The rest just have a default handler that outputs the             * ICMP type and code.             */            if (family == AF_INET)            {                struct icmp        *p_icmphdr;                struct ipheader    *p_iphdr;                int                 ip_hdr_size;                /* Get seperate pointers to ICMP and IP headers */                p_iphdr = (struct ipheader *)(p_buf);                ip_hdr_size = 4 * IP_GET_IHL(p_iphdr);                p_icmphdr = (struct icmp *)(p_buf + ip_hdr_size);                /* Adjust received length to not count the IP header */                len = status - ip_hdr_size;                if (p_icmphdr->icmp_type != ICMP_ECHOREPLY)                                    {                    switch (p_icmphdr->icmp_type)                    {                        case ICMP_UNREACH:                            switch( p_icmphdr->icmp_code )                            {                                case ICMP_UNREACH_NET:                                    PRINTF("%s reports destination net "                                           "unreachable.\n", from_str);                                    break;                                case ICMP_UNREACH_HOST:                                    PRINTF("%s reports destination host "                                           "unreachable.\n", from_str);                                    break;                                case ICMP_UNREACH_PORT:                                    PRINTF("%s reports destination port "                                           "unreachable.\n", from_str);                                    break;                                case ICMP_UNREACH_NEEDFRAG:                                    PRINTF("%s reports destination "                                           "unreachable - fragmentation "                                           "required but don't-fragment "                                           "set.\n", from_str);                                    break;                                default:                                    PRINTF("%s reports destination "                                           "unreachable: code %d.\n",                                           from_str, p_icmphdr->icmp_code);                                    break;                            }                            /* choose vaguely sensible error code */                            err = EHOSTUNREACH;                            break;                                                case ICMP_TIMXCEED:                            PRINTF("%s reports time-to-live exceeded "                                   "(with code %d).\n",                                   from_str, p_icmphdr->icmp_code);                            /* choose vaguely sensible error code */                            err = EHOSTUNREACH;                            break;                        case ICMP_PARAMPROB:                            PRINTF("%s reports parameter problem "                                   "(with code %d).\n",                                   from_str, p_icmphdr->icmp_code);                            /* choose vaguely sensible error code */                            err = EHOSTUNREACH;                            break;                                                    case ICMP_ECHO:                            /*                              * We might see our own echo request                              * in some cases                             */                            if (p_icmphdr->icmp_id != fd)                            {                                PRINTF("ICMP echo request from %s.\n",                                       from_str);                            }                            break;                        default:                            PRINTF("ICMP response from %s, type %d, "                                   "code %d.\n", from_str,                                   p_icmphdr->icmp_type,                                   p_icmphdr->icmp_code);                    }                    if (err != 0)                    {                        break;                    }                }                /* ignore other people's echo replies */                else if (p_icmphdr->icmp_id == fd)                {                    /* Output the result */                    roundtrip = (time_recv.tv_sec * 1000)                                + (time_recv.tv_usec / 1000 );                    /*                      * Granularity of timer means that a round trip                     * time < 10ms won't show up accurately                     */                    PRINTF("%d bytes from %s: seq=%u, ttl=%d, rtt%s%ldms\n",                           len, from_str, p_icmphdr->icmp_seq, p_iphdr->ttl,                           (roundtrip >= 10) ? "=" : "<",                           (roundtrip >= 10) ? roundtrip : 10);                    break;                }            }            else            {                /* Pointer to ICMPv6 headers */                struct icmp6_hdr   *p_icmp6hdr = (struct icmp6_hdr *)p_buf;                            /* Check ICMP6 message type */                if (p_icmp6hdr->icmp6_type != ICMP6_ECHO_REPLY)                {                    switch (p_icmp6hdr->icmp6_type)                    {                        case ICMP6_DST_UNREACH:                            switch (p_icmp6hdr->icmp6_code)                            {                                case ICMP6_DST_UNREACH_NOROUTE:                                    PRINTF("%s reports no route to "                                           "destination.\n", from_str);                                    break;                                case ICMP6_DST_UNREACH_ADMIN:                                    PRINTF("%s reports communication "                                           "with destination administrative "                                           "prohibited.\n", from_str);                                    break;                                case ICMP6_DST_UNREACH_BEYONDSCOPE:                                    PRINTF("%s reports destination beyond "                                           "scope of source address %s.\n",                                           from_str);                                    break;                                case ICMP6_DST_UNREACH_ADDR:                                    PRINTF("%s reports destination "                                           "address %s unreachable.\n",                                           from_str, to_str);                                    break;                                default:                                    PRINTF("%s reports destination "                                           "unreachable: code %d.\n",                                           from_str,                                           p_icmp6hdr->icmp6_code);                                    break;                            }                            /* choose vaguely sensible error code */                            err = EHOSTUNREACH;                            break;                        case ICMP6_PACKET_TOO_BIG:                            PRINTF("%s reports packet too big "                                   "(with code %d).\n",                                   from_str, p_icmp6hdr->icmp6_code);                            /* choose vaguely sensible error code */                            err = EHOSTUNREACH;                            break;                        case ICMP6_TIME_EXCEEDED:                            switch (p_icmp6hdr->icmp6_code)                            {                                case ICMP6_TIME_EXCEED_TRANSIT:                                    PRINTF("%s reports hop limit exceeded.\n",                                           from_str);                                    break;                                default:                                    PRINTF("%s reports time exceeded: "                                           "code %d.\n", from_str,                                           p_icmp6hdr->icmp6_code);                                    break;                            }                            /* choose vaguely sensible error code */                            err = EHOSTUNREACH;                            break;                                                case ICMP6_PARAM_PROB:                            PRINTF("%s reports parameter problem "                                   "(with code %d).\n",                                   from_str, p_icmp6hdr->icmp6_code);                            /* choose vaguely sensible error code */                            err = EHOSTUNREACH;                            break;                        case ICMP6_ECHO_REQUEST:                            /*                              * We might see our own echo request                              * in some cases                             */                            if (p_icmp6hdr->icmp6_id != fd)                            {                                PRINTF("ICMP echo request from %s.\n",                                       from_str);                            }                            break;                        default:                            /* Print only errors, skip informational */                            if (!(p_icmp6hdr->icmp6_type & ICMP6_INFOMSG_MASK))                            {                                PRINTF("ICMP response from %s, type %d, "                                       "code %d.\n", from_str,                                       p_icmp6hdr->icmp6_type,                                       p_icmp6hdr->icmp6_code);                            }                    }                    if (err != 0)                    {                        break;                    }                }                /* Ignore other people's echo replies */                else if (p_icmp6hdr->icmp6_id == fd)                {                    /* Output the result */                    roundtrip = (time_recv.tv_sec * 1000)                                + (time_recv.tv_usec / 1000);                    /*                     * Granularity of timer means that a round trip                     * time < 10ms won't show up accurately                     */                    PRINTF("%d bytes from %s: seq=%u, rtt%s%ldms\n",                           len, from_str, p_icmp6hdr->icmp6_seq,                           (roundtrip >= 10) ? "=" : "<",                           (roundtrip >= 10) ? roundtrip : 10);                    break;                }            }        } /* End forever loop */            } /* End attempts loop */    /* Close Raw IPv6 socket */    close(fd);        /* Free memory allocated for buffer */    free(pkt);        return err;    } /* do_ping6_v4_v6 *//* in_cksum -- *     Checksum routine for Internet Protocol family headers (C Version). *     Very dumb, but good enough for ping. * * PARAMETERS: *     addr - first address of the buffer with data *     len  - length of the data in buffer * * RETURNS: *     icmp checksum value */u_shortin_cksum(u_short *addr, int len){    register int        nleft = len;    register u_short   *w = addr;    register int        sum = 0;    u_short             answer = 0;    /*     * Our algorithm is simple, using a 32 bit accumulator (sum), we add     * sequential 16 bit words to it, and at the end, fold back all the     * carry bits from the top 16 bits into the lower 16 bits.     */    for (nleft = len; nleft > 1; nleft -= 2)    {        sum += *w++;    }    /* Mop up an odd byte, if necessary */    if (nleft == 1) {        *(u_char *)(&answer) = *(u_char *)w ;        sum += answer;    }    /* Add back carry outs from top 16 bits to low 16 bits */    sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */    sum += (sum >> 16);                 /* add carry */    answer = ~sum;                      /* truncate to 16 bits */    return (answer);} /* in_cksum *//* ping_prepare_packet -- *     prepares protocol specific (PF_INET or PF_INET6) ICMP echo *     request with payload (see PING_EXTRA_DATA_LEN and *     PING_EXTRA_DATA_FIRST_VALUE definitions). * * PARAMETERS: *     family    - protocol family *     fd        - opened socket (used as request ID) *     p_buf     - pointer to buffer prepared for packet *     p_buf_len - prepared buffer length on input and used buffer *                 length on output * * RETURNS: *     ESUCCESS - success *     EINVAL   - prepared buffer too small or unknown protocol family */static intping_prepare_packet(int family, int fd, char *p_buf, int *p_buf_len){    /* Length of ICMP header */    int hdr_len = (family == AF_INET) ? sizeof(struct icmphdr)                                      : sizeof(struct icmp6_hdr);    /* Total length of the ICMP header and payload */    int total_len = hdr_len + PING_EXTRA_DATA_LEN;        int i;        /* Check if message fit in prepared buffer */    if (*p_buf_len < total_len)    {        return EINVAL;    }        /*     * Paint a numeric pattern in the data portion of the packet,     * so we can verify in a traffic monitor     */    for (i = 0; i < PING_EXTRA_DATA_LEN; i++)    {        p_buf[i + hdr_len] = PING_EXTRA_DATA_FIRST_VALUE + i;    }    if (family == PF_INET)    {        struct icmp *p_icmphdr = (struct icmp *)p_buf;                p_icmphdr->icmp_type  = ICMP_ECHO;        p_icmphdr->icmp_code  = 0;        p_icmphdr->icmp_cksum = 0; /* Calculated and inserted below */        p_icmphdr->icmp_seq   = 0;        p_icmphdr->icmp_id    = fd;        p_icmphdr->icmp_cksum = in_cksum((ushort *)p_icmphdr, total_len);    }    else if (family == PF_INET6)    {        struct icmp6_hdr *p_icmp6hdr = (struct icmp6_hdr *)p_buf;            p_icmp6hdr->icmp6_type  = ICMP6_ECHO_REQUEST;        p_icmp6hdr->icmp6_code  = 0;        p_icmp6hdr->icmp6_cksum = 0; /* Calculated and inserted by kernel */        p_icmp6hdr->icmp6_seq   = 0;        p_icmp6hdr->icmp6_id    = fd;            }    else    {        return EINVAL;    }    /* Return used length of the buffer */    *p_buf_len = total_len;    return ESUCCESS;    } /* ping_prepare_packet *//* tv_sub -- *     Subtract timeval "in" from "out", adjust value of "out" *     with result. * * PARAMETERS: *     out - minuend and difference *     in  - subtrahend * * RETURNS: *     -- */voidtv_sub(struct timeval *out, struct timeval *in){    if ((out->tv_usec -= in->tv_usec) < 0)    {        --out->tv_sec;        out->tv_usec += 1000000;    }    out->tv_sec -= in->tv_sec;} /* tv_sub */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -