libpcap 를 사용 하여 네트워크 메 시 지 를 분석 합 니 다.

최근 tcpdump 에서 잡 은 메 시 지 를 분석 하려 고 합 니 다. 시작 할 때 wireshark 명령 행 도구 인 tshark 로 분석 결 과 를 텍스트 파일 로 저장 한 다음 정규 표현 식 으로 필요 한 필드 와 일치 시 키 는 것 이 좋 습 니 다. 프로 토 콜 을 분석 하지 않 고 필요 한 필드 만 캡 처 하면 됩 니 다. 단점 은 상당히 느 립 니 다.330 M 의 tcpdump 파일 은 tshark 처 리 를 거 쳐 5G + 의 텍스트 파일 을 얻 고 이 5G + 텍스트 에서 문자열 을 일치 시 켜 야 합 니 다.
그래서 한 층 내 려 가 보 니 wireshark 와 tcpdump 는 모두 같은 라 이브 러 리 인 libpcap 를 사용 하여 스냅 백 작업 을 하 는 것 을 발견 하 였 습 니 다.스냅 백 에 필요 한 libpcap 함수 가 많 지 않 고 주로 프로 토 콜 부분 을 분석 하 는 것 이 귀 찮 습 니 다.인터넷 에서 libpcap 자 료 를 찾 았 습 니 다. 여기 서 정리 하 겠 습 니 다.
프로필 (참고 자료 [1])
libpcap 는 C 언어 라 이브 러 리 입 니 다. libpcap 의 영어 뜻 은 Packet Capture library 입 니 다. 즉, 패 킷 캡 처 함수 라 이브 러 리 입 니 다. 그 기능 은 네트워크 카드 를 통 해 네트워크 이 더 넷 의 패 킷 을 캡 처 하 는 것 입 니 다.이 라 이브 러 리 는 서로 다른 플랫폼 에 일치 하 는 c 함수 프로 그래 밍 인 터 페 이 스 를 제공 합 니 다. libpcap 가 설 치 된 플랫폼 에서 libpcap 를 인터페이스 로 쓴 프로그램, 응용 프로그램 으로 자 유 롭 게 플랫폼 을 넘 어 사용 할 수 있 습 니 다.그것 은 여러 가지 운영 체 제 를 지원 한다.libpcap 구조 가 간단 하고 사용 이 편리 합 니 다.이것 은 20 여 개의 api 패 키 징 함 수 를 제공 합 니 다. 우 리 는 이러한 api 함 수 를 이용 하여 본 네트워크 탐측 기 에 필요 한 네트워크 패 킷 감청 기능 을 완성 할 수 있 습 니 다.
첫 번 째 pcap 프로그램:
#include <stdio.h>
#include <pcap.h>
 
int main()
{
   pcap_t* pd;
   char ebuf[PCAP_ERRBUF_SIZE], *dev;
   const u_char* pkt;
   struct pcap_pkthdr ph;
 
   dev = pcap_lookupdev(ebuf);
   if (!dev) {
      fprintf(stderr, "%s
", ebuf); return -1; } printf("get net device -> %s
", dev); pd = pcap_open_live(dev, 65535, 0, 0, ebuf); if (!pd) { fprintf(stderr, "%s
", ebuf); return -1; } pkt = pcap_next(pd, &ph); printf("A packet is captured.
"); pcap_close(pd); return 0;

libpcap 함 수 를 사용 하면 헤더 파일 pcap. h 를 포함 하고 컴 파일 할 때 링크 옵션 - lpcap 을 추가 합 니 다.함수.
char *pcap_lookupdev(char *errbuf);

현재 기기 에서 사용 할 수 있 는 네트워크 인터페이스 이름 을 가 져 오 는 데 사용 되 며, 찾 으 면 이름 을 되 돌려 주 고, 찾 지 못 하면 NULL 을 되 돌려 줍 니 다. 실패 원인 은 errbuf 에 저 장 됩 니 다.errbuf 의 길 이 는 적어도 PCAPERRBUF_SIZE。이 함 수 는 이 더 넷 카드 만 찾 는 것 같 습 니 다. 제 기계 에 있 는 무선 랜 카드 도 열거 하지 않 았 습 니 다. 이 더 넷 카드 가 여러 개 있 으 면 어떻게 될 지 모 르 겠 습 니 다.
장 비 를 찾 으 면 감청 할 수 있 습 니 다.함수.
pcap_t *pcap_open_live(const char *device, int snaplen,
      int promisc, int to_ms, char *errbuf);

대 pcaplookupdev () 에서 찾 은 장 치 를 감청 합 니 다.매개 변수 device 는 사용 가능 한 장치 이름 입 니 다.snaplen 은 메시지 캡 처 의 최대 길 이 를 지정 합 니 다.promisc 는 네트워크 카드 가 혼합 모드 에 있 는 지, 0 은 비 혼합 모드 이 고 1 은 혼합 모드 입 니 다.to_ms 는 캡 처 시간 을 설정 합 니 다. 이 시간 대 에 패 킷 이 없 으 면 시간 을 초과 하여 돌아 갑 니 다. 있 으 면 이 시간 대 에 캡 처 된 모든 패 킷 을 되 돌려 줍 니 다. 이 매개 변수 가 0 이면 데이터 가 오지 않 으 면 차단 모드 에 있 고 요구 에 부 합 된 패 킷 을 받 을 때 까지 설명 합 니 다.errbuf 는 오류 정 보 를 저장 하 는 데 사 용 됩 니 다.
tcpdump 나 wireshark 에 저 장 된 데이터 파일 을 열 려 면 함 수 를 사용 할 수 있 습 니 다.
pcap_t *pcap_open_offline(const char *fname, char *errbuf);

이 중 fname 은 열 파일 입 니 다. errbuf 는 오류 가 발생 했 을 때의 정 보 를 저장 하 는 데 사 용 됩 니 다.
다음은 메 시 지 를 캡 처 합 니 다.함수.
const u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h);

두 개의 인자 수신: 첫 번 째 는 pcap 사용open_live () 또는 pcapopen_오프라인 () 에서 얻 은 pcapt 포인터, 두 번 째 매개 변 수 는 pcap 가 캡 처 한 모든 가방 에 추가 한 정보 입 니 다.일반적으로 pcap 에서 캡 처 한 패 킷 형식 은 아래 와 같 습 니 다.
+---------------------+-------------------+-----+
| struct ether_header | ip/arp/... header | ... |
+---------------------+-------------------+-----+

pcap_next () 는 pcap 에 추 가 된 정 보 를 매개 변수 h 가 가리 키 는 구조 체 에 채 우 고 실제 패 킷 을 가리 키 는 지침 (즉, struct ether header 의 시작 위치) 을 되 돌려 줍 니 다.함수 의 반환 시간 은 pcap 에 달 려 있 습 니 다.open_live 속 의 toms 매개 변수 값 은 파일 을 직접 열 때 차단 할 필요 가 없습니다.
pcapnext () 가 돌아 와 서 정 보 를 인쇄 합 니 다. "A packet is captured." (pcap open live () 에 시간 초과 가 0 으로 설정 되 어 있 기 때 문 입 니 다. 즉, pcap next () 는 패 킷 이 도착 할 때 까지 계속 막 힙 니 다.)
분석 완료 후 함수 사용
void pcap_close(pcap_t *p);

자원 을 방출 하 다.
다른 pcap 프로그램:
#include <stdio.h>
#include <pcap.h>
 
static void printer(u_char* arg, const struct pcap_pkthdr* ph,
      const u_char* packet)
{
   printf("A packet is captured.
"); } int main() { pcap_t* pd; char ebuf[PCAP_ERRBUF_SIZE], *dev; dev = pcap_lookupdev(ebuf); if (!dev) { fprintf(stderr, "%s
", ebuf); return -1; } printf("get net device -> %s
", dev); pd = pcap_open_live(dev, 65535, 0, 0, ebuf); if (!pd) { fprintf(stderr, "%s
", ebuf); return -1; } pcap_dispatch(pd, 0, printer, NULL); pcap_close(pd); return 0;

 
앞에서 장 치 를 여 는 부분 은 첫 번 째 프로그램 과 같 습 니 다. 캡 처 한 부분 은 다른 함 수 를 사 용 했 습 니 다.
int pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user);

pcap_dispatch () 는 cnct 패 킷 을 읽 거나 시간 을 초과 하거나 파일 이나 버퍼 의 끝 에 읽 을 때 까지 되 돌려 줍 니 다.cnct 가 - 1 또는 0 이면 읽 기 시간 이 초과 되 거나 끝 날 때 까지 모든 패 킷 을 읽 는 것 을 표시 합 니 다.매개 변수 user 는 사용자 정의 매개 변수 로 리 셋 함수 에 전달 합 니 다.패 킷 을 캡 처 할 때마다 리 셋 함수 콜 백 을 호출 합 니 다. 그 중 pcaphandler 의 정 의 는 다음 과 같 습 니 다.
typedef void (*pcap_handler)(u_char *user, const struct pcap_pkthdr *h,
      const u_char *bytes);
첫 번 째 매개 변 수 는 user 가 pcap 에 전달 하 는 것 입 니 다.dispatch () 의 마지막 인자;두 번 째 매개 변 수 는 pcap 패 킷 의 시작 위 치 를 가리 키 는 struct pcap 입 니 다.pktdr 의 포인터 (앞의 그림 참조), bytes (또는 packet 이 실제 에 부합 한다 고 함) 는 실제 네트워크 메시지 의 시작 위치 (앞의 그림 에서 struct ether header 의 위치) 를 가리 키 며, 그 중에서 전체 메시지 의 길이 (bytes 가 가리 키 는 위치 에서 전체 메시지 의 끝 까지) 는 struct pcappkthdr 의 caplen 지정.struct pcap_pkthdr 의 정의:
struct pcap_pkthdr {
   struct timeval ts;      /* time stamp */
   bpf_u_int32 caplen;     /* length of portion present */
   bpf_u_int32 len;        /* length this packet (off wire) */
};

첫 번 째 매개 변수 ts 는 메 시 지 를 캡 처 하 는 시간 입 니 다. 세 번 째 매개 변수 len 은 알 수 없 지만 실제 출력 으로 볼 때 caplen 의 값 과 같 습 니 다.
실제 출력 을 보면 메시지 가 포 착 될 때마다 리 셋 함수 printer () 인쇄 메 시 지 를 호출 합 니 다.
그리고 하나 와 pcapdispatch () 기능 이 비슷 한 함수
int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user);

이 함 수 는 읽 기 시간 이 초과 되 었 을 때 돌아 오지 않 습 니 다. cnct 패 킷 을 캡 처 하거나 읽 기 오류 가 발생 했 을 때 만 돌아 갑 니 다.
또한 함수 pcap 사용 가능dump_open(),pcap_dump () 와 pcapdump_close () 메 시 지 를 파일 에 저장 합 니 다.tcpdump 와 wireshark 에 저 장 된 메시지 형식 은 모두 pcap 형식 을 따 르 기 때문에 상대방 의 데이터 파일 을 열 수 있 습 니 다. 그러나 pcap 함수 로 저 장 된 파일 은 파일 시작 에 pcap 정 보 를 추가 합 니 다. 이 파일 은 tcpdump 나 wireshark 로 직접 열 수 없습니다. 시작 하 는 pcap 내용 을 삭제 해 야 합 니 다.
자, 현재 사용 하고 있 는 함 수 는 주로 이것들 입 니 다. 더 많은 함 수 는 [1] 과 pcap. h 의 내용 을 참고 할 수 있 습 니 다.
참고 자료
[1] libpcap 함수 라 이브 러 리 [2] 스 니퍼 의 원시 트 래 픽 가이드 (libpcap 튜 토리 얼)
 
전환 하 다http://ouonline.net/libpcap-1

좋은 웹페이지 즐겨찾기