1 #include <stdio.h>
2 #include <unistd.h>
3 #include <string.h>
4 #include <stdint.h>
5 #include <stdarg.h>
6 #include "debug.h"
7 #include "tcp_in.h"
8 #include "logger.h"
9 #include "ip_in.h"
10
11 /*----------------------------------------------------------------------------*/
flush_log_data(mtcp_manager_t mtcp)12 void flush_log_data(mtcp_manager_t mtcp)
13 {
14 int ret = 0;
15 if (mtcp->w_buffer) {
16 EnqueueJobBuffer(mtcp->logger, mtcp->w_buffer);
17 ret = write(mtcp->sp_fd, "A", 1);
18 if (ret != 1) {
19 TRACE_INFO("Failed to flush logs in the buffer.\n");
20 perror("write() for pipe");
21 }
22 }
23 }
24 /*----------------------------------------------------------------------------*/
25 void
thread_printf(mtcp_manager_t mtcp,FILE * f_idx,const char * _Format,...)26 thread_printf(mtcp_manager_t mtcp, FILE* f_idx, const char* _Format, ...)
27 {
28 va_list argptr;
29 va_start(argptr, _Format);
30
31 #define PRINT_LIMIT 4096
32 int len;
33 log_buff *wbuf;
34
35 assert(f_idx != NULL);
36
37 pthread_mutex_lock(&mtcp->logger->mutex);
38 wbuf = mtcp->w_buffer;
39 if (wbuf && (wbuf->buff_len + PRINT_LIMIT > LOG_BUFF_SIZE)) {
40 flush_log_data(mtcp);
41 wbuf = NULL;
42 }
43
44 if (!wbuf) {
45 do { // out of free buffers!!
46 wbuf = DequeueFreeBuffer(mtcp->logger);
47 assert(wbuf);
48 } while (!wbuf);
49 wbuf->buff_len = 0;
50 wbuf->tid = mtcp->ctx->cpu;
51 wbuf->fid = f_idx;
52 mtcp->w_buffer = wbuf;
53 }
54
55 len = vsnprintf(wbuf->buff + wbuf->buff_len, PRINT_LIMIT, _Format, argptr);
56 wbuf->buff_len += len;
57 pthread_mutex_unlock(&mtcp->logger->mutex);
58
59 va_end(argptr);
60
61 }
62 /*----------------------------------------------------------------------------*/
63 void
DumpPacket(mtcp_manager_t mtcp,char * buf,int len,char * step,int ifindex)64 DumpPacket(mtcp_manager_t mtcp, char *buf, int len, char *step, int ifindex)
65 {
66 struct ethhdr *ethh;
67 struct iphdr *iph;
68 struct udphdr *udph;
69 struct tcphdr *tcph;
70 uint8_t *t;
71
72 if (ifindex >= 0)
73 thread_printf(mtcp, mtcp->log_fp, "%s %d %u", step, ifindex, mtcp->cur_ts);
74 else
75 thread_printf(mtcp, mtcp->log_fp, "%s ? %u", step, mtcp->cur_ts);
76
77 ethh = (struct ethhdr *)buf;
78 if (ntohs(ethh->h_proto) != ETH_P_IP) {
79 thread_printf(mtcp, mtcp->log_fp, "%02X:%02X:%02X:%02X:%02X:%02X -> %02X:%02X:%02X:%02X:%02X:%02X ",
80 ethh->h_source[0],
81 ethh->h_source[1],
82 ethh->h_source[2],
83 ethh->h_source[3],
84 ethh->h_source[4],
85 ethh->h_source[5],
86 ethh->h_dest[0],
87 ethh->h_dest[1],
88 ethh->h_dest[2],
89 ethh->h_dest[3],
90 ethh->h_dest[4],
91 ethh->h_dest[5]);
92
93 thread_printf(mtcp, mtcp->log_fp, "protocol %04hx ", ntohs(ethh->h_proto));
94 goto done;
95 }
96
97 thread_printf(mtcp, mtcp->log_fp, " ");
98
99 iph = (struct iphdr *)(ethh + 1);
100 udph = (struct udphdr *)((uint32_t *)iph + iph->ihl);
101 tcph = (struct tcphdr *)((uint32_t *)iph + iph->ihl);
102
103 t = (uint8_t *)&iph->saddr;
104 thread_printf(mtcp, mtcp->log_fp, "%u.%u.%u.%u", t[0], t[1], t[2], t[3]);
105 if (iph->protocol == IPPROTO_TCP || iph->protocol == IPPROTO_UDP)
106 thread_printf(mtcp, mtcp->log_fp, "(%d)", ntohs(udph->source));
107
108 thread_printf(mtcp, mtcp->log_fp, " -> ");
109
110 t = (uint8_t *)&iph->daddr;
111 thread_printf(mtcp, mtcp->log_fp, "%u.%u.%u.%u", t[0], t[1], t[2], t[3]);
112 if (iph->protocol == IPPROTO_TCP || iph->protocol == IPPROTO_UDP)
113 thread_printf(mtcp, mtcp->log_fp, "(%d)", ntohs(udph->dest));
114
115 thread_printf(mtcp, mtcp->log_fp, " IP_ID=%d", ntohs(iph->id));
116 thread_printf(mtcp, mtcp->log_fp, " TTL=%d ", iph->ttl);
117
118 if (ip_fast_csum(iph, iph->ihl)) {
119 __sum16 org_csum, correct_csum;
120
121 org_csum = iph->check;
122 iph->check = 0;
123 correct_csum = ip_fast_csum(iph, iph->ihl);
124 thread_printf(mtcp, mtcp->log_fp, "(bad checksum %04x should be %04x) ",
125 ntohs(org_csum), ntohs(correct_csum));
126 iph->check = org_csum;
127 }
128
129 switch (iph->protocol) {
130 case IPPROTO_TCP:
131 thread_printf(mtcp, mtcp->log_fp, "TCP ");
132
133 if (tcph->syn)
134 thread_printf(mtcp, mtcp->log_fp, "S ");
135 if (tcph->fin)
136 thread_printf(mtcp, mtcp->log_fp, "F ");
137 if (tcph->ack)
138 thread_printf(mtcp, mtcp->log_fp, "A ");
139 if (tcph->rst)
140 thread_printf(mtcp, mtcp->log_fp, "R ");
141
142 thread_printf(mtcp, mtcp->log_fp, "seq %u ", ntohl(tcph->seq));
143 if (tcph->ack)
144 thread_printf(mtcp, mtcp->log_fp, "ack %u ", ntohl(tcph->ack_seq));
145 thread_printf(mtcp, mtcp->log_fp, "WDW=%u ", ntohs(tcph->window));
146 break;
147 case IPPROTO_UDP:
148 thread_printf(mtcp, mtcp->log_fp, "UDP ");
149 break;
150 default:
151 thread_printf(mtcp, mtcp->log_fp, "protocol %d ", iph->protocol);
152 goto done;
153 }
154 done:
155 thread_printf(mtcp, mtcp->log_fp, "len=%d\n", len);
156 }
157 /*----------------------------------------------------------------------------*/
158 void
DumpIPPacket(mtcp_manager_t mtcp,const struct iphdr * iph,int len)159 DumpIPPacket(mtcp_manager_t mtcp, const struct iphdr *iph, int len)
160 {
161 struct udphdr *udph;
162 struct tcphdr *tcph;
163 uint8_t *t;
164
165 udph = (struct udphdr *)((uint32_t *)iph + iph->ihl);
166 tcph = (struct tcphdr *)((uint32_t *)iph + iph->ihl);
167
168 t = (uint8_t *)&iph->saddr;
169 thread_printf(mtcp, mtcp->log_fp, "%u.%u.%u.%u", t[0], t[1], t[2], t[3]);
170 if (iph->protocol == IPPROTO_TCP || iph->protocol == IPPROTO_UDP)
171 thread_printf(mtcp, mtcp->log_fp, "(%d)", ntohs(udph->source));
172
173 thread_printf(mtcp, mtcp->log_fp, " -> ");
174
175 t = (uint8_t *)&iph->daddr;
176 thread_printf(mtcp, mtcp->log_fp, "%u.%u.%u.%u", t[0], t[1], t[2], t[3]);
177 if (iph->protocol == IPPROTO_TCP || iph->protocol == IPPROTO_UDP)
178 thread_printf(mtcp, mtcp->log_fp, "(%d)", ntohs(udph->dest));
179
180 thread_printf(mtcp, mtcp->log_fp, " IP_ID=%d", ntohs(iph->id));
181 thread_printf(mtcp, mtcp->log_fp, " TTL=%d ", iph->ttl);
182
183 if (ip_fast_csum(iph, iph->ihl)) {
184 thread_printf(mtcp, mtcp->log_fp, "(bad checksum) ");
185 }
186
187 switch (iph->protocol) {
188 case IPPROTO_TCP:
189 thread_printf(mtcp, mtcp->log_fp, "TCP ");
190
191 if (tcph->syn)
192 thread_printf(mtcp, mtcp->log_fp, "S ");
193 if (tcph->fin)
194 thread_printf(mtcp, mtcp->log_fp, "F ");
195 if (tcph->ack)
196 thread_printf(mtcp, mtcp->log_fp, "A ");
197 if (tcph->rst)
198 thread_printf(mtcp, mtcp->log_fp, "R ");
199
200 thread_printf(mtcp, mtcp->log_fp, "seq %u ", ntohl(tcph->seq));
201 if (tcph->ack)
202 thread_printf(mtcp, mtcp->log_fp, "ack %u ", ntohl(tcph->ack_seq));
203 thread_printf(mtcp, mtcp->log_fp, "WDW=%u ", ntohs(tcph->window));
204 break;
205 case IPPROTO_UDP:
206 thread_printf(mtcp, mtcp->log_fp, "UDP ");
207 break;
208 default:
209 thread_printf(mtcp, mtcp->log_fp, "protocol %d ", iph->protocol);
210 goto done;
211 }
212 done:
213 thread_printf(mtcp, mtcp->log_fp, "len=%d\n", len);
214 }
215 /*----------------------------------------------------------------------------*/
216 void
DumpIPPacketToFile(FILE * fout,const struct iphdr * iph,int len)217 DumpIPPacketToFile(FILE *fout, const struct iphdr *iph, int len)
218 {
219 struct udphdr *udph;
220 struct tcphdr *tcph;
221 uint8_t *t;
222
223 udph = (struct udphdr *)((uint32_t *)iph + iph->ihl);
224 tcph = (struct tcphdr *)((uint32_t *)iph + iph->ihl);
225
226 t = (uint8_t *)&iph->saddr;
227 fprintf(fout, "%u.%u.%u.%u", t[0], t[1], t[2], t[3]);
228 if (iph->protocol == IPPROTO_TCP || iph->protocol == IPPROTO_UDP)
229 fprintf(fout, "(%d)", ntohs(udph->source));
230
231 fprintf(fout, " -> ");
232
233 t = (uint8_t *)&iph->daddr;
234 fprintf(fout, "%u.%u.%u.%u", t[0], t[1], t[2], t[3]);
235 if (iph->protocol == IPPROTO_TCP || iph->protocol == IPPROTO_UDP)
236 fprintf(fout, "(%d)", ntohs(udph->dest));
237
238 fprintf(fout, " IP_ID=%d", ntohs(iph->id));
239 fprintf(fout, " TTL=%d ", iph->ttl);
240
241 if (ip_fast_csum(iph, iph->ihl)) {
242 fprintf(fout, "(bad checksum) ");
243 }
244
245 switch (iph->protocol) {
246 case IPPROTO_TCP:
247 fprintf(fout, "TCP ");
248
249 if (tcph->syn)
250 fprintf(fout, "S ");
251 if (tcph->fin)
252 fprintf(fout, "F ");
253 if (tcph->ack)
254 fprintf(fout, "A ");
255 if (tcph->rst)
256 fprintf(fout, "R ");
257
258 fprintf(fout, "seq %u ", ntohl(tcph->seq));
259 if (tcph->ack)
260 fprintf(fout, "ack %u ", ntohl(tcph->ack_seq));
261 fprintf(fout, "WDW=%u ", ntohs(tcph->window));
262 break;
263 case IPPROTO_UDP:
264 fprintf(fout, "UDP ");
265 break;
266 default:
267 fprintf(fout, "protocol %d ", iph->protocol);
268 goto done;
269 }
270 done:
271 fprintf(fout, "len=%d\n", len);
272 }
273