티스토리 뷰
설명
목적 서버에 대한 ICMP(:12)에 대한 응답시간을 체크한다.
사용방법
int main(int argc, char **argv) { int sockfd; int ip; struct timeval atime; struct sockaddr_in addr; sockfd = IcmpInit(); ip = CheckIcmp(sockfd, argv[1], &atime, &addr); printf("%s ---> %d sec %d msec\n", inet_ntoa(addr.sin_addr), atime.tv_sec, atime.tv_usec); IcmpClear(sockfd); }
위의 코드를 컴파일한 후 실행시킨 결과다.
# ./icmp_check www.joinc.co.kr 218.234.19.87 ---> 0 sec 8 msec
int IcmpInit();
- ICMP 프로토콜을 사용하는 RAW 소켓을 작성한다.
- return : 열린 소켓지정자를 리턴한다.
int CheckIcmp(int sockfd, char *dstaddr, struct timeval *atime, struct sockaddr_in *ipaddr)
- 목적지 주소로 ICMP ECHO를 전송하고 리턴을 검사한다.
- sockfd : IcmpInit()를 통해서 리턴된 소켓지정자
- dstaddr : 조사하고자 하는 목적지의 인터넷 주소
- atime : 응답 시간 조사, atime.tv_sec (초), atime.tv_usec(밀리세컨드)
- ipaddr : 클라이언트(ECHO REPLAY)호스트 주소
- return : 실패했을 경우 -1을 리턴
int IcmpClear();
- 소켓을 닫고 자원을 해제한다.
코드
#include <stdlib.h> #include <netdb.h> #include <string.h> #include <netinet/ip_icmp.h> #include <arpa/inet.h> #include <errno.h> #include <sys/socket.h> #include <stdio.h> #include <unistd.h> #include <time.h> #include <sys/types.h> // IP CheckSum 생성 int in_cksum(u_short *p, int n) { register u_short answer; register long sum = 0; u_short odd_byte = 0; while(n > 1) { sum += *p++; n -= 2; } if (n == 1) { *(u_char *)(&odd_byte) = *(u_char *)p; sum += odd_byte; } sum = (sum >> 16) + (sum & 0xffff); sum += (sum >> 16); answer = ~sum; return (answer); } // ICMP 프로토콜을 지원하는 RAW소켓 생성 int IcmpInit() { int icmp_socket; icmp_socket = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); return icmp_socket; } int CheckIcmp(int sockfd, char *dstaddr, struct timeval *atime, struct sockaddr_in *ipaddr) { struct icmp *p, *rp; char buffer[1024]; int sl, ret, hlen; int diff; struct sockaddr_in addr, sin, from; struct ip *ip; struct timeval ltime; struct hostent *hentry; // 호스트 이름으로 부터 주소갑을 얻어온다. if ((hentry = gethostbyname(dstaddr)) == NULL) { return -1; } gettimeofday(<ime, NULL); memset(buffer, 0x00, 1024); p = (struct icmp *)buffer; p->icmp_type = ICMP_ECHO; p->icmp_code = 0; p->icmp_cksum = 0; p->icmp_seq = 15; p->icmp_id = getpid(); p->icmp_dun.id_ts.its_otime = ((ltime.tv_sec%100)*10000)+(ltime.tv_usec / 100); p->icmp_cksum = in_cksum((u_short *)p, 1000); memcpy(buffer+sizeof(*p), (void *)&time, 4); memset(&addr, 0, sizeof(0)); memcpy(&addr.sin_addr, hentry->h_addr, hentry->h_length); addr.sin_family = AF_INET; ret = sendto(sockfd, p, sizeof(*p), MSG_DONTWAIT, (struct sockaddr *)&addr, sizeof(addr)); if (ret < 0) { exit(0); return -1; } sl = sizeof(from); ret = recvfrom(sockfd, buffer, 1024, 0, (struct sockaddr *)&from, &sl); if (ret < 0) return -1; ip = (struct ip *)buffer; hlen = ip->ip_hl*4; rp = (struct icmp *)(buffer+hlen); gettimeofday(<ime, NULL); diff = (((ltime.tv_sec%100)*10000)+ltime.tv_usec/100) - rp->icmp_dun.id_ts.its_otime; atime->tv_sec = diff/1000; atime->tv_usec = diff/10; *ipaddr = addr; return sin.sin_addr.s_addr; } int IcmpClear(int sockfd) { close(sockfd); return 1; }
해야될 것
서버가 일정시간 응답하지 않을경우 에러를 발생하고 리턴하도록 코드를 수정해야 한다. 소켓 지정자에 대해 select()를 이용하면 될것이다. 입력에 대한 select()관련 코드는 read_wait를 참고하기 바란다.
출처 :http://www.joinc.co.kr/modules/moniwiki/wiki.php/Site/Code/C/icmp_check
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
TAG
- Java PermGen eclipse 이클립스 메모리 부족
- 공돌/공순 애인님 관리법
- 랜 연결상태
- 남자는 키
- Mista Swing
- Java
- 대청호
- 수락계곡
- 정규식 Regex
- 18-70mm
- 놈놈놈
- 윈도우 제거된 디바이스 드라이버
- gettimeofday
- 코드 예시
- 대둔산
- ckeditor5 #custom image file insert #uploads
- 자바스크립트
- 엑스포다리
- Don't let me be misunderstood
- 멀티바이트 와이드 문자열 변경
- 시동 안걸릴때 여자들은?
- spring-boot #java
- 섹스와 남자들의 착각
- Java Applet
- 나는 아직 살아있는건가
- Signed applet
- kde 전환
- D200
- 날자계산
- 2MB 개새끼
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
글 보관함