Skip to content

with-developer/Packet-Capture

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

12 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Pcap test

  • ๊ฐ•์˜: S-dev ๋„คํŠธ์›Œํฌ ๋ณด์•ˆ
  • ๋งˆ๊ฐ์ผ: July 13, 2023
  • ์ƒํƒœ: ์™„๋ฃŒ
  • ์œ ํ˜•: ๊ณผ์ œ

๋ชฉ์ฐจ

๊ณผ์ œ ๋‚ด์šฉ
ใ„ด์ƒ์„ธ

๊ณผ์ œ ํ•ด๊ฒฐ ๊ณผ์ •
ใ„ด0. ์Šค์ผˆ๋ ˆํ†ค ์ฝ”๋“œ
ใ„ด1. Ethernet Header์˜ src mac / dst mac ์ถœ๋ ฅ
ใ„ด2. IP Header์˜ src ip / dst ip
ใ„ด3. TCP Header์˜ src port / dst port
ใ„ด4. Payload(Data)์˜ hexadecimal value(์ตœ๋Œ€ 10๋ฐ”์ดํŠธ๊นŒ์ง€๋งŒ)

๊ฒฐ๊ณผ

์ „์ฒด ์ฝ”๋“œ

๊ณผ์ œ ๋‚ด์šฉ

์†ก์ˆ˜์‹ ๋˜๋Š” packet์„ captureํ•˜์—ฌ ์ค‘์š” ์ •๋ณด๋ฅผ ์ถœ๋ ฅํ•˜๋Š” C/C++ ๊ธฐ๋ฐ˜ ํ”„๋กœ๊ทธ๋žจ์„ ์ž‘์„ฑํ•˜๋ผ.

1. Ethernet Header์˜ src mac / dst mac
2. IP Header์˜ src ip / dst ip
3. TCP Header์˜ src port / dst port
4. Payload(Data)์˜ hexadecimal value(์ตœ๋Œ€ 10๋ฐ”์ดํŠธ๊นŒ์ง€๋งŒ)

์ƒ์„ธ

  • TCP packet์ด ์žกํžˆ๋Š” ๊ฒฝ์šฐ "ETH + IP + TCP + DATA" ๋กœ ๊ตฌ์„ฑ์ด ๋œ๋‹ค. ์ด ๊ฒฝ์šฐ(TCP packet์ด ์žกํ˜”๋‹ค๊ณ  ํŒ๋‹จ๋˜๋Š” ๊ฒฝ์šฐ๋งŒ)์—๋งŒ 1~4์˜ ์ •๋ณด๋ฅผ ์ถœ๋ ฅํ•˜๋„๋ก ํ•œ๋‹ค(Data์˜ ํฌ๊ธฐ๊ฐ€ 0์—ฌ๋„ ์ถœ๋ ฅํ•œ๋‹ค).
  • ๊ฐ๊ฐ์˜ Header์— ์žˆ๋Š” ํŠน์ • ์ •๋ณด๋“ค(mac, ip, port)๋ฅผ ์ถœ๋ ฅํ•  ๋•Œ, ๋…ธ๋‹ค๊ฐ€(packet์˜ ์‹œ์ž‘์œ„์น˜๋กœ๋ถ€ํ„ฐ ์ผ์ผ์ด ๋ฐ”์ดํŠธ ์„ธ์–ด ๊ฐ€๋ฉฐ)๋กœ ์ถœ๋ ฅํ•ด๋„ ๋˜๋Š”๋ฐ ๋ถˆํŽธํ•จ.
  • ์ด๋Ÿด ๋•Œ ๊ฐ๊ฐ์˜ Header ์ •๋ณด๋“ค์ด structure๋กœ ์ž˜ ์„ ์–ธํ•œ ํŒŒ์ผ์ด ์žˆ์œผ๋ฉด ์ฝ”๋“œ์˜ ๊ตฌ์„ฑ์ด ํ•œ๊ฒฐ ๊ฐ„๊ฒฐํ•ด์ง„๋‹ค. ์•ž์œผ๋กœ ๊ฐ€๊ธ‰์ ์ด๋ฉด ๋„คํŠธ์›Œํฌ ๊ด€๋ จ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ํ•  ๋•Œ์—๋Š” libnet ํ˜น์€ ์ž์ฒด์ ์ธ ๊ตฌ์กฐ์ฒด๋ฅผ ์„ ์–ธํ•˜์—ฌ ์‚ฌ์šฉํ•˜๋„๋ก ํ•œ๋‹ค.
    • http://packetfactory.openwall.net/projects/libnet > Latest Stable Version: 1.1.2.1 ๋‹ค์šด๋กœ๋“œ(libnet.tar.gz) > include/libnet/libnet-headers.h
    • libnet-headers.h ์•ˆ์— ์žˆ๋Š” ๋ณธ ๊ณผ์ œ์™€ ์ง์ ‘์ ์œผ๋กœ ๊ด€๋ จ๋œ ๊ตฌ์กฐ์ฒด๋“ค :
      • struct libnet_ethernet_hdr (479 line)
      • struct libnet_ipv4_hdr (647 line)
      • struct libnet_tcp_hdr (1519 line)
  • pcap-test ์ฝ”๋“œ๋ฅผ skeleton code์œผ๋กœ ํ•˜์—ฌ ๊ณผ์ œ๋ฅผ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•˜๋ฉฐ, pcap_findalldevs, pcap_compile, pcap_setfilter, pcap_lookupdev, pcap_loop API๋Š” ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค(์ธํ„ฐ๋„ท์— ๋Œ์•„๋‹ค๋‹ˆ๋Š” ์ฝ”๋“œ์— ํฌํ•จ๋˜์–ด ์žˆ๋Š” ํ•จ์ˆ˜๋“ค์ด๋ฉฐ, ๋ณธ ํ•จ์ˆ˜๋“ค์ด ๊ณผ์ œ์˜ ์ฝ”๋“œ์— ํฌํ•จ๋˜๋Š” ๊ฒฝ์šฐ ๊ณผ์ œ๋ฅผ ๋ฒ ๋‚€ ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผํ•จ).
  • Dummy interface๋ฅผ ์ด์šฉํ•˜์—ฌ ๋””๋ฒ„๊น…์„ ์‰ฝ๊ฒŒํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ๋ฉด ๊ณผ์ œ ์ˆ˜ํ–‰์— ๋„์›€์ด ๋œ๋‹ค.

๊ณผ์ œ ํ•ด๊ฒฐ ๊ณผ์ •

0. ์Šค์ผˆ๋ ˆํ†ค ์ฝ”๋“œ

์ฝ”๋“œ์˜ ์ดํ•ด๋ฅผ ๋•๊ธฐ ์œ„ํ•ด ์ตœ๋Œ€ํ•œ ์ž์„ธํ•˜๊ฒŒ ์ฃผ์„์„ ์ž‘์„ฑํ•ด๋ดค์Šต๋‹ˆ๋‹ค.

ํ‹€๋ฆฐ ๋ถ€๋ถ„์ด ์žˆ๋‹ค๋ฉด ๋ˆ„๊ตฌ๋“  ์ง€์ ํ•ด์ฃผ์‹œ๋ฉด ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

#include <pcap.h>
#include <stdbool.h>
#include <stdio.h>

void usage() {
	printf("syntax: pcap-test <interface>\n");
	printf("sample: pcap-test wlan0\n");
}

typedef struct {
	char* dev_;
} Param;

Param param = {
	.dev_ = NULL
};

bool parse(Param* param, int argc, char* argv[]) {
/* parse()ํ•จ์ˆ˜ ์ธ์ž
1. param ๊ตฌ์กฐ์ฒด์˜ ํฌ์ธํ„ฐ 
2. argc: ์ž…๋ ฅ๋œ ์ธ์ž์˜ Count
3. argv: ์‹ค์ œ ์ž…๋ ฅ๋œ ์ธ์ž์˜ Value
*/
	if (argc != 2) {
		usage();
		return false;
		// argc๊ฐ€ 2๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด, usage() ํ•จ์ˆ˜ ํ˜ธ์ถœ ํ›„ return false
	}
	param->dev_ = argv[1];
	return true;
  // argc๊ฐ€ 2๋ผ๋ฉด param ๊ตฌ์กฐ์ฒด์˜ dev_ ๋ณ€์ˆ˜์— ์ธ์ž๊ฐ’(argv[1])์œผ๋กœ ์„ค์ • ํ›„ return true;
}

int main(int argc, char* argv[]) {
	if (!parse(&param, argc, argv))
		return -1;
// parse ํ•จ์ˆ˜ ํ˜ธ์ถœ, param ๊ตฌ์กฐ์ฒด์˜ ํฌ์ธํ„ฐ, ์ž…๋ ฅ๋œ ์ธ์ž์˜ Count, ์ž…๋ ฅ๋œ ์ธ์ž์˜ Value๋ฅผ ์ธ์ž๊ฐ’์œผ๋กœ ๋„˜๊ฒจ์คŒ
// parse() ํ•จ์ˆ˜์—์„œ argc๊ฐ€ 2๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด false๊ฐ€ ๋ฆฌํ„ด๋˜๋ฏ€๋กœ main()ํ•จ์ˆ˜์—์„œ๋„ return -1์ด ๋ฐœ์ƒํ•จ

	char errbuf[PCAP_ERRBUF_SIZE];
  // PCAP_ERRBUF_SIZE๋Š” pcap.h ํŒŒ์ผ์—์„œ 256๋ฐ”์ดํŠธ๋กœ ์ •์˜๋˜์–ด ์žˆ์Œ
  // pcap.h: https://github.com/the-tcpdump-group/libpcap/blob/master/pcap/pcap.h
	pcap_t* pcap = pcap_open_live(param.dev_, BUFSIZ, 1, 1000, errbuf);
  /*
  1. ํŒจํ‚ท ์บก์ฒ˜๋ฅผ ์œ„ํ•ด ์—ด๋ ค๋Š” ๋„คํŠธ์›Œํฌ ๋””๋ฐ”์ด์Šค์˜ ์ด๋ฆ„
  2. ํŒจํ‚ท๋‹น ์บก์ฒ˜ํ•  ์ตœ๋Œ€ ๋ฐ”์ดํŠธ ์ˆ˜๋ฅผ ์ง€์ •
     BUFSIZ๊ฐ€ ์–ด๋””์— ์ •์˜ ๋˜์–ด ์žˆ๋Š”์ง€๋Š” ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค..
  3. promiscuous mode(1) ์„ค์ •
  4. millisecond ๋‹จ์œ„๋กœ Timeout ์ง€์ • 
  5. ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ ๋ฆฌํ„ดํ•  ๋ฒ„ํผ
  */
	if (pcap == NULL) {
		fprintf(stderr, "pcap_open_live(%s) return null - %s\n", param.dev_, errbuf);
		return -1;
	}
  // pcap ๊ฒฐ๊ณผ๊ฐ€ NULL์ธ ๊ฒฝ์šฐ ํ‘œ์ค€ ์—๋Ÿฌ๋ฅผ ์žฅ์น˜๋ช…๊ณผ ์—๋Ÿฌ๋ฉ”์„ธ์ง€์™€ ํ•จ๊ป˜ ์ถœ๋ ฅ

  /* ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜์—ฌ errbuf์— ์—๋Ÿฌ ๋ฉ”์„ธ์ง€๊ฐ€ ์ €์žฅ๋˜์—ˆ์ง€๋งŒ, pcap์ด NULL์ด ์•„๋‹ˆ๋ผ๋ฉด? 
  ์ด๋ผ๋Š” ์ƒ๊ฐ์„ ์ž ๊น ํ–ˆ์—ˆ์Šต๋‹ˆ๋‹ค.
  ํ•˜์ง€๋งŒ, pcap doc์„ ํ™•์ธํ•ด๋ณด๋‹ˆ, pcap_open_live ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰์— ์‹คํŒจํ•˜๊ฒŒ ๋˜๋ฉด pcap์€ ๋ฐ˜๋“œ์‹œ
  NULL๊ฐ’์œผ๋กœ ์„ค์ •๋œ๋‹ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ถ€๋ถ„์€ ๋”์ด์ƒ ์ˆ˜์ •ํ•  ํ•„์š”๊ฐ€ ์—†์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.
  doc Link: https://www.ibm.com/docs/en/aix/7.3?topic=p-pcap-open-live-subroutine
  */

	while (true) {
		struct pcap_pkthdr* header;
    /* 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)(์‹ค์ œ ํŒจํ‚ท์˜ ์ „์ฒด ๊ธธ์ด) */
    };

    */
		const u_char* packet;
    // packet์ด๋ผ๋Š” ์ด๋ฆ„์˜ ๋ณ€์ˆ˜๊ฐ€ unsigned charํ˜• ๋ฐ์ดํ„ฐ์˜ ์ฃผ์†Œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋ฉฐ, ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†์Œ
		int res = pcap_next_ex(pcap, &header, &packet);
    /* pcap_next_ex ํ•จ์ˆ˜ ์ธ์ž
    1. pcap_open_live๋ฅผ ํ†ตํ•ด ์˜คํ”ˆ๋œ pcap
    2. header ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋Š” ๋ณ€์ˆ˜
    3. packet ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋Š” ๋ณ€์ˆ˜ 
    return: ์„ฑ๊ณต ์‹œ 1์„ ๋ฐ˜ํ™˜ํ•˜๋ฉฐ, timeout์ด ๋  ๊ฒฝ์šฐ 0์„ ๋ฐ˜ํ™˜, ์—๋Ÿฌ์‹œ -1์„ ๋ฐ˜ํ™˜, EOF์‹œ -2๋ฅผ ๋ฐ˜ํ™˜ํ•จ
    */
		if (res == 0) continue;
    // timeout์‹œ continue๋ฅผ ํ†ตํ•ด while๋ฌธ ์žฌ์ง„์ž…
		if (res == PCAP_ERROR || res == PCAP_ERROR_BREAK) {
			printf("pcap_next_ex return %d(%s)\n", res, pcap_geterr(pcap));
			break;
      /* pcap.h์—์„œ PCAP_ERROR์™€ PCAP_ERROR_BREAK๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด define ๋˜์–ด์žˆ์Œ
			#define   PCAP_ERROR       -1
			#define   PCAP_ERROR_BREAK -2
			๋”ฐ๋ผ์„œ, ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฒฝ์šฐ ํ•ด๋‹น ์—๋Ÿฌ ๋ฉ”์„ธ์ง€๋ฅผ ์ถœ๋ ฅํ•ด์ฃผ๊ณ , while๋ฌธ์—์„œ ํƒˆ์ถœ
      */
		}
		printf("%u bytes captured\n", header->caplen);
		// header ๊ตฌ์กฐ์ฒด์— ์ €์žฅ๋œ caplen(ํ•œ๋ฒˆ์— ์ฝ์–ด๋“ค์ธ ํŒจํ‚ท์˜ ๊ธธ์ด)๋ฅผ ์ถœ๋ ฅ
	}

	pcap_close(pcap);
	// open๋œ pcap์„ close์ฒ˜๋ฆฌ
}

1. Ethernet Header์˜ src mac / dst mac ์ถœ๋ ฅ

  1. ethernet_hdr ๊ตฌ์กฐ์ฒด๋ฅผ ์ •์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

    libnet-headers.h์—์„œ ethernet_hdr ๊ตฌ์กฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

    struct libnet_ethernet_hdr
    {
        u_int8_t  ether_dhost[ETHER_ADDR_LEN];/* destination ethernet address */
        u_int8_t  ether_shost[ETHER_ADDR_LEN];/* source ethernet address */
        u_int16_t ether_type;                 /* protocol */
    };
  2. MAC ์ฃผ์†Œ๋Š” 6๋ฐ”์ดํŠธ์ด๋ฏ€๋กœ #difine ETHER_ADDR_LEN 6 ๋„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

  3. packet ํฌ์ธํ„ฐ๋ฅผ Ethernet Header ๊ตฌ์กฐ์ฒด ํฌ์ธํ„ฐ๋กœ ํ˜•๋ณ€ํ™˜ ํ•ฉ๋‹ˆ๋‹ค.

    struct libnet_ethernet_hdr* eth_hdr = (struct libnet_ethernet_hdr*)packet;
    /* 
    struct libnet_ethernet_hdr* eth_hdr
    -> eth_hdr๋ผ๋Š” ์ด๋ฆ„์˜ struct libnet_ethernet_hdr ํƒ€์ž…์˜ ํฌ์ธํ„ฐ๋ฅผ ์„ ์–ธ
    
    (struct libnet_ethernet_hdr*)packet
    -> packet์ด ๊ฐ€๋ฆฌํ‚ค๋Š” ๋ฉ”๋ชจ๋ฆฌ์˜ ์‹œ์ž‘ ์œ„์น˜์—์„œ struct libnet_ethernet_hdr ๊ตฌ์กฐ์ฒด์˜ ํฌ๊ธฐ๋งŒํผ์˜ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ struct libnet_ethernet_hdr ํ˜•์‹์œผ๋กœ ํ•ด์„
    */
  4. src mac / dst mac์„ ์ถœ๋ ฅํ•ด์ฃผ๋Š” ํ•จ์ˆ˜๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

    void printMac(u_int8_t* src_mac, u_int8_t* dst_mac){
            printf("Source Mac: %02x %02x %02x %02x %02x %02x\n", src_mac[0],src_mac[1],src_mac[2],src_mac[3],src_mac[4],src_mac[5]);
            printf("Destination Mac: %02x %02x %02x %02x %02x %02x\n", dst_mac[0],dst_mac[1],dst_mac[2],dst_mac[3],dst_mac[4],dst_mac[5]);
    }
    /*
    libnet_ethernet_hdr ๊ตฌ์กฐ์ฒด์—์„œ mac์ฃผ์†Œ๋Š” `ETHER_ADDR_LEN`ํฌ๊ธฐ์˜ ๋ฐฐ์—ด๋กœ ๊ด€๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์—, 6๋ฐ”์ดํŠธ๊ฐ’์„ mac[0] ~ mac[5]๋กœ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.
    */
  5. mainํ•จ์ˆ˜์—์„œ printMac ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

    printMac(eth_hdr -> ether_shost, eth_hdr -> ether_dhost);
    //eth_hdr์˜ ether_shost, ether_dhost๋ฅผ ์ธ์ž๊ฐ’์œผ๋กœ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.
  6. Ether Type์ด IPv4๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ ๋’ท ๋‚ด์šฉ์€ ์ถœ๋ ฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

    if(ntohs(eth_hdr -> ether_type) != ETHER_TYPE_IP) continue;

2. IP Header์˜ src ip / dst ip

  1. IPv4์˜ ๊ตฌ์กฐ์ฒด๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.

    libnet-headers.h์—์„œ libnet_ipv4_hdr ๊ตฌ์กฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

    struct libnet_ipv4_hdr
    {
    #if (LIBNET_LIL_ENDIAN)
        u_int8_t ip_hl:4,      /* header length */
               ip_v:4;         /* version */
    #endif
    #if (LIBNET_BIG_ENDIAN)
        u_int8_t ip_v:4,       /* version */
               ip_hl:4;        /* header length */
    #endif
        u_int8_t ip_tos;       /* type of service */
    #ifndef IPTOS_LOWDELAY
    #define IPTOS_LOWDELAY      0x10
    #endif
    #ifndef IPTOS_THROUGHPUT
    #define IPTOS_THROUGHPUT    0x08
    #endif
    #ifndef IPTOS_RELIABILITY
    #define IPTOS_RELIABILITY   0x04
    #endif
    #ifndef IPTOS_LOWCOST
    #define IPTOS_LOWCOST       0x02
    #endif
        u_int16_t ip_len;         /* total length */
        u_int16_t ip_id;          /* identification */
        u_int16_t ip_off;
    #ifndef IP_RF
    #define IP_RF 0x8000        /* reserved fragment flag */
    #endif
    #ifndef IP_DF
    #define IP_DF 0x4000        /* dont fragment flag */
    #endif
    #ifndef IP_MF
    #define IP_MF 0x2000        /* more fragments flag */
    #endif 
    #ifndef IP_OFFMASK
    #define IP_OFFMASK 0x1fff   /* mask for fragmenting bits */
    #endif
        u_int8_t ip_ttl;          /* time to live */
        u_int8_t ip_p;            /* protocol */
        u_int16_t ip_sum;         /* checksum */
        struct in_addr ip_src, ip_dst; /* source and dest address */
    };
    
    /* ๊ตฌ์กฐ์ฒด์—์„œ ์•„๋ž˜์™€ ๊ฐ™์€ #if, #endif ๋ฌธ์ด ๋ณด์ž…๋‹ˆ๋‹ค.
    #if (LIBNET_LIL_ENDIAN)
        u_int8_t ip_hl:4,      
               ip_v:4;         
    #endif
    #if (LIBNET_BIG_ENDIAN)
        u_int8_t ip_v:4,       
               ip_hl:4;       
    #endif
    
    ๊ฒ€์ƒ‰์„ ํ•ด๋ณด๋‹ˆ, ์ด๋Š” ์กฐ๊ฑด๋ถ€ ์ปดํŒŒ์ผ ์ง€์‹œ์ž๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.
    ์ปดํŒŒ์ผ ํ™˜๊ฒฝ์ด ๋ฆฌํ‹€์•ค๋””์–ธ์ธ์ง€, ๋น…์•ค๋””์–ธ์ธ์ง€์— ๋”ฐ๋ผ ์ปดํŒŒ์ผ์„ ๋‹ค๋ฅด๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ ์ž…๋‹ˆ๋‹ค.
     
    ๋ฆฌํ‹€ ์•ค๋””์–ธ์ธ ๊ฒฝ์šฐ ํŒจํ‚ท ํ—ค๋”๋Š” ip_hl, ip_v ์ˆœ์„œ๋Œ€๋กœ ํ•ด์„ํ•ด์•ผํ•˜๋ฉฐ, ๋น…์•ค๋””์–ธ์ธ ๊ฒฝ์šฐ ip_v, ip_hl ์ˆœ์„œ๋Œ€๋กœ ํ•ด์„ํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
    ์ฝ”๋“œ๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ๋™์ž‘ํ•˜๊ฒŒ ํ•˜๋ ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค.
    1. `#difine LIBNET_LIL_ENDIAN` ๋˜๋Š” `#difine LIBNET_BIG_ENDIAN` ๋งคํฌ๋กœ๋ฅผ ์„ ์–ธ
    2. ์ปดํŒŒ์ผ์„ ํ•  ๋•Œ `-DLIBNET_LIL_ENDIAN` ๋˜๋Š” `-DLIBNET_BIG_ENDIAN` ์˜ต์…˜์„ ์ถ”๊ฐ€
    
    ์ €๋Š” 2๋ฒˆ์„ ํƒํ•˜์—ฌ makefile์„ ์ˆ˜์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.
    
    makefile code
    LDLIBS += -lpcap
    CFLAGS += -DLIBNET_LIL_ENDIAN
    
    all: pcap-test
    
    pcap-test:  pcap-test.c
    
    clean:
            rm -f pcap-test *.o
    */
  2. Ethernet ํ—ค๋” ๋‹ค์Œ์— ์˜ค๋Š” IPv4 ํ—ค๋”์— ๋Œ€ํ•œ packet ํฌ์ธํ„ฐ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

    struct libnet_ipv4_hdr* ip_hdr = (struct libnet_ipv4_hdr*)(packet + sizeof(*eth_hdr));
  3. src ip / dst ip๋ฅผ ์ถœ๋ ฅํ•ด์ฃผ๋Š” ํ•จ์ˆ˜๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

    void printIP(struct in_addr src_ip, struct in_addr dst_ip) {
        printf("Source IP: %d.%d.%d.%d\n",
               src_ip.s_addr & 0xFF,
               (src_ip.s_addr >> 8) & 0xFF,
               (src_ip.s_addr >> 16) & 0xFF,
               (src_ip.s_addr >> 24) & 0xFF);
        printf("Destination IP: %d.%d.%d.%d\n",
               dst_ip.s_addr & 0xFF,
               (dst_ip.s_addr >> 8) & 0xFF,
               (dst_ip.s_addr >> 16) & 0xFF,
               (dst_ip.s_addr >> 24) & 0xFF);
    }
  4. mainํ•จ์ˆ˜์—์„œ printIPํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

    printIP(ip_hdr -> ip_src, ip_hdr -> ip_dst);
  5. TCP ์ด์™ธ์˜ ํŒจํ‚ท์€ ์ถœ๋ ฅํ•˜์ง€ ์•Š๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

    if(ip_hdr -> ip_p != PROTOCOL_TYPE_TCP) continue;

3. TCP Header์˜ src port / dst port

  1. TCP์˜ ๊ตฌ์กฐ์ฒด๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.

    libnet-headers.h์—์„œ libnet_tcp_hdr ๊ตฌ์กฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

    struct libnet_tcp_hdr
    {
        u_int16_t th_sport;       /* source port */
        u_int16_t th_dport;       /* destination port */
        u_int32_t th_seq;          /* sequence number */
        u_int32_t th_ack;          /* acknowledgement number */
    #if (LIBNET_LIL_ENDIAN)
        u_int8_t th_x2:4,         /* (unused) */
               th_off:4;        /* data offset */
    #endif
    #if (LIBNET_BIG_ENDIAN)
        u_int8_t th_off:4,        /* data offset */
               th_x2:4;         /* (unused) */
    #endif
        u_int8_t  th_flags;       /* control flags */
    #ifndef TH_FIN
    #define TH_FIN    0x01      /* finished send data */
    #endif
    #ifndef TH_SYN
    #define TH_SYN    0x02      /* synchronize sequence numbers */
    #endif
    #ifndef TH_RST
    #define TH_RST    0x04      /* reset the connection */
    #endif
    #ifndef TH_PUSH
    #define TH_PUSH   0x08      /* push data to the app layer */
    #endif
    #ifndef TH_ACK
    #define TH_ACK    0x10      /* acknowledge */
    #endif
    #ifndef TH_URG
    #define TH_URG    0x20      /* urgent! */
    #endif
    #ifndef TH_ECE
    #define TH_ECE    0x40
    #endif
    #ifndef TH_CWR   
    #define TH_CWR    0x80
    #endif
        u_int16_t th_win;         /* window */
        u_int16_t th_sum;         /* checksum */
        u_int16_t th_urp;         /* urgent pointer */
    };
  2. IPv4 ํ—ค๋” ๋‹ค์Œ์— ์˜ค๋Š” TCP ํ—ค๋”์— ๋Œ€ํ•œ packet ํฌ์ธํ„ฐ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

    struct libnet_tcp_hdr* tcp_hdr = (struct libnet_tcp_hdr*)(packet + sizeof(*eth_hdr) + ip_hdr -> ip_hl*4);
    /*
    TCP ํ—ค๋”๋Š” ํŒจํ‚ท์˜ ์‹œ์ž‘๋ถ€ํ„ฐ ์ด๋”๋„ท ํ—ค๋”์˜ ๊ธธ์ด์™€ IP ํ—ค๋”์˜ ๊ธธ์ด๋ฅผ ๋”ํ•œ ๊ณณ์— ์œ„์น˜ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
    ๋”ฐ๋ผ์„œ, packet + sizeof(*eth_hdr) + ip_hdr -> ip_hl*4์€ tcp header์˜ ์‹œ์ž‘ ์œ„์น˜์ž…๋‹ˆ๋‹ค.
    */
  3. src port / dst port๋ฅผ ์ถœ๋ ฅํ•ด์ฃผ๋Š” ํ•จ์ˆ˜๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

    void printPORT(u_int16_t src_port, u_int16_t dst_port){
            printf("Soruce Port: %d\n", ntohs(src_port));
            printf("Destination Port: %d\n", ntohs(dst_port));
    }
  4. mainํ•จ์ˆ˜์—์„œ printPORTํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

    printPORT(tcp_hdr -> th_sport, tcp_hdr -> th_dport);

4. Payload(Data)์˜ hexadecimal value(์ตœ๋Œ€ 10๋ฐ”์ดํŠธ๊นŒ์ง€๋งŒ)

  1. TCP ํ—ค๋” ๋‹ค์Œ์— ์˜ค๋Š” Payload(Data)์— ๋Œ€ํ•œ packet ํฌ์ธํ„ฐ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

    u_char *data = (u_char *)(packet + sizeof(*eth_hdr) + ip_hdr->ip_hl * 4 + tcp_hdr->th_off * 4);
  2. Payload(Data)์˜ length๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

    int data_len = ntohs(ip_hdr->ip_len) - (ip_hdr->ip_hl * 4 + tcp_hdr->th_off * 4);
  3. Payload(Data)๋ฅผ ์ถœ๋ ฅํ•ด์ฃผ๋Š” ํ•จ์ˆ˜๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

    void printDATA(int data_len, u_char* data){
            if (data_len == 0){
                    printf("Data is Zero Bytes\n");
                    return;
            }
            printf("Data is %d Bytes\n",data_len);
            printf("Data: ");
            if(data_len < 10){
                    for(int i = 0; i <= data_len; i++){
                            printf("%02x ", data[i]);
                            }
            }
            else{
                    for(int i = 0; i <=9; i++){
                            printf("%02x ",data[i]);
                    }
            }
            printf(". . .\n");
    }
    // data_len์ด 10๋ณด๋‹ค ์ž‘์„ ๊ฒฝ์šฐ ์ „์ฒด data๋ฅผ ์ถœ๋ ฅ์‹œ์ผœ์ฃผ๋ฉฐ, data_len์ด 10 ์ด์ƒ์ผ ๊ฒฝ์šฐ, data์˜ 10๋ฐ”์ดํŠธ๋งŒ ์ถœ๋ ฅ์‹œํ‚ต๋‹ˆ๋‹ค.
  4. mainํ•จ์ˆ˜์—์„œ printDATAํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

    printDATA(data_len, data);

๊ฒฐ๊ณผ

Run Image run_image

์ „์ฒด ์ฝ”๋“œ

Read pcap-test.c

About

pcap project

Topics

Resources

Stars

Watchers

Forks

Packages

No packages published