-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpcap-test.c
171 lines (122 loc) · 4.07 KB
/
pcap-test.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#include <pcap.h>
#include <stdbool.h>
#include <stdio.h>
#include <libnet.h>
#include <stdint.h>
#include <stddef.h>
#include <stdio.h>
//#include <iostream>
//#include <bits/in.h>
// #include "./libnet/include/libnet/libnet-headers.h"
// #define ETHER_ADDR_LEN 6
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[]) {
if (argc != 2) {
usage();
return false;
}
param->dev_ = argv[1];
return true;
}
int main(int argc, char* argv[]) {
if(argc != 2)
{
usage();
return -1;
} // 인자 잘못 입력시
if (!parse(¶m, argc, argv))
return -1;
char errbuf[PCAP_ERRBUF_SIZE]; // error buffer
// 위 함수는 실제 기기를 열어주는 기능
// pcap_open_live(device, snaplen, PROMISCUOUS, 1000, ebuf);
// snaplen : 패킷당 저장할 바이스 수, PROMISUOUS : ( 1 ) 모든 패킷을 받겠다는 의미
pcap_t* pcap = pcap_open_live(param.dev_, BUFSIZ, 1, 1000, errbuf);
if (pcap == NULL) {
fprintf(stderr, "pcap_open_live(%s) return null - %s\n\n", param.dev_, errbuf);
return -1;
}
while (true) {
struct pcap_pkthdr* header;
struct libnet_ethernet_hdr *ethernet;
struct libnet_ipv4_hdr *ipv4;
struct libnet_tcp_hdr * tcp;
const u_char* packet;
int res = pcap_next_ex(pcap, &header, &packet);
if (res == 0) continue;
if (res == PCAP_ERROR || res == PCAP_ERROR_BREAK) {
printf("pcap_next_ex return %d(%s)\n", res, pcap_geterr(pcap));
break;
} //error
//printf("%u bytes captured\n", header->caplen); // 각 패킷들은 byte 단위 .
ethernet = (struct libnet_ethernet_hdr *)packet; // packet의 주소를 libnet_ethernet_hdr의 포인터로
ipv4 = (struct libnet_ipv4_hdr*)(packet+sizeof(*ethernet)); //
tcp = (struct libnet_tcp_hdr *)(packet+sizeof(*ethernet)+sizeof(*ipv4));
// #============================== etherent ========================================
// print scr mac , dst mac
printf("<Ethernet>\n");
printf("source mac address\n");
for(int i=0; i<ETHER_ADDR_LEN; i++){
printf("%02x",ethernet->ether_shost[i]); // mac source 주소
if (i == ETHER_ADDR_LEN -1){
printf("\n");
}
}
printf("destination mac address \n");
for (int i =0; i <ETHER_ADDR_LEN; i++){
printf("%02x",ethernet->ether_dhost[i]); // mac destination 주소
if (i == ETHER_ADDR_LEN -1){
printf("\n");
}
}
//##============================ IPv4 ===================================================
// print ipv4 protocol
printf("<IPv4>\n");
u_int8_t ip_type = ipv4 -> ip_p; // TCP 버전 확인 Protocol TCP(6)
u_int8_t ip_sum = ipv4 -> ip_sum; // TCP checksum 버전 확인
/* TCP 일 때 뽑아야 하는 조건 추가 && Port 번호 추가 */
// 리틀엔디안으로 구성됨 (4byte)
printf("source ip address \n");
printf("%02x \n", ntohl(ipv4->ip_src.s_addr));
printf("destination ip address \n");
printf("%02x \n", ntohl(ipv4->ip_dst.s_addr));
// ntohs : Network to Host Short (2 byte)
if (ipv4->ip_p == 6){ // TCP packet만 가져오기 위해서
printf("<TCP>\n");
printf("source tcp port\n");
printf("%02x\n",tcp->th_sport);
printf("destination tcp port\n");
printf("%02x\n",tcp-> th_dport);
}else{
printf("UDP 입니다");
}
// ========================= Print Payload (Data) ==========================
printf("<Payload(Data)> \n");
uint8_t offset = tcp->th_off ;
// 빅엔디안으로 변환 하는 과정 추가
uint16_t offset_16 = offset << 8;
uint16_t tmp;
tmp = (offset_16 & 0xFF00) >> 8;
tmp += (offset_16 & 0x000F) <<4;
tmp += (offset_16 & 0x00F0) >> 4;
tmp = tmp * 4;
// ================================= Payload Data 출력 ============
uint8_t hsize = tmp;
if (hsize == 20){
printf("payload가 없습니다.");
}
for (uint32_t i = sizeof(*ethernet)+sizeof(*ipv4) + tmp; i < sizeof(*ethernet)+sizeof(*ipv4) + tmp + 10 && i < header->caplen; i++){
printf("0x%02x ", packet[i]);
}
printf("\n\n");
}
pcap_close(pcap);
}