📄 main.c
字号:
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/socket.h>#include <sys/socketvar.h>#include <sys/types.h>#include <netinet/in.h>#include <netdb.h>#include <arpa/inet.h>#include <time.h>#include <string.h>#define IP_RECORD_ROUTE 0x7#define DEF_PACKET_SIZE 32#define MAX_PACKET 1024 // Max ICMP packet size#define MAX_IP_HDR_SIZE 60 // Max IP header size w/options#define ICMP_ECHO 8#define ICMP_ECHOREPLY 0#define ICMP_MIN 8 // Minimum 8-byte ICMP packet (header)typedef struct _iphdr{ unsigned int h_len:4; // Length of the header unsigned int version:4; // Version of IP unsigned char tos; // Type of service unsigned short total_len; // Total length of the packet unsigned short ident; // Unique identifier unsigned short frag_and_flags; // Flags unsigned char ttl; // Time to live unsigned char proto; // Protocol (TCP, UDP etc) unsigned short checksum; // IP checksum unsigned int sourceIP; unsigned int destIP;}IpHeader;/* ***** Initial definition of IcmpHeader *****typedef struct _icmphdr{ BYTE i_type; BYTE i_code; // Type sub code USHORT i_cksum; USHORT i_id; USHORT i_seq; // This is not the standard header, but we reserve space for time ULONG timestamp;} IcmpHeader;*/typedef struct _icmphdr{ unsigned char i_type; unsigned char i_code; // Type sub code unsigned short i_cksum; unsigned short i_id; unsigned short i_seq; // This is not the standard header, but we reserve space for time unsigned long timestamp;}IcmpHeader;//// IP option header - use with socket option IP_OPTIONS//typedef struct _ipoptionhdr{ unsigned char code; // Option type unsigned char len; // Length of option hdr unsigned char ptr; // Offset into options unsigned long addr[9]; // List of IP addrs}IpOptionHeader;typedef struct sockaddr_in SOCKADDR_IN;typedef struct in_addr IN_ADDR;typedef struct hostent HOSTENT;int m_hSocket;IpOptionHeader m_ipopt;struct sockaddr_in m_addrDest;struct sockaddr_in m_addrFrom;char *icmp_data;char *recvbuf;unsigned short seq_no;char *lpdest;int m_bRecordRout;int datasize;/*************************************************************************** main.c - description ------------------- begin : 二 1月 7 16:32:47 CST 2003 copyright : (C) 2003 by 闻思源 email : wsy0@263.net ***************************************************************************//*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/#ifdef HAVE_CONFIG_H#include <config.h>#endifvoid initalize(){ icmp_data = NULL; seq_no = 0; recvbuf = NULL; m_bRecordRout = 0;/* lpdest = NULL; */ datasize = DEF_PACKET_SIZE; m_hSocket = 0;}void FillICMPData(char *icmp_data, int datasize){ IcmpHeader *icmp_hdr = NULL; char *datapart = NULL; icmp_hdr = (IcmpHeader *)icmp_data; icmp_hdr->i_type = ICMP_ECHO; // Request an ICMP echo icmp_hdr->i_code = 0; icmp_hdr->i_id = (unsigned short)getpid(); icmp_hdr->i_cksum = 0; icmp_hdr->i_seq = 0; datapart = icmp_data + sizeof(IcmpHeader);}void DecodeIPOptions(char *buf, int bytes){ IpOptionHeader *ipopt = NULL; struct in_addr inaddr; int i; HOSTENT *host = NULL; ipopt = (IpOptionHeader *)(buf + 20); printf("RR: "); for(i = 0; i < (ipopt->ptr / 4) - 1; i++) { inaddr.s_addr = ipopt->addr[i]; if (i != 0) printf(" "); host = gethostbyaddr((char *)&inaddr.s_addr, sizeof(inaddr.s_addr), AF_INET); if (host) printf("(%-15s) %s\n", inet_ntoa(inaddr), host->h_name); else printf("(%-15s)\n", inet_ntoa(inaddr)); } return;}unsigned short checksum(unsigned short *buffer, int size){ unsigned long cksum=0; while (size > 1) { cksum += *buffer++; size -= sizeof(unsigned short); } if (size) { cksum += *(unsigned char *)buffer; } cksum = (cksum >> 16) + (cksum & 0xffff); cksum += (cksum >>16); return (unsigned short)(~cksum);}void DecodeICMPHeader(char *buf, int bytes, SOCKADDR_IN *from){ IpHeader *iphdr = NULL; IcmpHeader *icmphdr = NULL; unsigned short iphdrlen; clock_t tick; static int icmpcount = 0; iphdr = (IpHeader *)buf; /* Number of 32-bit words * 4 = bytes */ iphdrlen = iphdr->h_len * 4; tick = clock(); if ((iphdrlen == MAX_IP_HDR_SIZE) && (!icmpcount)) DecodeIPOptions(buf, bytes); if (bytes < iphdrlen + ICMP_MIN) { printf("Too few bytes from %s\n", inet_ntoa(from->sin_addr)); } icmphdr = (IcmpHeader*)(buf + iphdrlen); if (icmphdr->i_type != ICMP_ECHOREPLY) { printf("nonecho type %d recvd\n", icmphdr->i_type); return; } // Make sure this is an ICMP reply to something we sent! // if (icmphdr->i_id != (unsigned short)getpid()) { printf("someone else's packet!\n"); return ; } printf("%d bytes from %s:", bytes, inet_ntoa(from->sin_addr)); printf(" icmp_seq = %d. ", icmphdr->i_seq); printf(" time: %d ms", (double)(tick - icmphdr->timestamp)); printf("\n"); icmpcount++; return;}void ping(int timeout){ m_hSocket = socket (AF_INET, SOCK_RAW, 1); if (m_hSocket == -1) { printf("socket() failed: \n"); return ; } printf("socket() SUCCESS!\n"); if (m_bRecordRout) { // Setup the IP option header to go out on every ICMP packet // bzero(&m_ipopt, sizeof(m_ipopt)); m_ipopt.code = IP_RECORD_ROUTE; // Record route option m_ipopt.ptr = 4; // Point to the first addr offset m_ipopt.len = 39; // Length of option header /* int ret = setsockopt(m_hSocket, SOL_SOCKET, IP_OPTION (void *)&m_ipopt, sizeof(m_ipopt)); if (ret == -1) { printf("setsockopt(IP_OPTIONS) failed! \n" ); return ; } */ } // Set the send/recv timeout values int bread; /* bread = setsockopt(m_hSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout)); if(bread == -1) { printf("setsockopt(SO_RCVTIMEO) failed! \n"); return ; } */ timeout = 1000; /* bread = setsockopt(m_hSocket, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, sizeof(timeout)); if (bread == -1) { printf("setsockopt(SO_SNDTIMEO) failed! \n" ); return ; } *//* memset(&m_addrDest, 0, sizeof(SOCKADDR_IN)); printf("memset(&m_addrDest, 0, sizeof(SOCKADDR_IN)) SUCCESS\n");*/ // // Resolve the endpoint's name if necessary // /* m_addrDest.sin_family = AF_INET; */ // lpdest="168.1.0.1"; m_addrDest.sin_addr.s_addr = inet_addr(lpdest); printf("inet_addr(lpdest) SUCCESS!"); if (m_addrDest.sin_addr.s_addr == INADDR_NONE) /* if (inet_aton(lpdest,&(m_addrDest.sin_addr))== -1) */ { printf("the IP address is not Dot Number format\n"); struct hostent *hp = NULL; if ((hp = gethostbyname(lpdest)) != NULL) { memcpy(&(m_addrDest.sin_addr), hp->h_addr, hp->h_length); /*m_addrDest.sin_family = hp->h_addrtype; */ printf("m_addrDest.sin_addr = %s\n", inet_ntoa(m_addrDest.sin_addr)); } else { printf("gethostbyname() failed! \n" ); return ; } } printf("(m_addrDest.sin_addr.s_addr = inet_addr(lpdest)) != INADDR_NONE\n"); // // Create the ICMP packet // datasize += sizeof(IcmpHeader); icmp_data =(char *) malloc(MAX_PACKET); recvbuf =(char *) malloc(MAX_PACKET); if (!icmp_data) { printf("malloc() failed! \n" ); return ; } memset(icmp_data,0,MAX_PACKET); FillICMPData(icmp_data,datasize); // // Start sending/receiving ICMP packets // while(1) { static int nCount = 0; int bwrote; if (nCount++ == 4) break; ((IcmpHeader*)icmp_data)->i_cksum = 0; ((IcmpHeader*)icmp_data)->timestamp = (double)clock(); ((IcmpHeader*)icmp_data)->i_seq = seq_no++; ((IcmpHeader*)icmp_data)->i_cksum = checksum((unsigned short *)icmp_data, datasize); bwrote = sendto(m_hSocket, icmp_data, datasize, 0, (struct sockaddr *)&m_addrDest, sizeof(m_addrDest)); if (bwrote == -1) { /* if (WSAGetLastError() == WSAETIMEDOUT) { printf("timed out\n"); continue; } */ printf("sendto() failed!\n"); return ; } if (bwrote < datasize) { printf("Wrote %d bytes\n", bwrote); } int fromlen = sizeof(m_addrFrom); bread = recvfrom(m_hSocket, recvbuf, MAX_PACKET, 0, (struct sockaddr*)&m_addrFrom, &fromlen); if (bread == -1) { /* if (WSAGetLastError() == WSAETIMEDOUT) { printf("ping %s timed out\n",inet_ntoa(m_addrFrom.sin_addr)); continue; } */ printf("recvfrom() failed! \n"); return ; } DecodeICMPHeader(recvbuf, bread, &m_addrFrom); sleep(1); }}int main(int argc, char *argv[]){ printf("Hello, Welcome to Ping\n"); if(argc!=2) { printf("usage: ping hostname\n"); exit; } lpdest=argv[1]; printf("the destination HOST is %s\n",lpdest); // initalize the variables initalize(); ping(1000); return EXIT_SUCCESS;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -