-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFinalProjectServerListener.c
233 lines (191 loc) · 6.36 KB
/
FinalProjectServerListener.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
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
//Arun Donti Enhanced Client
//This code has been adapted from :
//http://www.tcpdump.org/sniffex.c
// to compile
//gcc FinalProjectServerListener.c -o test -lm -lpcap
#define SIZE_ETHERNET 14
// lifetime in seconds for hop count
#define HOPLIFETIME 5
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <math.h>
#include <pcap.h>
#include <sys/time.h>
// IP header
struct sniff_ip {
u_char ip_vhl; // version << 4 | header length >> 2
u_char ip_tos; // type of service
u_short ip_len; // total length
u_short ip_id; // identification
u_short ip_off; // fragment offset field
#define IP_RF 0x8000 // reserved fragment flag
#define IP_DF 0x4000 // dont fragment flag
#define IP_MF 0x2000 // more fragments flag
#define IP_OFFMASK 0x1fff // mask for fragmenting bits
u_char ip_ttl; // time to live
u_char ip_p; // protocol
u_short ip_sum; // checksum
struct in_addr ip_src,ip_dst; // source and dest address
};
// Struct of hops + IP, might be more complicated than FILE I/O
/*
struct IPhop{
inet_ntoa addr;
int hops;
*IPhop next;
};
typedef struct IPhop IPhop;
*/
void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet);
void DieWithUserMessage(const char *msg, const char *detail) {
fputs(msg, stderr);
fputs(": ", stderr);
fputs(detail, stderr);
fputc('\n', stderr);
exit(1);
}
void DieWithSystemMessage(const char *msg) {
perror(msg);
exit(1);
}
//Creating a stream socket using TCP
int sock;
// to get time to reset file
struct timeval initial;
int main(int argc, char *argv[]) {
pcap_t *handle; // Session handle
char *dev; // The device to sniff on
char errbuf[PCAP_ERRBUF_SIZE]; // Error string
struct bpf_program fp; //The compiled filter
char filter_exp[] = "dst 192.168.1.101"; // The filter expression
bpf_u_int32 mask; // Our netmask
bpf_u_int32 net; // Our IP
struct pcap_pkthdr header; // The header that pcap gives us
const u_char *packet; // The actual packet
//private ip for NAT
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
char* natIP = "192.168.1.1";
// Establish connection with NAT
// Constructing the server address struct
struct sockaddr_in servAddr; // server address memset(&servAddr, 0, sizeof(servAddr)); // Zero out structure
servAddr.sin_family = AF_INET;// IPv4 address family
// Convert address
int rtnVal = inet_pton(AF_INET, natIP, &servAddr.sin_addr.s_addr);
if (rtnVal == 0){
DieWithUserMessage("inet_pton() failed", "invalid address string");
}
else if (rtnVal < 0){
DieWithSystemMessage("inet_pton() failed");
}
in_port_t servPort = atoi(argv[1]);
servAddr.sin_port = htons(servPort); //Local port
// Establish the connection to the NAT
if (connect(sock, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0)
DieWithSystemMessage("connect() failed");
// libpcap stuff
dev = pcap_lookupdev(errbuf);
if (dev == NULL) {
fprintf(stderr, "Couldn't find default device: %s\n", errbuf);
return(2);
}
/* Find the properties for the device */
if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) {
fprintf(stderr, "Couldn't get netmask for device %s: %s\n", dev, errbuf);
net = 0;
mask = 0;
}
/* Open the session in promiscuous mode */
handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf);
if (handle == NULL) {
fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf);
return(2);
}
// Compile and apply the filter
if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) {
fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(handle));
return(2);
}
if (pcap_setfilter(handle, &fp) == -1) {
fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(handle));
return(2);
}
// Grab a packet until error occurs //
// get starting time stamp
gettimeofday(&initial, NULL);
packet = pcap_loop(handle,-1,got_packet,NULL);
pcap_close(handle);
}
//Maurizio, should add code in here
void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet){
FILE *fp;
char buff[50];
struct timeval now;
gettimeofday(&now, NULL);
// find lifetime of file hopcount file
double elapsed = (now.tv_sec - initial.tv_sec) + ((now.tv_usec - initial.tv_usec)/1000000.0);
// start file from scratch if timeout and reset initial time
if (elapsed >= HOPLIFETIME){
fp = fopen("hopsByIP.txt","w");
gettimeofday(&initial, NULL);
printf("creating new file");
}
else{
fp = fopen("hopsByIP.txt","a+");
}
static int count = 1; // packet counter
static struct timeval tv1;
const struct sniff_ip *ip; // The IP header
printf("\nPacket number %d:\n", count);
count++;
ip = (struct sniff_ip*)(packet + SIZE_ETHERNET);
// the file already contains this IP
int getHops = NULL;
while(fgets(buff, sizeof(buff), fp) != NULL){
if(strstr(buff,inet_ntoa(ip->ip_src))){
fgets(buff, sizeof(buff), fp);
getHops = atoi(buff);
printf("%d hops listed in list\n ",getHops);
break;
}
}
if(getHops != NULL){
// let through if reasonably close hop count
int hopEQ = ceil((double)getHops *.05) + 1;
printf("hopEQ is %d\n", hopEQ);
printf("ttl on incomming packet is %d\n", (int)(ip->ip_ttl));
if ((int)(ip->ip_ttl) <= getHops + hopEQ && (int)(ip->ip_ttl) >= getHops - hopEQ){
//printf("ttl difference is okay for %s\n",inet_ntoa(ip->ip_src));
}
// blacklist this ip , add SERVER NAT communication for blacklist
else{
printf("BLACKLIST %s\n",inet_ntoa(ip->ip_src));
char banCommand[25];
memset(banCommand,'\0',25);
strcat(banCommand,"BAN;");
strcat(banCommand, inet_ntoa(ip->ip_src));
ssize_t banLength = strlen(banCommand);
// Send the string to the server
ssize_t numBytes = send(sock, banCommand, banLength, 0);
if (numBytes < 0){
DieWithSystemMessage("send() failed");
}
else if (numBytes != banLength){
DieWithUserMessage("send()", "sent unexpected number of bytes");
}
}
}
// print source IP and the TTL if it hasn't connected before'
else{
fprintf(fp,"\n%s \n%d", inet_ntoa(ip->ip_src), (ip->ip_ttl));
}
// Maurizio, everything is okay so send okay stuff to client
fclose(fp);
return;
}