IP header option을 사용하는 방법에 대해

hwsong의 이미지

현재 소켓을 이용해서 traceroute와 비슷한 프로그램을 코딩 중입니다.
여기서 제가 IP header option을 사용해야 하는데요,
정확한 방법을 모르겠습니다.

자료로 나와 있는 것도 없구 말이죠.
IP header option을 사용해 보신 분 계시면 답변 부탁드립니다.
물론 예제 source file이라도 있으시면... 정말 눈물겹도록 감사하겠죠...
그럼, 이만...

익명 사용자의 이미지

Seq만 검사하는 ping 만들었던거 소스 올립니다.
참고가 될지요... 참고로 RAW socket이므로 "root" 권한에서
실행되어야 함은 당연지사로 생각하시면 되고요.

이거 코드 잘못 수정하면 네트웍 이상해지는 경우도 있을수 있으니까
Local에서만 테스트해보심을 권고 합니다.

/*
 Copyright (c) Information Equipment co.,LTD.
 Code by JaeHyuk Cho <mailto:minzkn@infoeq.co.kr> 

 - Simple is best !   (Sequence number check ping)
*/

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>

static int __MZ_ICMP_CheckSum__(void *s_Buffer, int s_Size)
{
 int s_Return = 0;
 if(s_Size & 1)s_Return += (int)((*(unsigned char *)s_Buffer)++);
 s_Size >>= 1;
 while(s_Size-- > 0)s_Return += (int)(*(((unsigned short *)s_Buffer)++));
 if(s_Size == 1)s_Return += (int)(*(unsigned char *)(s_Buffer));
 s_Return  = (s_Return >> 16) + (s_Return & 0xFFFF);
 s_Return += (s_Return >> 16);
 return((~s_Return) & 0xffff);
}

int CORE_Ping(const char *s_HostName, unsigned int s_Index, unsigned int s_TimeOut)
{
 int                 s_Return = (-1), s_Socket, s_SendBytes, s_RecvBytes, s_IsSelect;
 struct protoent    *s_ProtoEntry;
 struct hostent     *s_HostEntry; 
 struct sockaddr_in  s_PingAddress, s_FromAddress;
 socklen_t           s_FromAddressLength;
 struct icmp        *s_ICMP;
 struct iphdr       *s_IPHeader;
 unsigned char       s_ICMP_Packet[ 60 + 76 + 56 ]; /* Packet assembly */
 fd_set              s_FD;
 struct timeval      s_TimeVal;
 s_HostEntry = gethostbyname(s_HostName); 
 if(s_HostEntry)
 {
  memset((void *)(&s_PingAddress), 0, sizeof(s_PingAddress));
  s_PingAddress.sin_family = AF_INET;
  memcpy((void *)(&s_PingAddress.sin_addr), s_HostEntry->h_addr, sizeof(s_PingAddress.sin_addr)); 
  memset((void *)(&s_ICMP_Packet[0]), 0, sizeof(s_ICMP_Packet));
  s_ICMP = (struct icmp *)(&s_ICMP_Packet[0]);
  s_ICMP->icmp_type  = ICMP_ECHO;
  s_ICMP->icmp_seq   = s_Index;
  s_ICMP->icmp_id    = getpid() & 0xffff;
  gettimeofday((struct timeval *)(&s_ICMP_Packet[8]), (void *)0);
  s_ICMP->icmp_cksum = __MZ_ICMP_CheckSum__((void *)(&s_ICMP_Packet[0]), sizeof(s_ICMP_Packet)); 
  s_ProtoEntry = getprotobyname("icmp");
  s_Socket = socket(AF_INET, SOCK_RAW, s_ProtoEntry ? s_ProtoEntry->p_proto : 1);
  setuid(getuid()); /* Who are you ? */
  if(s_Socket >= 0)
  {
   s_SendBytes = sendto(s_Socket, (void *)(&s_ICMP_Packet[0]), sizeof(s_ICMP_Packet), 
		        MSG_NOSIGNAL, /* Ignore broken pipe */ 
			(struct sockaddr *)(&s_PingAddress), sizeof(s_PingAddress));
   if(s_SendBytes == sizeof(s_ICMP_Packet))
   {
    memset((void *)(&s_FromAddress), 0, sizeof(s_FromAddress));	   
    s_FromAddressLength = sizeof(s_FromAddress);	   
    memset((void *)(&s_ICMP_Packet[0]), 0, sizeof(s_ICMP_Packet));
    s_TimeVal.tv_sec = s_TimeOut, s_TimeVal.tv_usec = 0;
    FD_ZERO(&s_FD); FD_SET(s_Socket, &s_FD);
    s_IsSelect = select(s_Socket + 1, &s_FD, (fd_set *)0, (fd_set *)0, &s_TimeVal);
    if(s_IsSelect > 0 && FD_ISSET(s_Socket, &s_FD) != 0)
    {
     s_RecvBytes = recvfrom(s_Socket, (void *)(&s_ICMP_Packet[0]), sizeof(s_ICMP_Packet),
		           MSG_NOSIGNAL, /* Ignore broken pipe */ 
			   (struct sockaddr *)(&s_FromAddress), (socklen_t *)(&s_FromAddressLength));
    }
    else s_RecvBytes = 0;
    if(s_RecvBytes >= 76)
    {
     s_IPHeader = (struct iphdr *)(&s_ICMP_Packet[0]); 
     s_ICMP = (struct icmp *)(&s_ICMP_Packet[ s_IPHeader->ihl << 2 ]);
     if(s_ICMP->icmp_type == ICMP_ECHOREPLY)
     {
      /* TODO:
              Packet check sum need
	      Time compute
	      Duplicate packet check
	      Send packet & Recv packet -> Two thread or alarm
      */	      
      s_Return = (int)s_ICMP->icmp_seq;
     }
    }
   }
   close(s_Socket);
  }
 }
 return(s_Return);
}

int main(int s_Argc, char *s_Argv[])
{
 int s_Return, s_Check, s_Index, s_ErrorCount, s_IsError, s_Count;
 fprintf(stdout, "MZ_Ping v0.0.1 - Code by JaeHyuk Cho <minzkn@infoeq.co.kr>\n\n");
 if(s_Argc > 1)
 {
  s_ErrorCount = 0, s_Index = 1;
  if(s_Argc > 2)sscanf(s_Argv[2], "%i", &s_Count); 
  else s_Count = 8;
  do
  {
   s_Check = CORE_Ping(s_Argv[1], s_Index /* Request sequence number */, 4u /* Timeout 4 second */);	 
   if(s_Check != s_Index)s_ErrorCount++, s_IsError = 1; 
   else s_IsError = 0; 
   fprintf(stdout, "Ping[%s]: %s (Seq %d->%d) - ERR=%d\n", 
	   s_Argv[1], s_IsError == 0 ? "OK" : "LOSS", s_Index, s_Check, s_ErrorCount);
   usleep(10000);
  }while(s_Index++ < s_Count);
  fprintf(stdout, "Total %d%% loss.\n", s_ErrorCount * 100 / s_Index);
  s_Return = s_ErrorCount;
 }
 else
 {
  fprintf(stdout, "usage: ping <host> <count>\n");
  s_Return = 0;
 } 
 return(s_Return);
}

/* End of source */

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.