pcap 예제 돌렸는데 eth0 장치가 잡히지 않네요.
글쓴이: tkfkdgody / 작성시간: 금, 2009/02/06 - 1:58오후
안녕하세요.
pcap joinc에서 소스 찾아 한번 돌려봤는데 에러가 나네요. 테스트 환경은 수세 10.1 x86_64 입니다.
glibc 2.4대이며, 커널은 2.6.16입니다.
테스트 소스는 아래와 같습니다.
// 사용중인 디바이스 이름을 얻어온다.
dev = pcap_lookupdev(errbuf);
if (dev == NULL)
{
printf("%s\n", errbuf);
exit(1);
}
위 부분에서 디폴트로 eth0만 검사하는거 같은데 제 테스트 피시는 이더넷카드(eth1)를 따로 하나 꼽아서 쓰거든요.
이걸 연결되어 있는 eth1 부분으로 변경되어지게 할려면 어떻게 해야할지요..
조언 좀 부탁드립니다.
감사합니다.
#include <sys/time.h>
#include <netinet/in.h>
#include <net/ethernet.h>
#include <pcap/pcap.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <netinet/ip_icmp.h>
#define PROMISCUOUS 1
#define NONPROMISCUOUS 0
// IP 헤더 구조체
struct ip *iph;
// TCP 헤더 구조체
struct tcphdr *tcph;
// 패킷을 받아들일경우 이 함수를 호출한다.
// packet 가 받아들인 패킷이다.
void callback(u_char *useless, const struct pcap_pkthdr *pkthdr,
const u_char *packet)
{
static int count = 1;
struct ether_header *ep;
unsigned short ether_type;
int chcnt =0;
int length=pkthdr->len;
// 이더넷 헤더를 가져온다.
ep = (struct ether_header *)packet;
// IP 헤더를 가져오기 위해서
// 이더넷 헤더 크기만큼 offset 한다.
packet += sizeof(struct ether_header);
// 프로토콜 타입을 알아낸다.
ether_type = ntohs(ep->ether_type);
// 만약 IP 패킷이라면
if (ether_type == ETHERTYPE_IP)
{
// IP 헤더에서 데이타 정보를 출력한다.
iph = (struct ip *)packet;
printf("IP 패킷\n");
printf("Version : %d\n", iph->ip_v);
printf("Header Len : %d\n", iph->ip_hl);
printf("Ident : %d\n", ntohs(iph->ip_id));
printf("TTL : %d\n", iph->ip_ttl);
printf("Src Address : %s\n", inet_ntoa(iph->ip_src));
printf("Dst Address : %s\n", inet_ntoa(iph->ip_dst));
// 만약 TCP 데이타 라면
// TCP 정보를 출력한다.
if (iph->ip_p == IPPROTO_TCP)
{
tcph = (struct tcp *)(packet + iph->ip_hl * 4);
printf("Src Port : %d\n" , ntohs(tcph->source));
printf("Dst Port : %d\n" , ntohs(tcph->dest));
}
// Packet 데이타 를 출력한다.
// IP 헤더 부터 출력한다.
while(length--)
{
printf("%02x", *(packet++));
if ((++chcnt % 16) == 0)
printf("\n");
}
}
// IP 패킷이 아니라면
else
{
printf("NONE IP 패킷\n");
}
printf("\n\n");
}
int main(int argc, char **argv)
{
char *dev;
char *net;
char *mask;
bpf_u_int32 netp;
bpf_u_int32 maskp;
char errbuf[PCAP_ERRBUF_SIZE];
int ret;
struct pcap_pkthdr hdr;
struct in_addr net_addr, mask_addr;
struct ether_header *eptr;
const u_char *packet;
struct bpf_program fp;
pcap_t *pcd; // packet capture descriptor
// 사용중인 디바이스 이름을 얻어온다.
dev = pcap_lookupdev(errbuf);
if (dev == NULL)
{
printf("%s\n", errbuf);
exit(1);
}
printf("DEV : %s\n", dev);
// 디바이스 이름에 대한 네트웍/마스크 정보를 얻어온다.
ret = pcap_lookupnet(dev, &netp, &maskp, errbuf);
if (ret == -1)
{
printf("%s\n", errbuf);
exit(1);
}
// 네트웍/마스트 정보를 점박이 3형제 스타일로 변경한다.
net_addr.s_addr = netp;
net = inet_ntoa(net_addr);
printf("NET : %s\n", net);
mask_addr.s_addr = maskp;
mask = inet_ntoa(mask_addr);
printf("MSK : %s\n", mask);
printf("=======================\n");
// 디바이스 dev 에 대한 packet capture
// descriptor 를얻어온다.
pcd = pcap_open_live(dev, BUFSIZ, NONPROMISCUOUS, -1, errbuf);
if (pcd == NULL)
{
printf("%s\n", errbuf);
exit(1);
}
// 컴파일 옵션을 준다.
if (pcap_compile(pcd, &fp, argv[2], 0, netp) == -1)
{
printf("compile error\n");
exit(1);
}
// 컴파일 옵션대로 패킷필터 룰을 세팅한다.
if (pcap_setfilter(pcd, &fp) == -1)
{
printf("setfilter error\n");
exit(0);
}
// 지정된 횟수만큼 패킷캡쳐를 한다.
// pcap_setfilter 을 통과한 패킷이 들어올경우
// callback 함수를 호출하도록 한다.
pcap_loop(pcd, atoi(argv[1]), callback, NULL);
}
컴파일 방법은 아래와 같다. [root@localhost pcap_test]# gcc -o pcap_test pcap_test.c -lpcap -I/usr/include/pcap
다음은 필자의 Linux 박스에서 테스트한 결과이다. [root@localhost pcap_test]# ./pcap_test -1 "port 80"
DEV : eth0
NET : 192.168.100.0
MSK : 255.255.255.0
=======================
IP 패킷
Version : 4
Header Len : 5
Ident : 51804
TTL : 64
Src Address : 192.168.100.130
Dst Address : 218.234.19.87
Src Port : 4996
Dst Port : 80
45000034ca5c400040065cfbc0a86482
daea1357138400502e7a303b2e7cc456
801021f0badb00000101080a0014e136
22631d7b485454502f312e3120323030
204f
IP 패킷
Version : 4
Header Len : 5
Ident : 41787
TTL : 54
Src Address : 218.234.19.87
Dst Address : 192.168.100.130
Src Port : 80
Dst Port : 4996Forums:


댓글 달기