static int tcp_send_ack(struct tcp_socket *sk) { unsigned char pkt[20]; struct tcphdr *hdr; hdr = (struct tcphdr *)pkt; hdr->srcport = htons(sk->localport); hdr->dstport = htons(sk->remoteport); hdr->seqnum = htonl(sk->snd_nxt); /* do not consume a seqnum! */ hdr->acknum = htonl(sk->rcv_nxt); hdr->hdrlen = 5; /* 20 / 4 = 5 */ hdr->reserved1 = hdr->reserved2 = 0; hdr->cntrlbits = TCPBIT_ACK; hdr->window = htons(TCP_DEFAULT_WINDOW); hdr->csum = 0; hdr->urgptr = 0; hdr->csum = tcp_checksum(pkt, hdr->hdrlen*4, htonl(INTERMOBI_OURIP), htonl(sk->remoteaddr)); ip_send(htonl(sk->remoteaddr), IPPROTO_TCP, pkt, 20); return 0; }
void rewriteIpv4( char* argv, int len, char* ipv4 ) { PETH_HDR ether; PIP_HDR ip; PTCP_HDR tcp; PUDP_HDR udp; int ulen; ether = (PETH_HDR)argv; // IPv4 if ( ntohs( ether->ether_type ) == ETHER_TYPE_IP ) { #ifdef DEBUG printf("rewrite.c - IPv4 rewrite\n"); #endif if ( checkPacketNotLen( len, ( ETHER_HDRLEN + IP_HDRLEN ) ) ) return; ip = (PIP_HDR)(argv + ETHER_HDRLEN); inet_pton( AF_INET, ipv4, &(ip->ip_saddr) ); ip->ip_checksum = 0; ip->ip_checksum = ip_checksum( ip, ( ip->ip_ihl * 4 ) ); #ifdef DEBUG printf("rewrite.c - IPv4 checksum recalculated = %x\n", ntohs( ip->ip_checksum ) ); #endif // TCP checksum if ( ip->ip_protocol == IPPROTO_TCP ) { ulen = len - ETHER_HDRLEN - ( ip->ip_ihl * 4 ); if ( checkPacketNotLen( len, ( ETHER_HDRLEN + ( ip->ip_ihl * 4 ) + TCP_HDRLEN ) ) ) return; tcp = (PTCP_HDR)(argv + ETHER_HDRLEN + ( ip->ip_ihl * 4 ) ); tcp->tcp_checksum = 0; tcp->tcp_checksum = tcp_checksum( tcp, ulen, ip->ip_saddr, ip->ip_daddr ); #ifdef DEBUG printf("rewrite.c - TCPv4 checksum recalculated = %x\n", ntohs( tcp->tcp_checksum ) ); #endif } // UDP checksum if ( ip->ip_protocol == IPPROTO_UDP ) { if ( checkPacketNotLen( len, ( ETHER_HDRLEN + ( ip->ip_ihl * 4 ) + UDP_HDRLEN ) ) ) return; ulen = len - ETHER_HDRLEN - ( ip->ip_ihl * 4 ); udp = (PUDP_HDR)(argv + ETHER_HDRLEN + ( ip->ip_ihl * 4 ) ); udp->udp_checksum = 0; udp->udp_checksum = udp_checksum( udp, ulen, ip->ip_saddr, ip->ip_daddr ); #ifdef DEBUG printf("rewrite.c - UDPv4 checksum recalculated = %x\n", ntohs( udp->udp_checksum ) ); #endif } } }
int send_pktbuff(pktbuff *pktbuff_out, struct pcb *pcb, struct thread_context *context, struct worker_data *data) { int rv; uint16_t len; // TODO: build layers based on pcb or pktbuff layer data // complete the lower layers and send pktbuff len = ethernet_build_header(&context->shared->if_info->mac, &pcb->remote_mac, IP4_ETHERTYPE, 0xFFFF, pktbuff_out->data); len += ip4_build_header(context->shared->inet_info->addr.s_addr, FLOWID_REMOTE_IP(pcb->flowid), pktbuff_out->len, pcb->ipproto, NULL, FCL_PTR_PAST(pktbuff_out->data, len)); pktbuff_out->len += len; // fixup layer 3 checksums struct ip4_pkt *send_ip = FCL_PTR_PAST(pktbuff_out->data, pcb_layer_offset(pcb, PCB_LAYER_IP4)); struct tcp_pkt *tcp; struct udp_pkt *udp; switch(pcb->ipproto) { case IPPROTO_TCP: tcp = ip4_get_next(send_ip); tcp->tcp_h.th_sum = tcp_checksum(send_ip); break; case IPPROTO_UDP: udp = ip4_get_next(send_ip); udp->udp_h.uh_sum = udp_checksum(send_ip); break; } // and finally queue the pktbuff for sending rv = tqueue_insert(context->pkt_xmit_q, &data->xmit_transaction, pktbuff_out); // xmit packet without waiting to fill a transaction if (rv == TQUEUE_SUCCESS) { tqueue_publish_transaction(context->pkt_xmit_q, &data->xmit_transaction); return 1; } return -1; }
/* * Функция, вызываемая pcap_loop при получении пакета. Производит * форматированный вывод его содержимого. Прототип обязательно такого вида. */ void handler_packet(u_char *args, struct pcap_pkthdr *info, u_char *packet) { short proto; // Инкапсулированный протокол текущего заголовка u_char *header; // Указатель на текущий заголовок u_char *header_prev; // Указатель на предыдущий заголовок u_short chsum; // Контрольная сумма // Выводим симолы для разделения вывода пакетов for (int i = 0; i< 93; i++) printf("="); printf("\n\n"); // Поочередно разворачиваем пакет, смещаясь до следующего заголовка header = packet; proto = ethernet_print((struct hdr_ethernet *)header); header += ethernet_getsize((struct hdr_ethernet *)header); while(proto != 0){ switch (proto){ case TYPE_IP: proto = ip_print((struct hdr_ip *)header); header_prev = header; header += ip_getsize((struct hdr_ip *)header) * 4; break; case TYPE_TCP: proto = tcp_print((struct hdr_tcp *)header); chsum = tcp_checksum(header, header_prev, info->caplen - (int)(header - packet)); printf("calc_chsum: %#x\n", chsum); header += tcp_getsize((struct hdr_tcp *)header); break; default: proto = 0; } } // Выводим оставшиеся данные print_data(header, info->caplen - (int)(header - packet)); printf("\n"); }
/* * Send a RST to destip, from port srcport to port dstport, acking seqnum. */ static int tcp_send_rst(unsigned long destip, unsigned short dstport, unsigned short srcport, unsigned long seqnum) { unsigned char pkt[20]; struct tcphdr *hdr = (struct tcphdr *)pkt; hdr->srcport = srcport; hdr->dstport = dstport; hdr->seqnum = 0; /* not used in this, right? */ hdr->acknum = htonl(ntohl(seqnum)+1); hdr->hdrlen = 5; /* 20 / 4 = 5 */ hdr->reserved1 = hdr->reserved2 = 0; hdr->cntrlbits = TCPBIT_RST | TCPBIT_ACK; hdr->window = 0; hdr->csum = 0; hdr->urgptr = 0; hdr->csum = tcp_checksum(pkt, hdr->hdrlen*4, htonl(INTERMOBI_OURIP), destip); ip_send(destip, IPPROTO_TCP, pkt, 20); return 0; }
static int writer(struct scanner *sc) { struct sockaddr_in6 *sin; struct tcphdr *tcp; int ret; /* TCP header. */ tcp = (struct tcphdr *) sc->obuf; tcp->source = htons(1024); tcp->dest = htons(sc->tracker.next); tcp->seq = 0; tcp->ack_seq = 0; tcp->res1 = 0; tcp->doff = 5; tcp->syn = 1; tcp->rst = tcp->psh = tcp->ack = tcp->urg = 0; tcp->res2 = 0; tcp->window = 0; tcp->check = 0; tcp->urg_ptr = 0; tcp->check = tcp_checksum(sc, tcp); ret = sendto(sc->rawfd, sc->obuf, sc->olen, 0, sc->dst->ai_addr, sc->dst->ai_addrlen); if (ret != sc->olen) { if (ret < 0) warn("sendto() error\n"); else info("sendto() can't send full data\n"); return -1; } /* Store the destination address string for debugging purpose. */ sin = (struct sockaddr_in6 *) sc->dst->ai_addr; inet_ntop(AF_INET6, &sin->sin6_addr, sc->addr, INET6_ADDRSTRLEN); return ret; }
int synscan_make_packet(void *buf, ipaddr_n_t src_ip, ipaddr_n_t dst_ip, uint32_t *validation, int probe_num) { struct ether_header *eth_header = (struct ether_header *)buf; struct ip *ip_header = (struct ip*)(ð_header[1]); struct tcphdr *tcp_header = (struct tcphdr*)(&ip_header[1]); uint32_t tcp_seq = validation[0]; ip_header->ip_src.s_addr = src_ip; ip_header->ip_dst.s_addr = dst_ip; tcp_header->th_sport = htons(get_src_port(num_ports, probe_num, validation)); tcp_header->th_seq = tcp_seq; tcp_header->th_sum = 0; tcp_header->th_sum = tcp_checksum(sizeof(struct tcphdr), ip_header->ip_src.s_addr, ip_header->ip_dst.s_addr, tcp_header); ip_header->ip_sum = 0; ip_header->ip_sum = zmap_ip_checksum((unsigned short *) ip_header); return EXIT_SUCCESS; }
/* * This is a bit complicated because we attempt to stuff everything * we've already sent that hasn't been acked into this packet, along * with the new data. * * XXX check the endpoint window and MSS to make sure we don't overflow it. * */ static int tcp_send_data(struct tcp_socket *sk, const unsigned char *data, int datalen) { unsigned char *pkt; struct tcphdr *hdr; struct tcpvec *cur; unsigned short flags = 0; unsigned long seqnum; /* First, enqueue the new data and increment the next seqnum */ if (data && datalen) tcp_txenqueue(sk, 0, sk->snd_nxt, bufdup(data, datalen), datalen); for (cur = sk->txqueue, datalen = 0, seqnum = sk->snd_nxt; cur && (datalen < sk->rcv_max); cur = cur->next) { if (cur->txcount >= TCP_MAX_RETRIES) { tcp_changestate(sk, STATE_TIME_WAIT); tcp_send_fin(sk); return -1; } flags |= cur->flags; if (cur->seqnum < seqnum) seqnum = cur->seqnum; /* get the lowest seqnum queued */ datalen += cur->len; } dprintf("tcp_send_data: procesing %d queued bytes\n", datalen); if (!(pkt = RimMalloc(20+datalen))) return -1; hdr = (struct tcphdr *)pkt; hdr->srcport = htons(sk->localport); hdr->dstport = htons(sk->remoteport); if (sk->snd_nxt < sk->snd_una) sk->snd_una = sk->snd_nxt; hdr->seqnum = htonl(seqnum); hdr->acknum = htonl(sk->rcv_nxt); hdr->hdrlen = 5; /* 20 / 4 = 5 */ hdr->reserved1 = hdr->reserved2 = 0; hdr->cntrlbits = TCPBIT_ACK | flags | (!flags ? TCPBIT_PSH : 0); hdr->window = htons(TCP_DEFAULT_WINDOW); hdr->csum = 0; hdr->urgptr = 0; for (cur = sk->txqueue, flags = 20; cur; cur = cur->next) { memcpy(pkt+flags, cur->buf+cur->start, cur->len); flags += cur->len; cur->lasttx = RimGetTicks(); cur->txcount++; } hdr->csum = tcp_checksum(pkt, (hdr->hdrlen*4)+datalen, htonl(INTERMOBI_OURIP), htonl(sk->remoteaddr)); ip_send(htonl(sk->remoteaddr), IPPROTO_TCP, pkt, 20+datalen); RimFree(pkt); return 0; }
/** * TODO : take the pseudo header function out. NOTE : make sure it is generic * enough to be called by handshake funcs AND send data funcs. * TODO : 3rd shake might have data * TODO : RST */ void tcp_send_handshake(int gripnum, socket_t *socket){ tcphdr *header = NULL; switch(gripnum) { case 0: printf("\t TODO : RST NOT IMPLEMENTED YET\n"); case SYN_SENT://1'st shake header = tcp_mastercrafter(socket->myport, socket->urport, socket->myseq, 0,0,1,0,0,0, WINSIZE); //half the max sequence number break; case SYN_RCVD://2'nd shake header = tcp_mastercrafter(socket->myport, socket->urport, (socket->myseq)++, socket->ackseq, 0,1,0,0,1, WINSIZE); break; case ESTABLISHED://3'rd shake header = tcp_mastercrafter(socket->myport, socket->urport, ++(socket->myseq), socket->ackseq, 0,0,0,0,1, WINSIZE); break; case FIN_WAIT_1:// from ESTABLISHED --> FIN_WAIT_1 state (FIN SEGMENT) header = tcp_mastercrafter(socket->myport, socket->urport, socket->myseq, socket->ackseq, 1,0,0,0,1,MAXSEQ); break; case CLOSE_WAIT: //regular ACK header = tcp_mastercrafter(socket->myport, socket->urport, socket->myseq, socket->ackseq, 0,0,0,0,1,MAXSEQ); break; case LAST_ACK: // moving from CLOSE_WAIT --> LAST_ACK (FIN SEGMENT) header = tcp_mastercrafter(socket->myport, socket->urport, socket->myseq, socket->ackseq, 1,0,0,0,1,MAXSEQ); break; case CLOSING: // moving from FIN_WAIT_1 --> CLOSING header = tcp_mastercrafter(socket->myport, socket->urport, socket->myseq, socket->ackseq, 1,0,0,0,1,MAXSEQ); break; case ACKNOWLEDGE: printf("RST, ACK\n"); header = tcp_mastercrafter(socket->myport, socket->urport, socket->myseq, socket->ackseq, 0,0,0,0,1,MAXSEQ); case RST: // RST packet header = tcp_mastercrafter(socket->myport, socket->urport, socket->myseq, socket->ackseq, 1,0,0,0,1,MAXSEQ); break; default: printf("\t WARNING : Unknown shake!\n"); return; } //0. make sure TCP header is not NULL if (header == NULL) { printf("\tWARNING : Could not make TCP header\n"); return; } struct pseudo_tcpp *tcp_packet = (uint16_t *)malloc(sizeof(struct pseudo_tcpp)); memset(tcp_packet, 0x0, sizeof(struct pseudo_tcpp)); //1. fill the pseudiheader part ((uint32_t *)tcp_packet)[0] = socket->myaddr; ((uint32_t *)tcp_packet)[1] = socket->uraddr; ((uint8_t *)tcp_packet)[9] = (uint8_t)TCP; ((uint16_t *)tcp_packet)[5] = ntohs((uint16_t)TCPHDRSIZE); //2. fill the header tcp_hton(header); memcpy(&tcp_packet->tcp, header, TCPHDRSIZE); //3. data (NONE) //TODO : 3rd handshake could have data. memset(tcp_packet->payload, 0, 1024); //4. checksum uint16_t checksum = tcp_checksum(tcp_packet, TCPHDRSIZE+12); //5. set the checksum in the TCP header header->check = checksum; if (header->check == 0) { printf("\t ERROR : something went wrong with checksum\n"); header->check = 0xffffff; } //6. TODO : error checking interface_t *nexthop = get_nexthop(socket->uraddr); //TODO : packet top pass to ip char *packet = (char *)malloc(TCPHDRSIZE+IPHDRSIZE); if (packet == NULL) { printf("\t ERROR : Malloc failed\n"); return; } //7. copy the TCP header to ip packet memset(packet, 0, TCPHDRSIZE+IPHDRSIZE); memcpy(packet, header, TCPHDRSIZE); //8. NO data, so you are done : pass to ip encapsulate_inip(socket->myaddr,socket->uraddr,(uint8_t)TCP,header, TCPHDRSIZE, &packet); //9. TCP/IP packet all set, sending time int ret = send_ip(nexthop, packet, TCPHDRSIZE+IPHDRSIZE); free(tcp_packet); free(packet); free(header); return; }
void packet_send(struct in_addr ip, uint16_t port, uint8_t type) { uint8_t packet[IP_MAXPACKET]; struct ifreq ifr; struct sockaddr_ll sll; int sockfd, done = 0; int ethdrlen = sizeof(struct ether_header); int iphdrlen = sizeof(struct ip); int tcphdrlen = sizeof(struct tcphdr); int udphdrlen = sizeof(struct udphdr); int packetlen = ethdrlen + iphdrlen; int payloadlen = 0; struct ether_header *eth = (struct ether_header *)packet; struct ip *iphdr = (struct ip *)(packet + ethdrlen); struct tcphdr *tcphdr = (struct tcphdr *)((uint8_t *)iphdr + iphdrlen); struct udphdr *udphdr = (struct udphdr *)((uint8_t *)iphdr + iphdrlen); char *payload; memset(packet, 0, IP_MAXPACKET); //printf("\tsend() - IP: %s, PORT: %d, TYPE:%x\n", inet_ntoa(ip), port, type); /* Set Static Options */ eth->ether_type = htons(ETHERTYPE_IP); iphdr->ip_hl = iphdrlen / sizeof(uint32_t); // 5 iphdr->ip_v = 4; iphdr->ip_ttl = 128; memcpy(&iphdr->ip_dst, &ip, sizeof(struct in_addr)); if( type == UDP ) { payload = (char *)packet + packetlen + udphdrlen; payloadlen = UDP_PAYLOAD; iphdr->ip_p = IPPROTO_UDP; udphdr->len = htons(udphdrlen + payloadlen); udphdr->dest = htons(port); packetlen += udphdrlen + payloadlen; }else { payload = (char *)packet + packetlen + tcphdrlen; iphdr->ip_p = IPPROTO_TCP; tcphdr->dest = htons(port); tcphdr->doff = tcphdrlen / 4; // 5 tcphdr->window = htons(8192); if( type == SYN ) { memcpy(payload, "\x05\xb4\x01\x01\x04\x02", 6); payloadlen = 6; iphdr->ip_len = htons(iphdrlen + tcphdrlen + 6); tcphdr->syn = 1; }else { iphdr->ip_len = htons(iphdrlen + tcphdrlen); tcphdr->fin = 1; } packetlen += tcphdrlen + payloadlen; } /* SEND PACKET */ srand(time(NULL) + pthread_self()); /* Set Packet Options */ if( (sockfd = socket(PF_PACKET, SOCK_RAW, IPPROTO_RAW)) < 0 ) { perror("socket(): "); return; } memset(&ifr, 0, sizeof(struct ifreq)); strncpy(ifr.ifr_name, "eth0", IFNAMSIZ-1); if( ioctl(sockfd, SIOCGIFINDEX, &ifr) < 0 ) { perror("ioctl(): "); close(sockfd); return; } sll.sll_family = AF_PACKET; sll.sll_ifindex = ifr.ifr_ifindex; if( bind(sockfd, (struct sockaddr *)&sll, sizeof(sll)) < 0 ) { perror("bind(): "); close(sockfd); return; } while( 1 ) { /* IP HEADER */ iphdr->ip_id = rand(); iphdr->ip_src.s_addr = rand(); iphdr->ip_sum = 0; iphdr->ip_sum = checksum((uint16_t *)iphdr, iphdrlen); if( type == UDP ) { /* UDP HEADER */ udphdr->source = rand(); udphdr->check = 0; udphdr->check = udp_checksum(iphdr, udphdr, payload, payloadlen); }else { /* TCP HEADER */ tcphdr->source = rand(); tcphdr->seq = rand(); tcphdr->ack_seq = rand(); tcphdr->check = 0; tcphdr->check = tcp_checksum(iphdr, tcphdr, payload, payloadlen); } //rawprint(packet, packetlen); /* SEND PACKET */ // if( (done = write(sockfd, packet, packetlen)) != packetlen ) if( (done = write(sockfd, packet, packetlen)) < 0 ) { perror("write()"); }else if( done != packetlen ) { printf("%d / %d bytes sended\n", done, packetlen); } sleep(1); } close(sockfd); }
// Main int main(int argc, char **argv) { // ----------- Variable char recv_packet[BUFF_SIZE+40]; struct iphdr * ip_header = (struct iphdr *) recv_packet; struct tcphdr * tcp_header = 0; // ----------- Start printf("\nStart Deflector\n\n"); // ----------- Raw Socket printf("Create Raw Socket(Receive)\n"); int recv_socket = socketRaw(IPPROTO_TCP, DEFLECTOR_PORT); // ----------- UDP printf("Create UDP Socket(Send)\n"); int send_socket = socket( PF_INET, SOCK_DGRAM, 0 ); struct sockaddr_in bypass_addr; memset( &bypass_addr, 0, sizeof(bypass_addr) ); bypass_addr.sin_family = AF_INET; bypass_addr.sin_port = htons(BYPASS_PORT); bypass_addr.sin_addr.s_addr = inet_addr(BYPASS_ADDR); // ----------- Main Loop printf("Enter Main Loop\n"); while(1) { recvRaw( recv_socket, recv_packet, sizeof(recv_packet) ); tcp_header = (struct tcphdr *) (recv_packet + ip_header->ihl * 4); if ( ntohs( tcp_header->dest ) == DEFLECTOR_PORT ) { tcp_header = (struct tcphdr *) (recv_packet + ip_header->ihl * 4); tcp_header->check = 0; tcp_header->check = tcp_checksum(ip_header, tcp_header); ip_header->check = 0; ip_header->check = checksum2((unsigned short*)ip_header, sizeof(struct iphdr)); // ----------- Receive Packet printf("\nReceive Packet\n"); #ifdef DEBUG_DEFLECTOR printf("----------------------------------------\n"); printf( "[ 패킷을 받았습니다. ]\n" ); printf( "발신자 IP : %s\n", inet_ntoa( * (struct in_addr*) &ip_header->saddr) ); printf( "발신자 Port : %5u\n", ntohs(tcp_header->source) ); printf( "수신자 IP : %s\n", inet_ntoa( * (struct in_addr*) &ip_header->daddr) ); printf( "수신자 Port : %5u\n", ntohs(tcp_header->dest) ); printf( "IP packet size : %d\n", ntohs(ip_header->tot_len)); printf( "IP check : %d\n", ip_header->check ); printf( "IP Version : %d\n", ip_header->version ); // IP 버전 정보 출력 printf( "Time To Live : %d\n", ip_header->ttl ); // TTL 정보 출력 printf( "TCP check : %d\n", tcp_header->check ); printf( "Window Size : %d\n", tcp_header->window ); // 윈도우 사이즈 정보 출력 printf( "Flags : " ); // 플래그 정보 출력 if( tcp_header->fin == 1 ) printf( "[FIN]\n" ); if( tcp_header->syn == 1 ) printf( "[SYN]\n" ); if( tcp_header->rst == 1 ) printf( "[RST]\n" ); if( tcp_header->psh == 1 ) printf( "[PSH]\n" ); if( tcp_header->ack == 1 ) printf( "[ACK]\n" ); if( tcp_header->urg == 1 ) printf( "[URG]\n" ); printf("-----------------------------------------\n"); #endif // ----------- Send UDP Packet printf("Send UDP Packet\n"); sendto( send_socket, (void *) &recv_packet, sizeof(recv_packet)+1, 0, (struct sockaddr *) &bypass_addr, sizeof(bypass_addr) ); } } }
void tcp(uint8_t *packetData, int packetLength, struct IPFrameHeader *ipHeader) { struct TCPFrameHeader *header = (struct TCPFrameHeader *)packetData; printf("\n\tTCP Header\n"); printf("\t\tSource Port: "); switch(ntohs(header->tcp_source_port)) { case PORT_TELNET: printf("Telnet\n"); break; case PORT_FTP: printf("FTP"); break; case PORT_HTTP: printf("HTTP"); break; case PORT_POP3: printf("POP3"); break; case PORT_SMTP: printf("SMTP"); break; default: printf("%d", ntohs(header->tcp_source_port)); break; } printf("\n"); printf("\t\tDest Port: "); switch(ntohs(header->tcp_destination_port)) { case PORT_TELNET: printf("Telnet\n"); break; case PORT_FTP: printf("FTP"); break; case PORT_HTTP: printf("HTTP"); break; case PORT_POP3: printf("POP3"); break; case PORT_SMTP: printf("SMTP"); break; default: printf("%d", ntohs(header->tcp_destination_port)); break; } printf("\n"); printf("\t\tSequence Number: %u\n", ntohl(header->tcp_sequence_number)); printf("\t\tACK Number: %u\n", ntohl(header->tcp_acknowledgement_number)); printf("\t\tSYN Flag: %s\n", (header->tcp_flags & TCP_SYN) ? "Yes" : "No"); printf("\t\tRST Flag: %s\n", (header->tcp_flags & TCP_RST) ? "Yes" : "No"); printf("\t\tFIN Flag: %s\n", (header->tcp_flags & TCP_FIN) ? "Yes" : "No"); printf("\t\tWindow Size: %u\n", ntohs(header->tcp_window_size)); printf("\t\tChecksum: "); if(tcp_checksum(header, ipHeader)) { printf("Incorrect"); } else { printf("Correct"); } printf(" (0x%x)", ntohs(header->tcp_checksum)); // free(psuedoHeader); }