[완료] libipq를 이용한 패킷 캡쳐 질문입니다.
글쓴이: yungyung / 작성시간: 일, 2007/02/25 - 7:10오후
안녕하세요. libipq를 이용하여 패킷 캡쳐를 하다가 의문나는 점이 있어서 글을 올리게 되었습니다.
# iptables -t mangle -A INPUT -p tcp -j QUEUE --dport 80
위와 같이 iptable을 설정하고 구글에서 검색하여 찾은 코드를 살짝 바꿔 아래(메인 함수)와 같이 작성하였습니다.
int main(int argc, char **argv)
{
int status;
unsigned char dump_payload = 0;
unsigned char inbuf[BUFSIZE];
struct ipq_handle *h;
int verdict = NF_ACCEPT;
h = ipq_create_handle(0, PF_INET);
if (!h) die(h);
status = ipq_set_mode(h, IPQ_COPY_PACKET, BUFSIZE);
if (status < 0) die(h);
do {
status = ipq_read(h, inbuf, BUFSIZE, 0);
if (status < 0) die(h);
switch (ipq_message_type(inbuf)) {
case NLMSG_ERROR:
fprintf(stderr, "Received error message %d\n", ipq_get_msgerr(inbuf));
break;
case IPQM_PACKET: {
unsigned char *packet = NULL;
unsigned char *tcppacket = NULL;
struct iphdr *iph = NULL;
struct tcphdr *tcph = NULL;
char *httpData = NULL;
struct iphdr *ip = NULL;
struct tcphdr *tcp = NULL;
char *http = NULL;
ipq_packet_msg_t *m = ipq_get_packet(inbuf);
if (!m) break;
if (m->data_len >= sizeof(struct iphdr)) {
packet = (unsigned char *)m + sizeof(*m);
}
fprintf(stderr, "Sending verdict %d on packet %lX\n", verdict, m->packet_id);
iph = (struct iphdr *)packet;
tcppacket = (unsigned char *)iph + sizeof(struct iphdr);
tcph = (struct tcphdr *)tcppacket;
httpData = (char *)tcph + sizeof(struct tcphdr);
ip = (struct iphdr *)malloc(sizeof(struct iphdr));
tcp = (struct tcphdr *)malloc(sizeof(struct tcphdr));
http = (char *)malloc(strlen(httpData));
if (ip == NULL || tcp == NULL || http == NULL){
fprintf(stderr, "out of memory\n");
exit(0);
}
memcpy(ip, iph, sizeof(struct iphdr));
memcpy(tcp, tcph, sizeof(struct tcphdr));
memcpy(http, httpData, strlen(httpData));
dump_iphdr((char *)ip);
fprintf(stderr, "httpData :%s\n", http);
free(ip);
free(tcp);
free(http);
status = ipq_set_verdict(h, m->packet_id, verdict, m->data_len, packet);
if (status < 0) die(h);
break;
}
default:
fprintf(stderr, "Unknown message!\n");
break;
}
if (dump_payload) write(1, inbuf, status);
} while (1);
ipq_destroy_handle(h);
return 0;
}컴파일해서 실행시켰는데 같은 패킷이 여러번(3번 이상) 출력되는 것을 확인했습니다.
코드에 문제가 있는건지 아님 다른 문제인지 아시는 분, 답변 부탁드립니다.
Forums:


...
mangling 부분 체크 해보시길..
pcap계열만 해봐서 정확한 답변을 드리긴 힘든데..
tcp쪽 fragment flag확인 해보시고 그게 아니면
layer-1 에서의 mangling 일수도 있으니 재구성을 해주셔야 할겁니다.
정확한 답변이 아니니 확인해보시고 ^^;; 혹시 답을 찾으시면 알려주세요^^;;
해결했습니다.^^
혹시나 해서 ethereal로 패킷을 캡쳐해서 하나하나 비교해봤습니다.
알고보니 SYN, ACK, FIN 패킷이었습니다.-_-;;
메모리를 동적 할당해서 http 헤더 정보를 출력시키고 free를 해줬는데 그것이 쓰레기 값으로 남아서 다음 패킷을 출력할 때 출력되더군요.;;
if (tcp-<ack == 1 && tcp-<psh == 1) fprintf(stderr, "httpData :\n\n%s\n", http);
우선 위처럼 고쳐서 http 헤더가 든 패킷만 http 헤더 데이터를 출력시키게끔 수정하였습니다.:D
참고로..
libpcap 쓰시면 tcpdump 필터룰을 오픈당시에 적용가능합니다^^;;
참고 하세요..
댓글 달기