How to use Winsock to implement ping (source code)

zhaozj2021-02-16  42

/ * This is a sample routine of ping.It's implemented with winsock1.1 * under windows 2000 professional and has been not tested under other * platform.Our target is to illustrator the principles, so many details * may be ignored. (Author email : Zhangwu2003@163.com) * / # include #include #include

#define send_size 32 #define packet_size 4096 # define icmp_echo 8 # define icmp_echoreply 0

Struct ICMP {UNSIGNED CHAR ICMP_TYPE; UNSIGNED CHAR ICMP_CODE; UNSIGNED SHORT ICMP_ID; UNSIGNED SHORT ICMP_SEQ; UNSIGNED long ICMP_DATA;

struct ip {unsigned char ip_hl: 4; unsigned char ip_v: 4; unsigned char ip_tos; unsigned short ip_len; unsigned short ip_id; unsigned short ip_off; unsigned char ip_ttl; unsigned char ip_p; unsigned short ip_sum; unsigned long ip_src; unsigned long ip_dst };

Unsigned char sendpacket [packet_size]; unsigned char reccvpacket [packet_size]; struct sockaddr_in dest_addr; struct sockaddr_in from_addr; int sockfd; int pid;

Unsigned short ca_chksum (unsigned short * addr, int LEN); int Pack (int Pack_no); int LACK (unsigned char * buf, int LEN); void send_packet (void); void recv_packet (void);

Void main (int Argc, char * argv []) {strunt host * host; struct protoent * protocol; wsadata wsadata; int scheout = 1000; int success_count = 4; int in; char * par_host;

PAR_HOST = Argv [Argc-1]; Switch (Argc) {Case 2: Break; Case 3: IF (Strcmp (Argv [1], "- T") == 0) {seund_count = 10000; Break;} // Fall Through Default: Printf ("USAGE:% s [-t] host name or ip address / n", argv [0]); exit (1);}

IF (WSAStartup (0x1010, & WSADATA)! = 0) {Printf ("WsaStartup Error / N"); exit (1);} if ((protocol = getProtobyname ("ICMP")) == null) {printf ("getProtobyname Error / N "); exit (1);} IF ((Sockfd = Socket (AF_INET, SOCK_RAW, Protocol-> p_proto)) <0) {Printf (" Socket Error / N "); exit (1);} if (Setsockopt (SOCKFD, SOL_SOCKET, SO_RCVTIMEO, (CHAR *) & Timeout, SizeOf (Timeout)) <0) FPRINTF (stderr, "failed to set recv timeout:% d / n", wsagetlasterror ()); if (setsockopt (sockfd , SOL_SOCKET, SO_SNDTIMEO, (CHAR *) & Timeout, SizeOf (Timeout)) <0) FPrintf (stderr, "failed to set send timeout:% d / n", wsagetlasterror ()); MEMSET (& dest_addr, 0, sizeof (dest_addr )); Dest_addr.sin_family = af_INET; if (Host = gethostByname (PAR_HOST)) {Memcpy ((char *) & dest_addr.sin_addr, host-> h_addr, host-> h_length; // resolve address to hostname if (Host = GethostByaddr (Host-> H_ADDR, 4, PF_INET)) PAR_HOST = Host-> h_name;} else if (dest_addr.sin_addr.s_addr = inet_addr (par_host) == inaddr_none) {Printf ("Unkown Hos T% S / N ", PAR_HOST); EXIT (1);

PID = get pid (); Printf ("pinging% s []: with% d bytes of data: / n / n", par_host, inet_ntoa (dest_addr.sin_addr), send_size); for (i = 0; i < Send_count; i ) {send_packet (); recv_packet (); SLEEP (1000);}}

// this algorithm is referenced from other's unsigned short cal_chksum (unsigned short * addr, int len) {int nleft = len; int sum = 0; unsigned short * w = addr; unsigned short answer = 0; while (nleft> 1) {SUM = * W ; NLEFT- = 2;} if (NLEFT == 1) {* (unsigned char *) = * (unsigned char *) W; sum = answer;} SUM = (SUM >> 16 ) (SUM & 0xFFF); SUM = (SUM >> 16); Answer = ~ Sum; Return Answer;} // Packing INT PACK (INT PACK_NO) {INT PACKSIZE; Struct ICMP * ICMP;

packsize = 8 SEND_SIZE; icmp = (struct icmp *) sendpacket; icmp-> icmp_type = ICMP_ECHO; icmp-> icmp_code = 0; icmp-> icmp_cksum = 0; icmp-> icmp_seq = pack_no; icmp-> icmp_id = pid; ICMP-> ICMP_DATA = GettickCount (); ICMP-> ICMP_CKSUM = CAL_CHKSUM ((unsigned short *) ICMP, PACKSIZE); / * Calibration Algorithm * / Return Packsize;}

// Unpack INT Unpack (INSIGNED Char * BUF, INT LEN) {struct ip * ip; struct icmp * icmp; double ipt; int iphdrlen

IP = (struct ip *) BUF; iPhdrlen = IP-> ip_hl * 4; ICMP = (struct ICMP *); if ((ICMP-> ICMP_TYPE == ICMP_ECHOREPLY) && (ICMP-> ICMP_ID == PID)) {len = len-iphdrlen-8; rtt = gettickcount () - ICMP-> ICMP_DATA; Printf ("reply from% s: bytes =% D time =%. 0FMS TTL =% D ICMP_SEQ =% u / n ", Inet_ntoa (from_addr.sin_addr), len, rtt, ip-> ip_ttl, ICMP-> ICMP_SEQ); Return 1;} return 0;

// Send void send_packet () {int packetsize; static int pack_no = 0; packetsize = pack (pack_no ); if (sendto (sockfd, sendpacket, packetsize, 0, (struct sockaddr *) & dest_addr, sizeof (dest_addr)) <0 ) Printf ("Destination Host Unreachable./N"; "Send N% D / N", PACK_NO-1);} // Receive Void RECV_PACKET () {Int n, fromlen; Int Success;

FromLen = SizeOf (from_addr); Do {IF ((N = Recvfrom (Sockfd, RecvPacket, Sizeof (Recvpacket), 0, (Struct SockAddr *) & from_addr, & fromlease)> = 0) Success = Unpack (Recvpacket, n); ELSE IF (Wsagetlasterror () == wsaetimedout) {Printf ("Request Timed Out./N"); Return;}} while (! "

}

转载请注明原文地址:https://www.9cbs.com/read-26172.html

New Post(0)