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
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
| #include <stdio.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <linux/types.h>
typedef unsigned int bpf_u_int32;
typedef unsigned short u_short;
typedef int bpf_int32;
typedef struct pcap_file_header {
bpf_u_int32 magic;
u_short version_major;
u_short version_minor;
bpf_int32 thiszone;
bpf_u_int32 sigfigs;
bpf_u_int32 snaplen;
bpf_u_int32 linktype;
}pcap_file_header;
typedef struct timestamp{
bpf_u_int32 timestamp_s;
bpf_u_int32 timestamp_ms;
}timestamp;
typedef struct pcap_header{
timestamp ts;
bpf_u_int32 capture_len;
bpf_u_int32 len;
}pcap_header;
#define ETH_ALEN 6
#define __LITTLE_ENDIAN_BITFIELD 1
#define NIPQUAD(addr) \
((unsigned char *)&addr)[0], \
((unsigned char *)&addr)[1], \
((unsigned char *)&addr)[2], \
((unsigned char *)&addr)[3]
struct ethhdr {
unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
unsigned char h_source[ETH_ALEN]; /* source ether addr */
unsigned short h_proto; /* packet type ID field */
};
struct iphdr {
#if defined(__LITTLE_ENDIAN_BITFIELD)
__u8 ihl:4,
version:4;
#elif defined (__BIG_ENDIAN_BITFIELD)
__u8 version:4,
ihl:4;
#endif
__u8 tos;
__be16 tot_len;
__be16 id;
__be16 frag_off;
__u8 ttl;
__u8 protocol;
__u16 check;
__be32 saddr;
__be32 daddr;
/*The options start here. */
};
struct tcphdr {
__u16 source;
__u16 dest;
__u32 seq;
__u32 ack_seq;
#if defined(__LITTLE_ENDIAN_BITFIELD)
__u16 res1:4,
doff:4,
fin:1,
syn:1,
rst:1,
psh:1,
ack:1,
urg:1,
ece:1,
cwr:1;
#elif defined(__BIG_ENDIAN_BITFIELD)
__u16 doff:4,
res1:4,
cwr:1,
ece:1,
urg:1,
ack:1,
psh:1,
rst:1,
syn:1,
fin:1;
#endif
__u16 window;
__u16 check;
__u16 urg_ptr;
};
struct udphdr {
__u16 source;
__u16 dest;
__u16 len;
__u16 check;
};
struct icmphdr {
__u8 type;
__u8 code;
__u16 checksum;
union {
struct {
__u16 id;
__u16 sequence;
} echo;
__u32 gateway;
struct {
__u16 __unused;
__u16 mtu;
} frag;
} un;
};
FILE *fp1, *fp2;
__u32 flag1, flag2, seq1, seq2, ip1, ip2;
long long stime;
void printPcap(int count, void * data, struct pcap_header *ph)
{
size_t size = ph->capture_len;
unsigned short iPos = 0;
struct ethhdr *eth;
struct iphdr *iph;
struct tcphdr *tcph;
struct udphdr *udph;
struct icmphdr *icmph;
__u8 op1, op2, type, len;
void * data1;
int i;
long long dt;
if (data==NULL) {
return;
}
eth = (struct ethhdr*)(data);
eth->h_proto = ntohs(eth->h_proto);
//printf("Ether:\tproto = 0x%x\n", eth->h_proto);
if (eth->h_proto == 0x0800) { // IP
iph = (struct iphdr*)(data+sizeof(struct ethhdr));
if (iph->protocol == IPPROTO_TCP) { // tcp
tcph = (struct tcphdr*)(data+sizeof(struct ethhdr)+sizeof(struct iphdr));
if (tcph->ack == 0 && tcph->syn == 1) {
seq1 = ntohl(tcph->seq);
ip1 = iph->saddr;
flag1 = 1;
stime = 1000000LL*ph->ts.timestamp_s + ph->ts.timestamp_ms;
} else if (tcph->ack == 1 && tcph->syn == 1) {
seq2 = ntohl(tcph->seq);
ip2 = iph->saddr;
flag2 = 1;
}
if (flag1 == 0) {
flag1 = 1;
seq1 = ntohl(tcph->seq)-1;
ip1 = iph->saddr;
stime = 1000000LL*ph->ts.timestamp_s + ph->ts.timestamp_ms;
}
if (flag2 == 0 && iph->saddr != ip1) {
flag2 = 1;
seq2 = ntohl(tcph->seq)-1;
ip2 = iph->saddr;
}
dt = (1000000LL*ph->ts.timestamp_s+ph->ts.timestamp_ms) - stime;
fprintf(fp1, "%d\t%llu\t", count, dt/1000);
fprintf(fp1, "%d.%d.%d.%d\t%d.%d.%d.%d\t%u\t%u\t%d\t",
NIPQUAD(iph->saddr), NIPQUAD(iph->daddr),
(iph->saddr==ip1?ntohl(tcph->seq)-seq1:ntohl(tcph->seq)-seq2),
(iph->saddr==ip1?ntohl(tcph->ack_seq)-seq2:ntohl(tcph->ack_seq)-seq1),
ntohs(iph->tot_len)-iph->ihl*4-tcph->doff*4 + tcph->syn + tcph->fin);
fprintf(fp1, "%d\t%d\t%d\t%d\t", ntohs(iph->tot_len), iph->ihl*4, tcph->doff*4, iph->ttl);
fprintf(fp1, "%u\t%u\t%d\t%d\t%d\t",
ntohl(tcph->seq), ntohl(tcph->ack_seq),
tcph->ack, tcph->syn, ntohs(tcph->window));
if (tcph->doff > 5) {
data1 = data + sizeof(struct ethhdr)+sizeof(struct iphdr)+sizeof(struct tcphdr);
op1 = *(__u8*)(data1);
op2 = *(__u8*)(data1+1);
type = *(__u8*)(data1+2);
len = *(__u8*)(data1+3);
//fprintf(fp1, "%u\t%u\t%u\t%u\n", op1, op2, type, len);
if (op1 == 1 && op2 == 1 && type == 5) { // sack
i = 4;
while (i < len+2) {
if (i > 4) fprintf(fp1, " ");
fprintf(fp1, "%u-%u", ntohl(*(__u32*)(data1+i))-seq2, ntohl(*(__u32*)(data1+i+4))-seq2);
i += 8;
}
}
}
fprintf(fp1, "\n");
} else if (iph->protocol == IPPROTO_UDP) { // udp
udph = (struct udphdr*)(data+sizeof(struct ethhdr)+sizeof(struct iphdr));
//printf("UDP:\tsource=%u\tdest=%u\tlen=%d\n", ntohs(udph->source), ntohs(udph->dest), ntohs(udph->len));
} else if (iph->protocol == IPPROTO_ICMP) { // ICMP
icmph = (struct icmphdr*)(data+sizeof(struct ethhdr)+sizeof(struct iphdr));
//printf("ICMP:\ttype=%u\tcode=%u\n", icmph->type, icmph->code);
}
}
}
#define MAX_ETH_FRAME 1514000
int main (int argc, const char * argv[])
{
pcap_file_header pfh;
pcap_header ph;
int count=0;
void * buff = NULL;
int readSize=0;
int ret = 0;
if (argc != 2) {
printf("uage: ./a.out pcap_filename\n");
return -1;
}
FILE *fp = fopen(argv[1], "r");
if (fp==NULL) {
fprintf(stderr, "Open file %s error.", argv[1]);
return -1;
}
fread(&pfh, sizeof(pcap_file_header), 1, fp);
fp1 = fopen("out", "w");
fprintf(fp1, "#ID\tTIME\tsaddr\tdaddr\tseq\tack_seq\tpayload\ttot_len\tihl\tdoff\tttl\tseq\tack_seq\tack\tsyn\twin\tSACK\n");
buff = (void *)malloc(MAX_ETH_FRAME);
flag1 = flag2 = 0;
for (count=1; ; count++) {
memset(buff,0,MAX_ETH_FRAME);
readSize=fread(&ph, sizeof(pcap_header), 1, fp);
if (readSize<=0) {
break;
}
if (buff==NULL) {
fprintf(stderr, "malloc memory failed.\n");
return -1;
}
readSize=fread(buff,1,ph.capture_len, fp);
if (readSize != ph.capture_len) {
free(buff);
fprintf(stderr, "pcap file parse error.\n");
return -1;
}
printPcap(count, buff, &ph);
if (feof(fp) || readSize <=0 ) {
break;
}
}
fclose(fp);
fclose(fp1);
return ret;
}
|