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