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 /*----------------------------------------------------------------------------*/ 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 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 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 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 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