IP Header 파싱하는 프로그램을 작성했는데 잘 안되네요

pefecman의 이미지

학교 과제로 아이피 헤더를 파싱해서 출력해주는 프로그램을 작성했는데

tcpdump 로 출력된 형식의 파일을 못알아먹네요

계속 아이피 헤더가 아니라는 메시지만;;

어디가 문제인지 좀 봐주시면 감사하겠습니다.

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

/*ip version4 header 구조체 - ip.h 에 정의되어있다 */

struct ip *iph;

/*ip version6 header 구조체 - ip6.h 에 정의되어있다 */

struct ip6_hdr *ip6h;

/*패킷을 받아들여서 ip header를 strip 해주는 함수*/

void strip(FILE *ifp)

{

unsigned short type;

struct ether_header *etherp;

/* etherp 포인터변수에 헤더를 저장한다 */

etherp = (struct ether_header *)ifp;

/* 이더넷 헤더 길이만큼 포인터를 이동시켜 ip 헤더를 가리키도록 한다 */

ifp += sizeof(struct ether_header);

/* 프로토콜 타입을 알아낸다 */

type = ntohs(etherp->ether_type);

/* 그리하여 만약 IPv4 패킷이라면 */

if (type == 0x0800)

{

/* IP 헤더 정보를 파싱하여 출력한다 */

iph = (struct ip *)ifp;

printf("IP version4 Packet 의 정보입니다 \n");

printf("Version : %d\n", iph->ip_v);

printf("Header Length : %d\n", iph->ip_hl);

printf("Type of Service : %d\n", iph->ip_tos);

printf("Total length of IP datagram : %d\n", iph->ip_len);

printf("Identification : %d\n", ntohs(iph->ip_id));

printf("Flags : %d\n", iph->ip_off);

printf("Time-to-Live : %d\n", iph->ip_ttl);

printf("Protocol : %d\n", iph->ip_p);

printf("Header Checksum : %d\n", iph->ip_sum);

printf("Source Ip address : %d\n", inet_ntoa(iph->ip_src)); /* 우리가 흔히 쓰는 10진수 형식의 형태로 바꿔준다 */

printf("Destination IP address : %d\n", inet_ntoa(iph->ip_dst));

}

/* 만약 IPv6 패킷이라면 */

else if (type == 0x86dd)

{

ip6h = (struct ip6_hdr *)ifp;

printf("IP version6 Packet 의 정보입니다 \n");

printf("Version & Traffic Class : %d\n", ip6h->ip6_vfc);

printf("Flow Label : %d\n", ip6h->ip6_flow);

printf("Payload Length : %d\n", ip6h->ip6_plen);

printf("Next Header : %d\n", ip6h->ip6_nxt);

printf("Hop Limit : %d\n", ntohs(ip6h->ip6_hlim));

printf("Source Ip address : %d\n", inet_ntoa(ip6h->ip6_src)); /* 우리가 흔히 쓰는 10진수 형식의 형태로 바꿔준다 */

printf("Destination IP address : %d\n", inet_ntoa(ip6h->ip6_dst));

}

else

printf("This is not IP Packet \n");

}

int main(int argc, char **argv)

{

FILE *ifp;

if (argc != 2) /*인자수가 2개가 아닐 경우 에러메시지 출력 후 종료*/

{

printf("오픈할 파일을 하나만 지정해주십시오 \n");
exit(1);

}

ifp = fopen(argv[1], "r"); /* 두번째 인자에서 지정한 파일이름을 오픈한다. 단 바이너리 모드로 연다. */

strip(ifp); /* 불러들인 파일을 strip 함수로 넘겨주어 parsing한다 */

fclose(ifp);

return 0;

}

tcpdump 로 캡쳐된 파일도 첨부했어요 ^^;; 확장자를 .bin 으로 바꿔서 보시면 될듯..

아래는 실행결과입니다.

pefecman@Choi:~/Desktop$ ./example comnet_hw.bin
This is not IP Packet

하지만 tcpdump 로 읽었을 땐 아이피 패킷이 맞는거 같은데 ;;

제대한지 얼마 안되서 그런지 프로그래밍에 관한 지식이 백지장이 되어버렸어요 ㅠㅠ

File attachments: 
첨부파일 크기
Plain text icon comnet_hw.txt261.92 KB
Plain text icon example.c.txt2.92 KB
hie의 이미지

먼저 올려주신 데이터 및 소스코드를 통해 확인할 수 있는
환경이 되지 못하여 말로만 적는 점 양해 바랍니다.

훌륭한 코드를 작성하는 것 만큼 중요한 것이 또한 디버깅이라
생각됩니다. 이러한 관점에서 본다면

else
printf("This is not IP Packet \n");

상기 코드는 디버깅에 큰 도움이 되질 못합니다. 왜냐하면 현상만
알려줄뿐 그 원인이 없기 때문입니다. IP Packet이 아니라고
판단했으면 그 값을 출력하도록 하는 것이 더 좋을 듯 합니다.

또한 패킷 전체 혹은 일부분을 덤프하여, 본인이 코딩할때 예상한 것과
동일한 내용인지 확인해 보는 것 또한 좋은 방법일 것입니다.

추후 이러한 것들이 모두 확인 된 후에 TCPDUMP의 소스코드와 본인이
작성한 코드를 비교해, 본인이 미처 생각하지 못했던 부분을 발견하고
보완한다면 금상첨화라 하겠습니다.

명쾌한 답변은 없구, 사족만 많았네요... ㅡ.ㅡ;;

prether의 이미지

Ethernet header는 14 바이트입니다.

그런데 4-byte alignment로 인해 sizeof(struct ether_header)==16으로
계산될 수 있습니다. 그래서 IP header의 시작점 계산을 위한 offset더하기가
+14가 아닌 +16으로 해서 계산이 제대로 안된 거 같네요.

제 추측이지만요~

/***************************************
Being the one is just like being in love.
***************************************/

grassman의 이미지

fopen() 한 뒤에 나온 FILE * 포인터는 그 자체만으로 파일의 내용을 갖고 있지 않습니다. 파일을 읽으려면 보통 다음의 수순을 밟습니다. (아주 무식한 방법이므로 작은 파일에만 사용하시기 바랍니다.)

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
 
void foo(FILE *fp)
{
  char *buffer;
  long size;
 
  fseek(fp, 0, SEEK_END);
  size = ftell(fp);
  fseek(fp, 0, SEEK_SET);
 
  buffer = (char *)malloc(size);
  if( !buffer )
    return; /* 메모리 할당 오류 */
 
  fread(buffer, 1, size, fp);
 
  /* buffer에는 읽어들인 파일의 내용이 있음 */
  /* 여기에서는 FILE *로 타입 캐스팅을 함 (함수 선언 참조) */
  strip((FILE *)buffer);
 
  free(buffer);
}

cppig1995의 이미지

윗분 말씀처럼 이 내용(및 ifp를 타입변환해서 iph, ip6h에 할당하는 두부분)이 잘못되었군요:

/*패킷을 받아들여서 ip header를 strip 해주는 함수*/
 
void strip(FILE *ifp)
 
{
 
unsigned short type;
 
struct ether_header *etherp;
 
/* etherp 포인터변수에 헤더를 저장한다 */
 
etherp = (struct ether_header *)ifp;

그러니까 ifp는 파일의 정보만 담고 있고, 내용을 읽으려면 따로 해야 합니다.

Real programmers /* don't */ comment their code.
If it was hard to write, it should be /* hard to */ read.

dasomoli의 이미지

혹시 성대세요?;
---------------------------------------------------------
*경고* 아바타 따라하지 마세요!!
dasomoli = DasomOLI = Dasom + DOLI = 다솜돌이
다솜 = 사랑하옴의 옛 고어.
Developer! ubuntu-ko! 다솜돌이 정석



dasomoli의 블로그(http://dasomoli.org)
dasomoli = DasomOLI = Dasom + DOLI = 다솜돌이
다솜 = 사랑하옴의 옛 고어.
Developer! ubuntu-ko! 다솜돌이 정석
pefecman1의 이미지

일러주신대로 해보고 안되면 또 배워가야겠네요 ㅎㅎ

감사합니다~

Dasomoli//맞습니다;;

컴퓨터 네트워크 들으시는 분이신가보네요 ㅎㅎㅎ

안녕하세요?의 이미지

저도 이거 숙제하고 있는데,

pcap lib의 함수를 사용하지 않고 패킷의 내용을 읽어오는 방법을 모르겠습니다.

혹시 해결하셨으면 방법좀 알려주셨으면 안될까요?

제 email은 bigwill@skku.edu입니다.

댓글 달기

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