[완료] 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 필터룰을 오픈당시에 적용가능합니다^^;;
참고 하세요..
댓글 달기