span class=postbody완전한 ping 은 아닙니다. 정말로 최소구현입니다.
br /
br /
이것은 sid 가 걸려있거나 root 유저에서 실행가능합니다. 이유는 RAW socket 이기 때문입니다.
br /
br /
/spantable align=center border=0 cellpadding=3 cellspacing=1 width=90%tbodytr tdspan class=genmedb코드:/b/span/td /tr tr td class=code/*
br /
Copyright (c) Information Equipment co.,LTD.
br /
Code by JaeHyuk Cho lt;mailto:minzkn@infoeq.co.krgt;
br /
br /
- Simple is best !nbsp; nbsp;(Sequence number check ping)
br /
br /
Bugreport : To JaeHyuk Cho
br /
*/
br /
br /
#include lt;stdio.hgt;
br /
#include lt;string.hgt;
br /
#include lt;sys/types.hgt;
br /
#include lt;sys/param.hgt;
br /
#include lt;sys/time.hgt;
br /
#include lt;sys/socket.hgt;
br /
#include lt;netinet/in.hgt;
br /
#include lt;netinet/ip.hgt;
br /
#include lt;netinet/ip_icmp.hgt;
br /
#include lt;arpa/inet.hgt;
br /
#include lt;netdb.hgt;
br /
#include lt;unistd.hgt;
br /
br /
static int __MZ_ICMP_CheckSum__(void *s_Buffer, int s_Size)
br /
{
br /
int s_Return = 0;
br /
if(s_Size amp; 1)s_Return += (int)((*(unsigned char *)s_Buffer)++);
br /
s_Size gt;gt;= 1;
br /
while(s_Size-- gt; 0)s_Return += (int)(*(((unsigned short *)s_Buffer)++));
br /
if(s_Size == 1)s_Return += (int)(*(unsigned char *)(s_Buffer));
br /
s_Returnnbsp; = (s_Return gt;gt; 16) + (s_Return amp; 0xFFFF);
br /
s_Return += (s_Return gt;gt; 16);
br /
return((~s_Return) amp; 0xffff);
br /
}
br /
br /
int CORE_Ping(const char *s_HostName, unsigned int s_Index, unsigned int s_TimeOut)
br /
{
br /
intnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp;s_Return = (-1), s_Socket, s_SendBytes, s_RecvBytes, s_IsSelect;
br /
struct protoentnbsp; nbsp; *s_ProtoEntry;
br /
struct hostentnbsp; nbsp; nbsp;*s_HostEntry;
br /
struct sockaddr_innbsp; s_PingAddress, s_FromAddress;
br /
socklen_tnbsp; nbsp; nbsp; nbsp; nbsp; nbsp;s_FromAddressLength;
br /
struct icmpnbsp; nbsp; nbsp; nbsp; *s_ICMP;
br /
struct iphdrnbsp; nbsp; nbsp; nbsp;*s_IPHeader;
br /
unsigned charnbsp; nbsp; nbsp; nbsp;s_ICMP_Packet[ 60 + 76 + 56 ]; /* Packet assembly */
br /
fd_setnbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; s_FD;
br /
struct timevalnbsp; nbsp; nbsp; s_TimeVal;
br /
s_HostEntry = gethostbyname(s_HostName);
br /
if(s_HostEntry)
br /
{
br /
nbsp; memset((void *)(amp;s_PingAddress), 0, sizeof(s_PingAddress));
br /
nbsp; s_PingAddress.sin_family = AF_INET;
br /
nbsp; memcpy((void *)(amp;s_PingAddress.sin_addr), s_HostEntry-gt;h_addr, sizeof(s_PingAddress.sin_addr));
br /
nbsp; memset((void *)(amp;s_ICMP_Packet[0]), 0, sizeof(s_ICMP_Packet));
br /
nbsp; s_ICMP = (struct icmp *)(amp;s_ICMP_Packet[0]);
br /
nbsp; s_ICMP-gt;icmp_typenbsp; = ICMP_ECHO;
br /
nbsp; s_ICMP-gt;icmp_seqnbsp; nbsp;= s_Index;
br /
nbsp; s_ICMP-gt;icmp_idnbsp; nbsp; = getpid() amp; 0xffff;
br /
nbsp; gettimeofday((struct timeval *)(amp;s_ICMP_Packet[8]), (void *)0);
br /
nbsp; s_ICMP-gt;icmp_cksum = __MZ_ICMP_CheckSum__((void *)(amp;s_ICMP_Packet[0]), sizeof(s_ICMP_Packet));
br /
nbsp; s_ProtoEntry = getprotobyname(icmp);
br /
nbsp; s_Socket = socket(AF_INET, SOCK_RAW, s_ProtoEntry ? s_ProtoEntry-gt;p_proto : 1);
br /
nbsp; setuid(getuid()); /* Who are you ? */
br /
nbsp; if(s_Socket gt;= 0)
br /
nbsp; {
br /
nbsp; nbsp;s_SendBytes = sendto(s_Socket, (void *)(amp;s_ICMP_Packet[0]), sizeof(s_ICMP_Packet),
br /
nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; MSG_NOSIGNAL, /* Ignore broken pipe */
br /
nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; (struct sockaddr *)(amp;s_PingAddress), sizeof(s_PingAddress));
br /
nbsp; nbsp;if(s_SendBytes == sizeof(s_ICMP_Packet))
br /
nbsp; nbsp;{
br /
nbsp; nbsp; memset((void *)(amp;s_FromAddress), 0, sizeof(s_FromAddress));
br /
nbsp; nbsp; s_FromAddressLength = sizeof(s_FromAddress);
br /
nbsp; nbsp; memset((void *)(amp;s_ICMP_Packet[0]), 0, sizeof(s_ICMP_Packet));
br /
nbsp; nbsp; s_TimeVal.tv_sec = s_TimeOut, s_TimeVal.tv_usec = 0;
br /
nbsp; nbsp; FD_ZERO(amp;s_FD); FD_SET(s_Socket, amp;s_FD);
br /
nbsp; nbsp; s_IsSelect = select(s_Socket + 1, amp;s_FD, (fd_set *)0, (fd_set *)0, amp;s_TimeVal);
br /
nbsp; nbsp; if(s_IsSelect gt; 0 amp;amp; FD_ISSET(s_Socket, amp;s_FD) != 0)
br /
nbsp; nbsp; {
br /
nbsp; nbsp; nbsp;s_RecvBytes = recvfrom(s_Socket, (void *)(amp;s_ICMP_Packet[0]), sizeof(s_ICMP_Packet),
br /
nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp;MSG_NOSIGNAL, /* Ignore broken pipe */
br /
nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp;(struct sockaddr *)(amp;s_FromAddress), (socklen_t *)(amp;s_FromAddressLength));
br /
nbsp; nbsp; }
br /
nbsp; nbsp; else s_RecvBytes = 0;
br /
nbsp; nbsp; if(s_RecvBytes gt;= 76)
br /
nbsp; nbsp; {
br /
nbsp; nbsp; nbsp;s_IPHeader = (struct iphdr *)(amp;s_ICMP_Packet[0]);
br /
nbsp; nbsp; nbsp;s_ICMP = (struct icmp *)(amp;s_ICMP_Packet[ s_IPHeader-gt;ihl lt;lt; 2 ]);
br /
nbsp; nbsp; nbsp;if(s_ICMP-gt;icmp_type == ICMP_ECHOREPLY)
br /
nbsp; nbsp; nbsp;{
br /
nbsp; nbsp; nbsp; /* TODO:
br /
nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; Packet check sum need
br /
nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; Time compute
br /
nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; Duplicate packet check
br /
nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; nbsp; Send packet amp; Recv packet -gt; Two thread or alarm
br /
nbsp; nbsp; nbsp; */
br /
nbsp; nbsp; nbsp; s_Return = (int)s_ICMP-gt;icmp_seq;
br /
nbsp; nbsp; nbsp;}
br /
nbsp; nbsp; }
br /
nbsp; nbsp;}
br /
nbsp; nbsp;close(s_Socket);
br /
nbsp; }
br /
}
br /
return(s_Return);
br /
}
br /
br /
int main(int s_Argc, char *s_Argv[])
br /
{
br /
int s_Return, s_Check, s_Index, s_ErrorCount, s_IsError, s_Count;
br /
fprintf(stdout, MZ_Ping v0.0.1 - Code by JaeHyuk Cho lt;minzkn@infoeq.co.krgt;\n\n);
br /
if(s_Argc gt; 1)
br /
{
br /
nbsp; s_ErrorCount = 0, s_Index = 1;
br /
nbsp; if(s_Argc gt; 2)sscanf(s_Argv[2], %i, amp;s_Count);
br /
nbsp; else s_Count = 8;
br /
nbsp; do
br /
nbsp; {
br /
nbsp; nbsp;s_Check = CORE_Ping(s_Argv[1], s_Index /* Request sequence number */, 4u /* Timeout 4 second */);
br /
nbsp; nbsp;if(s_Check != s_Index)s_ErrorCount++, s_IsError = 1;
br /
nbsp; nbsp;else s_IsError = 0;
br /
nbsp; nbsp;fprintf(stdout, Ping[%s]: %s (Seq %d-gt;%d) - ERR=%d\n,
br /
nbsp; nbsp; nbsp; nbsp; nbsp; nbsp;s_Argv[1], s_IsError == 0 ? OK : LOSS, s_Index, s_Check, s_ErrorCount);
br /
nbsp; nbsp;usleep(10000);
br /
nbsp; }while(s_Index++ lt; s_Count);
br /
nbsp; fprintf(stdout, Total %d%% loss.\n, s_ErrorCount * 100 / s_Index);
br /
nbsp; s_Return = s_ErrorCount;
br /
}
br /
else
br /
{
br /
nbsp; fprintf(stdout, usage: ping lt;hostgt; lt;countgt;\n);
br /
nbsp; s_Return = 0;
br /
}
br /
return(s_Return);
br /
}
br /
br /
/* End of source *//td/tr/tbody/table
받은 트랙백이 없고,
댓글 2개가 달렸습니다.

글
댓글을 달아 주세요
댓글 RSS 주소 : http://blog.minzkn.com/rss/comment/106댓글 ATOM 주소 : http://blog.minzkn.com/atom/comment/106
유용한 소스 잘 참조했습니다.
그런데 Ping 손실률 구하는 라인의 코딩이 조금 잘못 된 것 같습니다.
fprintf(stdout, Total %d%% loss.\n, s_ErrorCount * 100 / s_Index);
:s_Index를 s_Count로 바꿔야 맞을 것 같네요.
잘 썻음니다..