[완료]raw socket 관련문제입니다,,

revol2236의 이미지

며칠 전부터 raw socket에서 ping을 구현하고 있는 한 학생입니다,,

그런데 ping 에는 s 옵션이 있어서 보낼 ping size를 정해서 보낼수있더군요,,;;

일단 저도 그것을 구현하기 위해서 ip_off멤버에 손을 대서 어떻게 어떻게 MF 플래그를 포함하여 offset정도는 맞출수 있게 되었습니다,,

그런데 wireshark로 패킷을 검사하면 이상하게 ping request 항목은 사라지고 모두 ip fragmentation 으로 인식되던군요.

4일째 밤마다 구글링을 하고 찾아도 구현 방법은 않나오더라고요..

어떻게 설정 혹은 구현을 해야 icmp+ip 헤더에 나머지 ip fragmentation이 딸려가게 할수 있나요??

/*
제가 생각한 방법은 buffer에는 ip+icmp 헤더를 넣어서 전송하고 그전에 nbuffer에 ip헤더(fragmentaion)을 
전송하는 방법입니다. 코드에 나왔있지만 offset은 제대로 맞춘상태고 wireshark로 보았을때 의도한대로
나오네요. 그냥 buffer와 nbuffer는 배열로 선언했습니다,, request도 가지 않는 상황이기에 recvfrom 은 구현해 놓지 않았습니다 
제 허접한 코드입니다*/
 
 
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <errno.h>
#include <unistd.h>
#include <netinet/ip_icmp.h>
unsigned short in_cksum(unsigned short *,int len);
int main(int argc,char **argv){
if(argc!=3){
printf("USAGE %s [dest IP] [source ip]\n",argv[0]);
exit(1);
}
 
	int nsock,clnt_size,size;
	int on=1,i=0,len;
	char buffer[1480];
        struct ip *iphdr;
	struct in_addr ex_addr;
        struct icmp *icmp;
        struct sockaddr_in serv_sock;
	char nbuffer[1480];
 
nsock=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);
if(nsock<0){
printf("socket connect error\n");
exit(1);
}
 
setsockopt(nsock, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(on) );
 
bzero(&serv_sock,sizeof(serv_sock)); 
serv_sock.sin_family=AF_INET; 
serv_sock.sin_addr.s_addr=inet_addr(argv[1]); 
 
//nbuffer 시작
memset(nbuffer,0x0,1480);
iphdr=(struct ip*)(nbuffer);
iphdr->ip_v=4; 
iphdr->ip_hl=5; 
iphdr->ip_p=IPPROTO_ICMP;//IPPROTO_TCP; 
iphdr->ip_len=htons(1480); 
iphdr->ip_id=20; 
iphdr->ip_ttl=125; 
iphdr->ip_off=htons(IP_MF);
iphdr->ip_sum=0;
iphdr->ip_tos=0x000;
ex_addr.s_addr=inet_addr(argv[2]);
iphdr->ip_src=ex_addr; 
ex_addr.s_addr=inet_addr(argv[1]);
iphdr->ip_dst=ex_addr; 
iphdr->ip_sum=in_cksum((unsigned short *)iphdr,sizeof(struct iphdr)); //ip header end 
//nbuffer 끝
 
//buffer 시작
iphdr=(struct ip*)(buffer);
iphdr->ip_v=4; 
iphdr->ip_hl=5; 
iphdr->ip_p=IPPROTO_ICMP;//IPPROTO_TCP; 
iphdr->ip_len=htons(1480); 
iphdr->ip_id=20; 
iphdr->ip_ttl=125;
iphdr->ip_off=htons(185);
iphdr->ip_sum=0;
iphdr->ip_tos=0x000;
ex_addr.s_addr=inet_addr(argv[2]);
iphdr->ip_src=ex_addr; 
ex_addr.s_addr=inet_addr(argv[1]);
iphdr->ip_dst=ex_addr; 
iphdr->ip_sum=in_cksum((unsigned short *)iphdr,sizeof(struct iphdr)); //ip header end 
 
icmp=(struct icmp*)(buffer+sizeof(struct ip)); 
icmp->icmp_type=ICMP_ECHO;//ICMP_UNREACH; 
icmp->icmp_code=0; 
icmp->icmp_cksum=0; 
icmp->icmp_seq=15; 
icmp->icmp_id=20;   
icmp->icmp_cksum=in_cksum((unsigned short*)icmp,900); 
//buffer 끝
sendto(nsock,nbuffer,sizeof(nbuffer),0x0,(struct sockaddr*)&serv_sock,sizeof(serv_sock));
sendto(nsock,buffer,sizeof(buffer),0x0,(struct sockaddr*)&serv_sock,sizeof(serv_sock));
}
 
unsigned short in_cksum(unsigned short *addr,int len)
{
    register int sum = 0;
    u_short answer = 0;
    register u_short *w = addr;
    register int nleft = len;
 
    /*
    * Our algorithm is simple, using a 32 bit accumulator (sum), we add
    * sequential 16 bit words to it, and at the end, fold back all the
    * carry bits from the top 16 bits into the lower 16 bits.
    */
    while(nleft > 1)  {
        sum += *w++;
        nleft -= 2;
    }
 
    /* mop up an odd byte, if necessary */
    if(nleft == 1) {
        *(u_char *)(&answer) = *(u_char *)w ;
        sum += answer;
    }
 
    /* add back carry outs from top 16 bits to low 16 bits */
    sum = (sum >> 16) + (sum & 0xffff);     /* add hi 16 to low 16 */
    sum += (sum >> 16);                     /* add carry */
    answer = ~sum;                          /* truncate to 16 bits */
    return(answer);
}
dreamkey의 이미지

socket() 세번째 파라미터 값에 IPPROTO_ICMP 대신 IPPROTO_RAW 또는 255로 설정해 보세요.

그래야만 IP헤더부터 윗단에 패킷을 넣으실 수 있을겁니다.

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.