[완료]패킷 캡쳐후 패킵 복사 문제
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAX_NUM 3
#define SNAP_LEN
#define TIMEOUT 100
#define PROMISCUOUS 1
#define NONPROMISCUOUS 0
#define PACKET_ARRAY_SIZE 10000
int pkt_cnt=0;
struct packetBox{
u_int pkt_len;
u_char *pkt;
};
struct packetBox pb[10000];
void callback(u_char *, const struct pcap_pkthdr *, const u_char *);
void packetContainer(void);
int main(){
char *dev;
char *net;
char *mask;
char errbuf[PCAP_ERRBUF_SIZE];
bpf_u_int32 netp,maskp;
//struct pcap_pkthdr hdr;
struct in_addr net_addr,mask_addr;
//struct ether_header *eptr;
//const u_char *packet;
pcap_t *pd;
pcap_if_t *tmp, *alldev;
int ret,i;
pcap_findalldevs(&alldev,errbuf);
for(tmp = alldev,i=0; tmp ; tmp=tmp->next){
printf("%d. %s",++i,tmp->name);
if(tmp->description)
printf("(%s)\n",tmp->description);
else
printf("No description\n");
}
if(!i){
printf("No Devices\n");
return -1;
}
printf("Choose one of the lists : ");
scanf("%d",&ret);
for(tmp = alldev,i=0;inext,i++);
/*
if((dev = pcap_lookupdev(errbuf)) == NULL){
printf("%s\n",errbuf);
exit(1);
}
strcpy(dev,"wlan0");
*/
dev = tmp->name;
if((ret = pcap_lookupnet(dev,&netp,&maskp,errbuf)) == -1){
printf("%s\n",errbuf);
exit(1);
}
printf("Device : %s\n",dev);
net_addr.s_addr = netp;
mask_addr.s_addr = maskp;
net = inet_ntoa(net_addr);
printf("Net : %s\n",net);
mask = inet_ntoa(mask_addr);
printf("Mask : %s\n",mask);
pd = pcap_open_live(dev,1024,PROMISCUOUS,100,errbuf);
pcap_loop(pd,MAX_NUM,callback,0);
packetContainer();
pcap_close(pd);
return 0;
}
void packetContainer(){
int len,l_cnt;
for(l_cnt=0; l_cnt < pkt_cnt;l_cnt++){
printf("l_cnt : %d\n",l_cnt);
for(len=0;len < pb[l_cnt].pkt_len ; ){
//printf("(len:%d)",len);
printf("%02x ",*(pb[l_cnt].pkt++));
if( !(++len%16))printf("\n");
}printf("\n");
}
}
void callback(u_char *usr, const struct pcap_pkthdr *h,const u_char *packet){
int len=0;
struct ether_header *ep;
u_short ether_type;
struct ip *iph;
static int cnt=0;
printf("\nPACKET NO.%d\t",++cnt);
ep = (struct ether_header *)packet;
packet += sizeof(struct ether_header);
ether_type = ntohs(ep->ether_type);
if(ether_type == ETHERTYPE_IP){
iph = (struct ip*)packet;
printf("%s ->",inet_ntoa(iph->ip_src));
printf("%s\n",inet_ntoa(iph->ip_dst));
printf("IP packet ");
if(iph->ip_p == IPPROTO_TCP){
printf("TCP\n");
}
else if(iph->ip_p == IPPROTO_UDP){
printf("UDP\n");
}
else if(iph->ip_p == IPPROTO_ICMP){
printf("IP_ICMP\n");
}
pb[pkt_cnt].pkt_len = h->len;
pb[pkt_cnt].pkt = (u_char*)malloc(sizeof(packet));
printf("size of Packet:%d\n",sizeof(packet));
//strcpy(pb[pkt_cnt].pkt,packet);
memcpy(pb[pkt_cnt].pkt,packet,strlen((char*)packet));
/* while(len < h->len){
printf("%02x ",*(pb[pkt_cnt].pkt++));
if( ++len%16 == 0 )printf("\n");
}printf("\n");*/
pkt_cnt++;
printf("pkt_cnt:%d\n",pkt_cnt);
while(len < h->len){
printf("%02x ",*(packet++));
if( (++len %16) == 0)
printf("\n");
}
printf("\n");
}
else
printf("Non IP packet\n");
}
libpcap를 이용해 패킷분석하는 프로그램을 만들어 보려고 합니다.
QT를 이용해 비쥬얼하게 하려고 하는데요.
와이어샤크나 이더리얼처럼 세개의 레이어로 나뉘어 맨 상단의 패킷 열을 클릭하면 맨 아래 레이어에 패킷 정보를 보여주려고 합니다.
callback함수는 한번 호출되서 죽기때문에 패킷정보를 저장해야될것 같아서 상단에 정말 간단한 구조체를 두고 패킷을 복사하려고 합니다.
그런데 packet 크기는 복사가 되는데 내용물은 쓸데없는 이상한값이 자꾸 들어가네요;;;
왜 그런지 아시는 분 있나요;;;;
strcpy도 해봤고 memcpy도 해봤는데 안되네요;;;;;
답변 주시면 정말 감사하겠습니다!!!!!!!!!
.
참고로 저 소스는 http://www.joinc.co.kr/modules/moniwiki/wiki.php/article/libpcap%C0%BB_%C0%CC%BF%EB%C7%D1_%C7%C1%B7%CE%B1%D7%B7%A1%B9%D6 를 비롯한 여러 예제 소스를 보고 만든 테스트 프로그램입니다. -
pb[pkt_cnt].pkt =
pb[pkt_cnt].pkt = (u_char*)malloc(sizeof(packet));
printf("size of Packet:%d\n",sizeof(packet));
여기서 패킷 사이즈가 정녕 sizeof(packet)인지 진지하게 고찰해보시기 바랍니다 '~');;
여기서 sizeof(packet)은
여기서 sizeof(packet)은 packet의 사이즈라기보다는 char형의 사이즈죠.
즉 4byte크기로 pb[pkt_cnt].pkt에 메모리를 할당해주는것이죠.
문제는 그 아래에서 수행하려고 하는 패킷의 내용복사입니다.
//strcpy(pb[pkt_cnt].pkt,packet);
memcpy(pb[pkt_cnt].pkt,packet,strlen((char*)packet));
위 두 방식을 모두 사용해보았지만 엉뚱한 패킷내용이 복사가 됩니다.
패킷 내용을 뿌려주는 다른 함수내에서 pb[pkt_cnt].pkt를 참조하여 출력하면
엉뚱한 값이 복사된것을 알 수가 있습니다.
이것에 대한 해결책은 없는건가요?
!!
00126 struct pcap_pkthdr {
00127 struct timeval ts;
00128 bpf_u_int32 caplen;
00129 bpf_u_int32 len;
00130 };
감사합니다!! ^^
처음에 무슨 말인지 몰라 헤더파일 뒤져보고, packet 길이와 사이즈 뒤져보면서 수정했습니다 ^^
님 덕분에 알아냈네요 ㅎㅎ
일단 딴걸 다 무시하고
strlen 으로 패킷의 데이터의 길이를 잴 수 있나요? 아마 헤더에 패킷길이가 따로 있을 것
같은데요. strlen 계열의 함수는 중간에 0 값이 있으면 해당 크기까지만 인식합니다.
패킷이라면 어떤 데이터가 있을지 모르는데, strlen으로 복사하는 건 위험할것 같습니다.
=========================
CharSyam ^^ --- 고운 하루
=========================
=========================
CharSyam ^^ --- 고운 하루
=========================
네
네 strlen((char*)packet) 하니 1이 나오더라고요.
정작 진짜 패킷의 길이는 h->caplen 이랑 h->len이 가지고 있는데요
메모리 할당할때 h->len 만큼 할당해주고, 복사할때 또 그만큼 하니 제대로 되네요.
감사합니다 ^^!
댓글 달기