'2008/09/09'에 해당되는 글 1건

  1. 2008/09/09 장인정신 [C/Network/ICMP(v6)] ping 구현 예제 #2 - 20080909 (3)
DIV class=postbodyBRBRBRBRBR이것은 ICMP 및 ICMPv6를 사용한 ping구현에 대한 예제성격의 소스입니다.BR옛날에도 제가 ping 을 간략하게 구현한바 있었죠.BR이번에 올리는것은 그때버젼보다는 좀더 완성도가 있는 버젼이라고 말할수 있겠습니다.BR게다가 IPv6를 고려한 ICMPv6를 구현한 부분도 추가되었습니다.BR물론 아직도 완전한 버젼은 아니고 다음에 또 기회가 되면 좀더 완성해서 올려볼까 합니다.BRBR테스트 하실때는 당연히 RAW socket을 사용하기 때문에 root 권한으로 실행하셔야 합니다.BRBR DIV class=codetitleBCode:/B/DIV DIV class=codecontent/*BRCopyright (C) INFOEQ co.,LTD.BRAll rights reserved.BRBRAuthor: JaeHyuk Cho lt;minzkn@infoeq.comgt;BRBRTiny ping example sourceBR*/BRBR/* need for struct addrinfo */BR#if 1L amp;amp; (!defined(_POSIX_SOURCE))BR# define _POSIX_SOURCEnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp;(1L)BR#endifBRBR#include lt;sys/types.hgt;BR#include lt;sys/time.hgt;BR#include lt;sys/socket.hgt;BR#include lt;stdio.hgt;BR#include lt;stdlib.hgt;BR#include lt;string.hgt;BR#include lt;unistd.hgt;BRBR#include lt;netinet/in.hgt;BR#include lt;netdb.hgt;BR#include lt;arpa/inet.hgt;BRBR#define def_mzping_icmp_optimize (1)BRBR#define def_mzping_icmp_min_packet_size (1 + 1 + 2 + 2 + 2) /* type(1) + code(1) + checksum(2) + identifier(2) + sequence_number(2) */BRBRstatic unsigned int mzping_icmp_checksum(const void *s_data, size_t s_size);BRstatic unsigned int mzping_ts32_us(void);BRstatic int mzping_icmp_v4(int s_socket, const char *s_hostname, const char *s_address_string, struct addrinfo *s_addrinfo, int s_sequence_number, int s_timeout);BRstatic int mzping_icmp_v6(int s_socket, const char *s_hostname, const char *s_address_string, struct addrinfo *s_addrinfo, int s_sequence_number, int s_timeout);BRBRint mzping(const char *s_hostname, int s_count);BRBRint main(int s_argc, char **s_argv);BRBRstatic unsigned int mzping_icmp_checksum(const void *s_data, size_t s_size)BR{BRnbsp; nbsp; register unsigned int s_result = 0u;BRBRnbsp; nbsp; while(s_size gt; ((size_t)1)) {BR#if def_mzping_icmp_optimize == (0)nbsp; nbsp; BRnbsp; nbsp; nbsp; nbsp; s_result += (unsigned int)(ntohs(*((const unsigned short int *)s_data)));BR#elseBRnbsp; nbsp; nbsp; nbsp; s_result += (unsigned int)(*((const unsigned short int *)s_data));BR#endifnbsp; nbsp; nbsp; nbsp; BRnbsp; nbsp; nbsp; nbsp; s_data = ((const unsigned short int *)s_data) + ((size_t)1);BRnbsp; nbsp; nbsp; nbsp; s_size -= (size_t)2;BRnbsp; nbsp; }BRnbsp; nbsp;BRnbsp; nbsp; if(s_size gt; ((size_t)0)) {BRnbsp; nbsp; nbsp; nbsp; s_result += (unsigned int)(*((const unsigned char *)s_data));BRnbsp; nbsp; }BRBR#if def_mzping_icmp_optimize == (0)nbsp; nbsp; BRnbsp; nbsp; while(s_result gt; 0xffffu) {BRnbsp; nbsp; nbsp; nbsp; s_result = (s_result gt;gt; 16) + (s_result amp; 0xffffu);BRnbsp; nbsp; }BR#elseBRnbsp; nbsp; s_result = (s_result gt;gt; 16) + (s_result amp; 0xffffu);BRnbsp; nbsp; s_result += s_result gt;gt; 16;BR#endifBRBR#if def_mzping_icmp_optimize == (0)nbsp; nbsp; BRnbsp; nbsp; return(htons((~s_result) amp; 0xffffu));BR#elseBRnbsp; nbsp; return((~s_result) amp; 0xffffu);BR#endifBR}BRBRstatic unsigned int mzping_ts32_us(void)BR{BRnbsp; nbsp; struct timeval s_timeval;BRnbsp; nbsp; BRnbsp; nbsp; (void)gettimeofday((struct timeval *)(amp;s_timeval), (void *)0);BRnbsp; nbsp; BRnbsp; nbsp; return((s_timeval.tv_sec * 1000000u) + s_timeval.tv_usec);BR}BRBRstatic int mzping_icmp_v4(int s_socket, const char *s_hostname, const char *s_address_string, struct addrinfo *s_addrinfo, int s_sequence_number, int s_timeout)BR{BRnbsp; nbsp; int s_result, s_check, s_myid;BRnbsp; nbsp; unsigned char s_packet[ (20 + 40) + (def_mzping_icmp_min_packet_size + 4) ];BRnbsp; nbsp; size_t s_packet_size;BRnbsp; nbsp; ssize_t s_send_bytes;BRnbsp; nbsp; size_t s_ip_header_size;BRnbsp; nbsp; fd_set s_fd_rx;BRnbsp; nbsp; struct timeval s_timeval;BRnbsp; nbsp; ssize_t s_recv_bytes;BRnbsp; nbsp; socklen_t s_socklen_in;BRnbsp; nbsp; struct sockaddr_in s_sockaddr_in;BRBRnbsp; nbsp; s_result = (-1);BRnbsp; nbsp; s_myid = (int)(getpid() amp; 0xffff);BRBRnbsp; nbsp; s_packet_size = (size_t)0;BRnbsp; nbsp; s_packet[s_packet_size] = 8u; /* ICMP_ECHO */BRnbsp; nbsp; s_packet_size += (size_t)1;BRnbsp; nbsp; s_packet[s_packet_size] = 0u; /* code */BRnbsp; nbsp; s_packet_size += (size_t)1;BRnbsp; nbsp; *((unsigned short int *)(amp;s_packet[s_packet_size])) = 0u; /* checksum */BRnbsp; nbsp; s_packet_size += (size_t)2;BRnbsp; nbsp; *((unsigned short int *)(amp;s_packet[s_packet_size])) = htons(s_myid); /* identifier */BRnbsp; nbsp; s_packet_size += (size_t)2;BRnbsp; nbsp; *((unsigned short int *)(amp;s_packet[s_packet_size])) = htons(s_sequence_number); /* sequence number */BRnbsp; nbsp; s_packet_size += (size_t)2;BR#if def_mzping_icmp_optimize == (0)nbsp; nbsp; BRnbsp; nbsp; *((unsigned int *)(amp;s_packet[8])) = htonl(mzping_ts32_us()); /* optional: time stamp */BR#elseBRnbsp; nbsp; *((unsigned int *)(amp;s_packet[8])) = (unsigned int)mzping_ts32_us(); /* optional: time stamp */BR#endifBRnbsp; nbsp; s_packet_size += (size_t)4;BRBRnbsp; nbsp; /* do checksum */BRnbsp; nbsp; *((unsigned short int *)(amp;s_packet[2])) = mzping_icmp_checksum((const void *)(amp;s_packet[0]), s_packet_size); /* checksum */BRnbsp; BRnbsp; nbsp; s_send_bytes = sendto(s_socket, (const void *)(amp;s_packet[0]), s_packet_size, MSG_NOSIGNAL,BRnbsp; nbsp; nbsp; nbsp; (struct sockaddr *)s_addrinfo-gt;ai_addr, s_addrinfo-gt;ai_addrlen);BRnbsp; nbsp; if(s_send_bytes != ((ssize_t)s_packet_size)) {BRnbsp; nbsp; nbsp; nbsp; (void)fprintf(stderr, send: can not send %ld/%lu\n, (long)s_send_bytes, (unsigned long)sizeof(s_packet));BRnbsp; nbsp; nbsp; nbsp; return(-1);BRnbsp; nbsp; }BRBRl_need_echoreply:;BRnbsp; nbsp; FD_ZERO(amp;s_fd_rx);BRnbsp; nbsp; FD_SET(s_socket, amp;s_fd_rx);BRnbsp; nbsp; s_timeval.tv_sec = s_timeout / 1000;BRnbsp; nbsp; s_timeval.tv_usec = (s_timeout % 1000) * 1000;BRnbsp; nbsp; s_check = select(s_socket + 1, (fd_set *)(amp;s_fd_rx), (fd_set *)0, (fd_set *)0, (struct timeval *)(amp;s_timeval));BRnbsp; nbsp; if(s_check == (-1)) {BRnbsp; nbsp; nbsp; nbsp; perror(select);BRnbsp; nbsp; nbsp; nbsp; return(-1);BRnbsp; nbsp; }BRnbsp; nbsp; if(s_check == 0) {BRnbsp; nbsp; nbsp; nbsp; (void)fprintf(stderr, select: timeout\n);BRnbsp; nbsp; nbsp; nbsp; return(-1);BRnbsp; nbsp; }BRnbsp; nbsp; if(FD_ISSET(s_socket, amp;s_fd_rx) == 0) {BRnbsp; nbsp; nbsp; nbsp; (void)fprintf(stderr, select: is not set\n);BRnbsp; nbsp; nbsp; nbsp; return(-1);BRnbsp; nbsp; }BRBRnbsp; nbsp; s_socklen_in = (socklen_t)sizeof(s_sockaddr_in);BRnbsp; nbsp; s_recv_bytes = recvfrom(s_socket, (void *)(amp;s_packet[0]), sizeof(s_packet), MSG_NOSIGNAL, (struct sockaddr *)(amp;s_sockaddr_in), (socklen_t *)(amp;s_socklen_in));BRnbsp; nbsp; if(s_recv_bytes == ((ssize_t)(-1))) {BRnbsp; nbsp; nbsp; nbsp; perror(recvfrom);BRnbsp; nbsp; nbsp; nbsp; return(-1);BRnbsp; nbsp; }BRnbsp; nbsp; BRnbsp; nbsp; s_ip_header_size = ((size_t)((s_packet[0] gt;gt; 0) amp; 0x0fu)) lt;lt; 2;BRnbsp; nbsp; if(s_recv_bytes lt; (s_ip_header_size + s_packet_size)) {BRnbsp; nbsp; nbsp; nbsp; /* (void)fprintf(stderr, too small packet\n); */BRnbsp; nbsp; nbsp; nbsp; goto l_need_echoreply;BRnbsp; nbsp; }BRBRnbsp; nbsp; if(ntohs(*((unsigned short int *)(amp;s_packet[s_ip_header_size + 4]))) != s_myid) {BRnbsp; nbsp; nbsp; nbsp; /* (void)fprintf(stderr, not my ping\n); */BRnbsp; nbsp; nbsp; nbsp; goto l_need_echoreply;BRnbsp; nbsp; }BRnbsp; nbsp; BRnbsp; nbsp; if(s_packet[s_ip_header_size] == 8u /* ICMP_ECHO */) { /* maybe localhost loopback case */BRnbsp; nbsp; nbsp; nbsp; goto l_need_echoreply;BRnbsp; nbsp; }BRBRnbsp; nbsp; if(s_packet[s_ip_header_size] == 0u /* ICMP_ECHOREPLY */) {BRnbsp; nbsp; nbsp; nbsp; unsigned int s_trip_time;BRnbsp; nbsp; nbsp; nbsp; s_result = (int)ntohs(*((unsigned short int *)(amp;s_packet[s_ip_header_size + 1 + 1 + 2 + 2])));BR#if def_mzping_icmp_optimize == (0)nbsp; nbsp; BRnbsp; nbsp; nbsp; nbsp; s_trip_time = mzping_ts32_us() - ntohl(*((unsigned int *)(amp;s_packet[s_ip_header_size + def_mzping_icmp_min_packet_size])));BR#elseBRnbsp; nbsp; nbsp; nbsp; s_trip_time = mzping_ts32_us() - (*((unsigned int *)(amp;s_packet[s_ip_header_size + def_mzping_icmp_min_packet_size])));BR#endifBRnbsp; nbsp; nbsp; nbsp; (void)fprintf(stdout, %ld bytes from %s (%s): icmp_seq=%d ttl=%u time=%u.%03u ms;\n,BRnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; (unsigned long)(s_recv_bytes - (s_ip_header_size)),BRnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; s_hostname,BRnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; s_address_string,BRnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; s_result,BRnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; (unsigned int)s_packet[8],BRnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; s_trip_time / 1000u,BRnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; s_trip_time % 1000u);BRnbsp; nbsp; }BRBRnbsp; nbsp; return(s_result);BR}BRBRstatic int mzping_icmp_v6(int s_socket, const char *s_hostname, const char *s_address_string, struct addrinfo *s_addrinfo, int s_sequence_number, int s_timeout)BR{BRnbsp; nbsp; int s_result, s_check, s_myid;BRnbsp; nbsp; unsigned char s_packet[ (def_mzping_icmp_min_packet_size + 4) ];BRnbsp; nbsp; size_t s_packet_size;BRnbsp; nbsp; ssize_t s_send_bytes;BRBRnbsp; nbsp; fd_set s_fd_rx;BRnbsp; nbsp; struct timeval s_timeval;BRnbsp; nbsp; ssize_t s_recv_bytes;BRnbsp; nbsp; socklen_t s_socklen_in;BRnbsp; nbsp; struct sockaddr_in s_sockaddr_in;BRBRnbsp; nbsp; s_result = (-1);BRnbsp; nbsp; s_myid = (int)(getpid() amp; 0xffff);BRBRnbsp; nbsp; s_packet_size = (size_t)0;BRnbsp; nbsp; s_packet[s_packet_size] = 128u; /* ICMP6_ECHO_REQUEST */BRnbsp; nbsp; s_packet_size += (size_t)1;BRnbsp; nbsp; s_packet[s_packet_size] = 0u; /* code */BRnbsp; nbsp; s_packet_size += (size_t)1;BRnbsp; nbsp; *((unsigned short int *)(amp;s_packet[s_packet_size])) = 0u; /* checksum */BRnbsp; nbsp; s_packet_size += (size_t)2;BRnbsp; nbsp; *((unsigned short int *)(amp;s_packet[s_packet_size])) = htons(s_myid); /* identifier */BRnbsp; nbsp; s_packet_size += (size_t)2;BRnbsp; nbsp; *((unsigned short int *)(amp;s_packet[s_packet_size])) = htons(s_sequence_number); /* sequence number */BRnbsp; nbsp; s_packet_size += (size_t)2;BR#if def_mzping_icmp_optimize == (0)nbsp; nbsp; BRnbsp; nbsp; *((unsigned int *)(amp;s_packet[8])) = htonl(mzping_ts32_us()); /* optional: time stamp */BR#elseBRnbsp; nbsp; *((unsigned int *)(amp;s_packet[8])) = (unsigned int)mzping_ts32_us(); /* optional: time stamp */BR#endifBRnbsp; nbsp; s_packet_size += (size_t)4;BRBRnbsp; nbsp; /* do checksum */BRnbsp; nbsp; *((unsigned short int *)(amp;s_packet[2])) = mzping_icmp_checksum((const void *)(amp;s_packet[0]), s_packet_size); /* checksum */BRBRnbsp; nbsp; s_send_bytes = sendto(s_socket, (const void *)(amp;s_packet[0]), s_packet_size, MSG_NOSIGNAL,BRnbsp; nbsp; nbsp; nbsp; (struct sockaddr *)s_addrinfo-gt;ai_addr, s_addrinfo-gt;ai_addrlen);BRnbsp; nbsp; if(s_send_bytes != ((ssize_t)s_packet_size)) {BRnbsp; nbsp; nbsp; nbsp; (void)fprintf(stderr, send: can not send %ld/%lu\n, (long)s_send_bytes, (unsigned long)sizeof(s_packet));BRnbsp; nbsp; nbsp; nbsp; return(-1);BRnbsp; nbsp; }BRBRl_need_echoreply:;BRnbsp; nbsp; FD_ZERO(amp;s_fd_rx);BRnbsp; nbsp; FD_SET(s_socket, amp;s_fd_rx);BRnbsp; nbsp; s_timeval.tv_sec = s_timeout / 1000;BRnbsp; nbsp; s_timeval.tv_usec = (s_timeout % 1000) * 1000;BRnbsp; nbsp; s_check = select(s_socket + 1, (fd_set *)(amp;s_fd_rx), (fd_set *)0, (fd_set *)0, (struct timeval *)(amp;s_timeval));BRnbsp; nbsp; if(s_check == (-1)) {BRnbsp; nbsp; nbsp; nbsp; perror(select);BRnbsp; nbsp; nbsp; nbsp; return(-1);BRnbsp; nbsp; }BRnbsp; nbsp; if(s_check == 0) {BRnbsp; nbsp; nbsp; nbsp; (void)fprintf(stderr, select: timeout\n);BRnbsp; nbsp; nbsp; nbsp; return(-1);BRnbsp; nbsp; }BRnbsp; nbsp; if(FD_ISSET(s_socket, amp;s_fd_rx) == 0) {BRnbsp; nbsp; nbsp; nbsp; (void)fprintf(stderr, select: is not set\n);BRnbsp; nbsp; nbsp; nbsp; return(-1);BRnbsp; nbsp; }BRnbsp; nbsp; BRnbsp; nbsp; s_socklen_in = (socklen_t)sizeof(s_sockaddr_in);BRnbsp; nbsp; s_recv_bytes = recvfrom(s_socket, (void *)(amp;s_packet[0]), sizeof(s_packet), MSG_NOSIGNAL, (struct sockaddr *)(amp;s_sockaddr_in), (socklen_t *)(amp;s_socklen_in));BRnbsp; nbsp; if(s_recv_bytes == ((ssize_t)(-1))) {BRnbsp; nbsp; nbsp; nbsp; perror(recvfrom);BRnbsp; nbsp; nbsp; nbsp; return(-1);BRnbsp; nbsp; }BRnbsp; nbsp; BRnbsp; nbsp; if(s_recv_bytes lt; s_packet_size) {BRnbsp; nbsp; nbsp; nbsp; /* (void)fprintf(stderr, too small packet\n); */BRnbsp; nbsp; nbsp; nbsp; goto l_need_echoreply;BRnbsp; nbsp; }BRnbsp; nbsp; BRnbsp; nbsp; if(ntohs(*((unsigned short int *)(amp;s_packet[4]))) != s_myid) {BRnbsp; nbsp; nbsp; nbsp; /* (void)fprintf(stderr, not my ping\n); */BRnbsp; nbsp; nbsp; nbsp; goto l_need_echoreply;BRnbsp; nbsp; }BRBRnbsp; nbsp; if(s_packet[0] == 128u /* ICMP6_ECHO_REQUEST */) {BRnbsp; nbsp; nbsp; nbsp; goto l_need_echoreply;BRnbsp; nbsp; }BRnbsp; nbsp; BRnbsp; nbsp; if(s_packet[0] == 129u /* ICMP6_ECHO_REPLY */) {BRnbsp; nbsp; nbsp; nbsp; unsigned int s_trip_time;BRnbsp; nbsp; nbsp; nbsp; s_result = (int)ntohs(*((unsigned short int *)(amp;s_packet[1 + 1 + 2 + 2])));BR#if def_mzping_icmp_optimize == (0)nbsp; nbsp; BRnbsp; nbsp; nbsp; nbsp; s_trip_time = mzping_ts32_us() - ntohl(*((unsigned int *)(amp;s_packet[def_mzping_icmp_min_packet_size])));BR#elseBRnbsp; nbsp; nbsp; nbsp; s_trip_time = mzping_ts32_us() - (*((unsigned int *)(amp;s_packet[def_mzping_icmp_min_packet_size])));BR#endifBRnbsp; nbsp; nbsp; nbsp; (void)fprintf(stdout, %ld bytes from %s (%s): icmp_seq=%d ttl=%u time=%u.%03u ms;\n,BRnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; (unsigned long)s_recv_bytes,BRnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; s_hostname,BRnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; s_address_string,BRnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; s_result,BRnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; (unsigned int)0u /* TODO: Hops limit here */,BRnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; s_trip_time / 1000u,BRnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; s_trip_time % 1000u);BRnbsp; nbsp; }BRBRnbsp; nbsp; return(s_result);BR}BRBRint mzping(const char *s_hostname, int s_count)BR{BRnbsp; nbsp; int s_sequence_number = 0, s_check, s_socket;BRnbsp; nbsp; struct addrinfo *s_addrinfo_result;BRnbsp; nbsp; struct addrinfo s_addrinfo_hints;BRnbsp; nbsp; struct addrinfo *s_addrinfo;BRnbsp; nbsp; char s_address_string[ 64 ];BRnbsp; nbsp;BRnbsp; nbsp; /* resolv name */BRnbsp; nbsp; (void)memset((void *)(amp;s_addrinfo_hints), 0, sizeof(s_addrinfo_hints));BRnbsp; nbsp; s_addrinfo_hints.ai_socktype = SOCK_RAW;BRnbsp; nbsp; s_addrinfo_hints.ai_family = AF_UNSPEC;BRnbsp; nbsp; s_check = getaddrinfo(s_hostname, (const char *)0, (const struct addrinfo *)(amp;s_addrinfo_hints), (struct addrinfo **)(amp;s_addrinfo_result));BRnbsp; nbsp; if(s_check != 0) {BRnbsp; nbsp; nbsp; nbsp; (void)fprintf(stderr, getaddrinfo error: %s\n, gai_strerror(s_check));BRnbsp; nbsp; nbsp; nbsp; return(-1);BRnbsp; nbsp; }BRBRnbsp; nbsp; do {BRnbsp; nbsp; nbsp; nbsp; s_sequence_number++;BRBRnbsp; nbsp; nbsp; nbsp; for(s_addrinfo = s_addrinfo_result;s_addrinfo != ((struct addrinfo *)0);s_addrinfo = s_addrinfo-gt;ai_next) {BRnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; if(s_addrinfo-gt;ai_family == AF_INET) { /* ICMP */BRnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; struct sockaddr_in *s_in;BRBRnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; s_socket = socket(s_addrinfo-gt;ai_family, SOCK_RAW, IPPROTO_ICMP);BRnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; if(s_socket == (-1)) {BRnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; perror(socket);BRnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; continue;BRnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; }BRBRnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; s_in = (struct sockaddr_in *)s_addrinfo-gt;ai_addr;BRnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; inet_ntop(s_addrinfo-gt;ai_family, (const void *)(amp;s_in-gt;sin_addr), (char *)(amp;s_address_string[0]), (socklen_t)sizeof(s_address_string));BRnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; BRnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; s_check = mzping_icmp_v4(s_socket, s_hostname, (const char *)(amp;s_address_string[0]), s_addrinfo, s_sequence_number, 20000);BRnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; close(s_socket);BRnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; }BRnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; else if(s_addrinfo-gt;ai_family == AF_INET6) { /* ICMPv6 */BRnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; struct sockaddr_in6 *s_in6;BRnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; BRnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; s_socket = socket(s_addrinfo-gt;ai_family, SOCK_RAW, IPPROTO_ICMPV6);BRnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; if(s_socket == (-1)) {BRnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; perror(socket);BRnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; continue;BRnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; }BRnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; BRnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; s_in6 = (struct sockaddr_in6 *)s_addrinfo-gt;ai_addr;BRnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; inet_ntop(s_addrinfo-gt;ai_family, (const void *)(amp;s_in6-gt;sin6_addr), (char *)(amp;s_address_string[0]), (socklen_t)sizeof(s_address_string));BRnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; BRnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; s_check = mzping_icmp_v6(s_socket, s_hostname, (const char *)(amp;s_address_string[0]), s_addrinfo, s_sequence_number, 20000);BRnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; close(s_socket);BRnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; }BRnbsp; nbsp; nbsp; nbsp; }BRBRnbsp; nbsp; nbsp; nbsp; (void)sleep(1);BRnbsp; nbsp; }while(s_sequence_number lt; s_count);BRBRnbsp; nbsp; freeaddrinfo((struct addrinfo *)s_addrinfo_result);BRBRnbsp; nbsp; return(1);BRBR}BRBRint main(int s_argc, char **s_argv)BR{BRnbsp; nbsp; int s_count = 4;BRnbsp; nbsp; BRnbsp; nbsp; (void)fprintf(stdout, mzping v0.0.2 - Code by JaeHyuk Cho lt;minzkn@minzkn.comgt;\n);BRBRnbsp; nbsp; if(s_argc lt;= 1) {BRnbsp; nbsp; nbsp; nbsp; (void)fprintf(stdout, usage: %s lt;hostgt; lt;countgt;\n, (char *)s_argv[0]);BRnbsp; nbsp; nbsp; nbsp; BRnbsp; nbsp; nbsp; nbsp; /* (void)mzping(localhost, s_count); */BRBRnbsp; nbsp; nbsp; nbsp; return(EXIT_SUCCESS);BRnbsp; nbsp; }BRBRnbsp; nbsp; if(s_argc gt;= 3) {BRnbsp; nbsp; nbsp; nbsp; if(sscanf(s_argv[2], %i, amp;s_count) != 1) {BRnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; perror(count);BRnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; return(EXIT_FAILURE);BRnbsp; nbsp; nbsp; nbsp; }BRnbsp; nbsp; }BRBRnbsp; nbsp; (void)setuid(getuid());BRnbsp; nbsp; (void)mzping(s_argv[1], s_count);BRBRnbsp; nbsp; return(EXIT_SUCCESS);BR}BRBR/* vim: set expandtab: */BR/* End of source *//DIVBRBR DIV class=codetitleBCode:/B/DIV DIV class=codecontent# Copyright (C) Information Equipment co.,LTDBR# All rights reserved.BR# Code by JaeHyuk Cho lt;mailto:minzkn@infoeq.comgt;BRBRCROSS_COMPILEnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; ?=#BRBRCCnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp;:=$(CROSS_COMPILE)gcc#BRLDnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp;:=$(CROSS_COMPILE)ld#BRRMnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp;:=rm -f#BRSTRIPnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; :=$(CROSS_COMPILE)strip#BRBRTHIS_NAMEnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; :=mzping#BRBRCFLAGSnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp;:=-Os -pipe -Wall -Werror -ansi -fomit-frame-pointer -fPIC -I.#BR#CFLAGSnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp;:=-Os -pipe -Wall -Werror -fomit-frame-pointer -fPIC -I.#BRBRLDFLAGSnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; :=-s#BRSTRIPFLAGSnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp;:=--remove-section=.comment --remove-section=.note#BRBRTARGET_binnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp;:=$(THIS_NAME)#BRTARGETnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp;:=$(TARGET_bin)#BRBROBJECTS_binnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; := mzping.o#BROBJECTSnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; := $(OBJECTS_bin)#BRBRDEPENDnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp;:= Makefile#BRBR.PHONY: all cleanBRBRall: $(TARGET)BRclean: ; $(RM) *.o $(TARGET)BRBR$(TARGET_bin): $(OBJECTS_bin)BRnbsp; nbsp; nbsp; nbsp; $(CC) $(LDFLAGS) -o $(@) $(^)BRnbsp; nbsp; nbsp; nbsp; $(STRIP) $(STRIPFLAGS) $(@)BR$(OBJECTS): $(DEPEND)BRBR%.o: %.c ; $(CC) $(CFLAGS) -c -o $(@) $(lt;)BRBR# End of Makefile/DIV/DIV
크리에이티브 커먼즈 라이센스
Creative Commons License
2008/09/09 15:31 2008/09/09 15:31
받은 트랙백이 없고, 댓글 3개가 달렸습니다.

댓글+트랙백 RSS :: http://blog.minzkn.com/rss/response/290

댓글+트랙백 ATOM :: http://blog.minzkn.com/atom/response/290

트랙백 주소 :: http://blog.minzkn.com/trackback/290

트랙백 RSS :: http://blog.minzkn.com/rss/trackback/290

트랙백 ATOM :: http://blog.minzkn.com/atom/trackback/290

댓글을 달아 주세요

댓글 RSS 주소 : http://blog.minzkn.com/rss/comment/290
댓글 ATOM 주소 : http://blog.minzkn.com/atom/comment/290
  1. wsong 2008/10/07 23:47  댓글주소  수정/삭제  댓글쓰기

    함수의 return을 전부 static으로 쓰셨는데요.
    static을 안써도 되는거 같은데..
    혹시 특별한 이유가 있나요?

  2. minzkn 2008/10/08 09:18  댓글주소  수정/삭제  댓글쓰기

    return값이 static이라기보다는 함수가 static(유효범위한정 심볼)이라는거죠.

    외부에 불필요하게 심볼이 노출될 필요가 없도록 static으로 한정시킨겁니다.
    물론 단순하게 생각한다면 static은 선택사항입니다. 필수는 아닙니다.

    주요 목적은 외부에서 함수심볼이 보이지 않게 하여 외부 다른 프로그램에서 이와 동일한 함수 심볼을 사용할수 있도록 name space를 관리한다는 의미에서 static을 사용한겁니다.

    요런 작은 예제까지 static을 사용할 필요는 없습니다만 적어도 저는 이러한 간단한 예제코드가 커다란 모듈에 융합될것을 고려하면서 예제를 짜는것뿐입니다. 그 이상도 그 이하도 아닙니다. 개발자마다 코딩습성이라는것이 있는데 저는 요런스타일이구나라고만 생각하시면 될듯 하네요.

    리눅스 커널소스도 보시면 아시겠지만 간단한 모듈들도 내부 함수는 static을 사용하는것을 볼수 있습니다. 그와 비슷한 이치로 사용하는것 뿐입니다.
    많은 사람들이 함께 만드는 목적물로 탄생하기 위해서는 외부에서 사용하지 않는 심볼은 static으로 제한을 걸어둠으로써 제 3자가 그 심볼명을 사용할수 있다는 취지입니다.