-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
158 lines (136 loc) · 4.2 KB
/
main.cpp
File metadata and controls
158 lines (136 loc) · 4.2 KB
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
#include <sys/time.h>
#include <netinet/in.h>
#include <net/ethernet.h>
#include <pcap/pcap.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <netinet/ip_icmp.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/ether.h>
#define PROMISCUOUS 1
#define NONPROMISCUOUS 0
// IP 헤더 구조체
struct ip *iph;
// TCP 헤더 구조체
struct tcphdr *tcph;
char compileoption[10]="";
int count=1;
// 패킷을 받아들일경우 이 함수를 호출한다.
// packet 가 받아들인 패킷이다.
void callbacka(u_char *useless, const struct pcap_pkthdr *pkthdr,
const u_char *packet)
{
static int count = 1;
struct ether_header *ep;
unsigned short ether_type;
int chcnt =0;
int length=pkthdr->len;
// 이더넷 헤더를 가져온다.
ep = (struct ether_header *)packet;
// IP 헤더를 가져오기 위해서
// 이더넷 헤더 크기만큼 offset 한다.
packet += sizeof(struct ether_header);
// 프로토콜 타입을 알아낸다.
ether_type = ntohs(ep->ether_type);
// 만약 IP 패킷이라면
if (ether_type == ETHERTYPE_IP)
{
// IP 헤더에서 데이타 정보를 출력한다.
iph = (struct ip *)packet;
printf("Packet Count: %d\n",count++);
printf("Version : %d\n", iph->ip_v);
printf("Header Len : %d\n", iph->ip_hl);
printf("Ident : %d\n", ntohs(iph->ip_id));
printf("TTL : %d\n", iph->ip_ttl);
printf("Src Address : %s\n", inet_ntoa(iph->ip_src));
printf("Dst Address : %s\n", inet_ntoa(iph->ip_dst));
printf("Dst Mac : %s\n", ether_ntoa ( (struct ether_addr *) ep->ether_dhost));
printf("Src Mac : %s\n", ether_ntoa ( (struct ether_addr *) ep->ether_shost));
// 만약 TCP 데이타 라면
// TCP 정보를 출력한다.
if (iph->ip_p == IPPROTO_TCP)
{
tcph = (struct tcphdr *)(packet + iph->ip_hl * 4);
printf("Src Port : %d\n" , ntohs(tcph->source));
printf("Dst Port : %d\n" , ntohs(tcph->dest));
}
}
// IP 패킷이 아니라면
else
{
printf("NONE IP 패킷\n");
}
printf("\n\n");
}
int main(int argc, char **argv)
{
char *dev;
char *net;
char *mask;
bpf_u_int32 netp;
bpf_u_int32 maskp;
char errbuf[PCAP_ERRBUF_SIZE];
int ret;
struct pcap_pkthdr hdr;
struct in_addr net_addr, mask_addr;
struct ether_header *eptr;
const u_char *packet;
struct bpf_program fp;
pcap_t *pcd; // packet capture descriptor
// 사용중인 디바이스 이름을 얻어온다.
dev = pcap_lookupdev(errbuf);
if (dev == NULL)
{
printf("%s\n", errbuf);
exit(1);
}
printf("DEV : %s\n", dev);
// 디바이스 이름에 대한 네트웍/마스크 정보를 얻어온다.
ret = pcap_lookupnet(dev, &netp, &maskp, errbuf);
if (ret == -1)
{
printf("%s\n", errbuf);
exit(1);
}
// 네트웍/마스트 정보를 점박이 3형제 스타일로 변경한다.
net_addr.s_addr = netp;
net = inet_ntoa(net_addr);
printf("NET : %s\n", net);
mask_addr.s_addr = maskp;
mask = inet_ntoa(mask_addr);
printf("MSK : %s\n", mask);
printf("=======================\n");
// 디바이스 dev 에 대한 packet capture
// descriptor 를얻어온다.
pcd = pcap_open_live(dev, BUFSIZ, NONPROMISCUOUS, -1, errbuf);
if (pcd == NULL)
{
printf("%s\n", errbuf);
exit(1);
}
// 컴파일 옵션을 준다.
if (pcap_compile(pcd, &fp, compileoption, 0, netp) == -1)
{
printf("compile error\n");
exit(1);
}
// 컴파일 옵션대로 패킷필터 룰을 세팅한다.
if (pcap_setfilter(pcd, &fp) == -1)
{
printf("setfilter error\n");
exit(0);
}
// 지정된 횟수만큼 패킷캡쳐를 한다.
// pcap_setfilter 을 통과한 패킷이 들어올경우
// callback 함수를 호출하도록 한다.
pcap_loop(pcd, 0, callbacka, NULL);
}