IP Header 파싱하는 프로그램을 작성했는데 잘 안되네요
학교 과제로 아이피 헤더를 파싱해서 출력해주는 프로그램을 작성했는데
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 로 읽었을 땐 아이피 패킷이 맞는거 같은데 ;;
제대한지 얼마 안되서 그런지 프로그래밍에 관한 지식이 백지장이 되어버렸어요 ㅠㅠ
첨부 | 파일 크기 |
---|---|
comnet_hw.txt | 261.92 KB |
example.c.txt | 2.92 KB |
먼저 올려주신
먼저 올려주신 데이터 및 소스코드를 통해 확인할 수 있는
환경이 되지 못하여 말로만 적는 점 양해 바랍니다.
훌륭한 코드를 작성하는 것 만큼 중요한 것이 또한 디버깅이라
생각됩니다. 이러한 관점에서 본다면
상기 코드는 디버깅에 큰 도움이 되질 못합니다. 왜냐하면 현상만
알려줄뿐 그 원인이 없기 때문입니다. IP Packet이 아니라고
판단했으면 그 값을 출력하도록 하는 것이 더 좋을 듯 합니다.
또한 패킷 전체 혹은 일부분을 덤프하여, 본인이 코딩할때 예상한 것과
동일한 내용인지 확인해 보는 것 또한 좋은 방법일 것입니다.
추후 이러한 것들이 모두 확인 된 후에 TCPDUMP의 소스코드와 본인이
작성한 코드를 비교해, 본인이 미처 생각하지 못했던 부분을 발견하고
보완한다면 금상첨화라 하겠습니다.
명쾌한 답변은 없구, 사족만 많았네요... ㅡ.ㅡ;;
sizeof(struct ether_header)값이 14 인지 확인
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.
***************************************/
fopen() 한 뒤에 나온
fopen() 한 뒤에 나온 FILE * 포인터는 그 자체만으로 파일의 내용을 갖고 있지 않습니다. 파일을 읽으려면 보통 다음의 수순을 밟습니다. (아주 무식한 방법이므로 작은 파일에만 사용하시기 바랍니다.)
윗분 말씀처럼 이
윗분 말씀처럼 이 내용(및 ifp를 타입변환해서 iph, ip6h에 할당하는 두부분)이 잘못되었군요:
그러니까 ifp는 파일의 정보만 담고 있고, 내용을 읽으려면 따로 해야 합니다.
Real programmers /* don't */ comment their code.
If it was hard to write, it should be /* hard to */ read.
혹시
혹시 성대세요?;
---------------------------------------------------------
*경고* 아바타 따라하지 마세요!!
dasomoli = DasomOLI = Dasom + DOLI = 다솜돌이
다솜 = 사랑하옴의 옛 고어.
Developer! ubuntu-ko! 다솜돌이 정석
dasomoli의 블로그(http://dasomoli.org)
dasomoli = DasomOLI = Dasom + DOLI = 다솜돌이
다솜 = 사랑하옴의 옛 고어.
Developer! ubuntu-ko! 다솜돌이 정석
아ㅡ답변 감사드립니다.
일러주신대로 해보고 안되면 또 배워가야겠네요 ㅎㅎ
감사합니다~
Dasomoli//맞습니다;;
컴퓨터 네트워크 들으시는 분이신가보네요 ㅎㅎㅎ
이거 혹시 해결하셨나요?
저도 이거 숙제하고 있는데,
pcap lib의 함수를 사용하지 않고 패킷의 내용을 읽어오는 방법을 모르겠습니다.
혹시 해결하셨으면 방법좀 알려주셨으면 안될까요?
제 email은 bigwill@skku.edu입니다.
댓글 달기