?? ping.c
字號(hào):
/* * Created with help from Mike Muuss' PING.C * (part of netkit-base-0.17) * AND * Help from Beej's guide to network programming * http://www.ecst.csuchico.edu/~beej/guide/net/ */#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <errno.h>#include <string.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netdb.h>#include <netinet/ip.h>#include <sys/timeb.h>#include "Ping.h"#define INPACK_LENGTH 65535#define OUTPACK_LENGTH 65535struct icmp_echo { u_int8_t type; u_int8_t code; u_int16_t checksum; u_int16_t identifier; u_int16_t sequence_number;};char *icmp_data;pid_t ident = 0;u_int16_t seq = 0;int sockfd_global;int invalid_checksum = 0;/* * Borrowed the checksum code from: * http://www.fenix.ne.jp/~thomas/memo/ip/checksum.html */unsigned short checksum(unsigned short *buf, int size) { unsigned long sum = 0; while (size > 1) { sum += *buf++; size -= 2; } if (size) { sum += *(u_int8_t *)buf; } sum = (sum & 0xffff) + (sum >> 16); sum = (sum & 0xffff) + (sum >> 16); return ~sum;}int send_echo_request(int sockfd, struct sockaddr_in *their_addr, char *data) { void *outpack = malloc(OUTPACK_LENGTH); size_t space = 0; struct icmp_echo *echo_packet; int numbytes = 0; echo_packet = malloc(sizeof(struct icmp_echo)); if (echo_packet == NULL) return -3; echo_packet->type = 8; echo_packet->code = 0; echo_packet->checksum = 0; echo_packet->identifier = (u_int16_t) getpid(); echo_packet->sequence_number = seq; memcpy(outpack, echo_packet, sizeof(struct icmp_echo)); space += sizeof(struct icmp_echo); memcpy(outpack+(sizeof(struct icmp_echo)), data, strlen(data)); space += strlen(data); invalid_checksum = 0; echo_packet->checksum = checksum((unsigned short *) outpack, space); memcpy(outpack, echo_packet, sizeof(struct icmp_echo)); numbytes = sendto(sockfd, (void *) outpack, space, 0, (struct sockaddr *)their_addr, sizeof(struct sockaddr)); if (numbytes == -1) { return -4; } free(outpack); return 0;}/* * int icmp_echo_send(char *host, int sequence, char *data); * * Parameters: * host - host to send icmp echo packet to * sequence - packet sequence number * data - data to include in packet * * Return Values: * 0 - icmp echo send success * -1 - failure looking up hostname * -2 - failure creating network socket * -3 - error malloc'ing memory * -4 - error sending packet */int icmp_echo_send(char *host, int sequence, char *data) { int sockfd; int packlen = 0; struct hostent *he; struct sockaddr_in dest; if ((he = gethostbyname(host)) == NULL) return -1; sockfd = socket(PF_INET, SOCK_RAW, 1); sockfd_global = sockfd; if (sockfd == -1) return -2; dest.sin_family = PF_INET; dest.sin_port = htons(0); dest.sin_addr = *((struct in_addr *)he->h_addr); memset(&(dest.sin_zero), '\0', 8); ident = getpid(); seq = sequence; return send_echo_request(sockfd, &dest, data);}/* * JNI Wrapper code to icmp_echo_send() */JNIEXPORT jint JNICALL Java_Ping_icmp_1send (JNIEnv *env, jobject obj, jstring host, jint s, jstring data) { jint retval; char *h = (*env)->GetStringUTFChars(env, host, 0); char *d = (*env)->GetStringUTFChars(env, data, 0); retval = (jint) icmp_echo_send(h, s, d); (*env)->ReleaseStringUTFChars(env, host, h); (*env)->ReleaseStringUTFChars(env, data, d); return retval;}/* * JNI Wrapper code to icmp_echo_reply() * (returns NULL if a error occours receiving the packet, * or packet timeout expires) */JNIEXPORT jstring JNICALL Java_Ping_icmp_1recv (JNIEnv *env, jobject obj, jint t) { int retval = icmp_echo_reply(t); jstring tmp; if (retval < 0) { return NULL; } tmp = (*env)->NewStringUTF(env, icmp_data); free(icmp_data); return tmp;}#ifndef LIB/* * Small implementation of ping code for testing purposes */int main(int argc, char *argv[]) { int retval = 0; struct timeb start; struct timeb end; struct timeb res; struct hostent *h; if (argc != 5) { fprintf(stderr, "Error! Usage:\n"); fprintf(stderr, " %s <dst host> <seq num> <data> <timeout>\n", argv[0]); exit(1); } if ((h = gethostbyname(argv[1])) == NULL) { herror("gethostbyname"); exit(1); } printf("icmp echo (request) to %s [%s]\n", h->h_name, inet_ntoa(*((struct in_addr *)h->h_addr))); ftime(&start); retval = icmp_echo_send(argv[1], atoi(argv[2]), argv[3]); if (retval < 0) { fprintf(stderr, "Error (%d) sending packet\n", retval); return; } retval = icmp_echo_reply(atoi(argv[4])); ftime(&end); if (retval < 0) { printf("[TIMEOUT]\n"); return 1; } if (start.millitm > end.millitm) { end.time -= 1; end.millitm += 1000; } printf("time delta: %ds%dms", end.time - start.time, end.millitm - start.millitm); if (invalid_checksum) { printf(" [INCORRECT CHECKSUM]"); } printf("\n"); return 0;}#endifint icmp_reply(void *inpack, int packlen) { struct ip *ip_pkt = malloc(sizeof(struct ip)); struct icmp_echo *icmp_pkt = malloc(sizeof(struct icmp_echo)); size_t ipoptlen; size_t hlen; void *data = malloc(INPACK_LENGTH); void *tmp_ck = malloc(OUTPACK_LENGTH); u_int16_t cksum, cksum_tmp; size_t space = 0; ip_pkt = (struct ip *)inpack; hlen = ip_pkt->ip_hl << 2; ipoptlen = hlen - sizeof(struct ip); packlen -= hlen; icmp_pkt = (struct icmp_echo *) (inpack+hlen); if ((u_int16_t) getpid() != icmp_pkt->identifier) { return -1; } memcpy(data, inpack+hlen+8, packlen-8); cksum = icmp_pkt->checksum; icmp_pkt->checksum = 0; memcpy(tmp_ck, icmp_pkt, sizeof(struct icmp_echo)); space += sizeof(struct icmp_echo); memcpy(tmp_ck+(sizeof(struct icmp_echo)), data, strlen(data)); space += strlen(data); cksum_tmp = checksum((unsigned short *) tmp_ck, space); if (cksum_tmp != cksum) { invalid_checksum = 1; } icmp_pkt->checksum = cksum; icmp_data = malloc(INPACK_LENGTH); sprintf(icmp_data, "%d %s\0", icmp_pkt->sequence_number, data);#ifdef DEBUG printf("received: "); printf("type: %x\n", icmp_pkt->type); printf("code: %x\n", icmp_pkt->code); printf("checksum: %x\n", icmp_pkt->checksum); printf("sequence: %d\n", icmp_pkt->sequence_number); printf("identifier: %d\n", icmp_pkt->identifier); printf("%s\n", (char *)data);#endif return 0;}int icmp_echo_reply(int timeout) { int packlen = 0, retval = 0; void *inpack = malloc(INPACK_LENGTH); fd_set readfds; struct timeval tv; struct sockaddr_in from; socklen_t fromlen = sizeof(from); int sockfd = sockfd_global; FD_ZERO(&readfds); FD_SET(sockfd, &readfds); tv.tv_sec = timeout; tv.tv_usec = 0; while (tv.tv_sec > 0) { retval = select(sockfd + 1, &readfds, NULL, NULL, &tv); if (retval > 0) { packlen = recvfrom(sockfd, inpack, INPACK_LENGTH, 0, (struct sockaddr *)&from, &fromlen); if ((icmp_reply(inpack, packlen)) == -1) {#ifdef DEBUG printf("Not our packet!\n");#endif continue; } else { return 0; } } else { return -1; } }}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -