X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=blobdiff_plain;f=misc%2Fnetwork_servers%2Fvtl%2Ftest%2Fvtl_harness.cc;fp=misc%2Fnetwork_servers%2Fvtl%2Ftest%2Fvtl_harness.cc;h=6125b45efcdf6bbc90e1cbb4e763d772144c1d4f;hp=0000000000000000000000000000000000000000;hb=ac93f0773f4c6cef2f2f542240695a8706037d41;hpb=c016bb46bd68474161e275a5ace086c3fb810d9f diff --git a/misc/network_servers/vtl/test/vtl_harness.cc b/misc/network_servers/vtl/test/vtl_harness.cc new file mode 100755 index 0000000..6125b45 --- /dev/null +++ b/misc/network_servers/vtl/test/vtl_harness.cc @@ -0,0 +1,633 @@ +#include +#include +#ifdef linux +#include +#include +#include +#endif + +#include "vtl_harness.h" + +DEBUG_DECLARE(); + + +#define F_NONE 0 +#define F_LOCAL_ACK 1 + +unsigned short g_fflags; + + +int g_do_local_ack = 0; +/* IP Address utility functions */ + + + +/* Global Pipe Descriptors */ +int vtp_in_fd, vtp_out_fd; + + +/* Connection List Handling */ +struct VTP_CON g_vtp_cons[MAX_VTP_CONS]; +int g_first_vtp; +int g_last_vtp; +int g_num_vtp_cons; + +int add_vtp_con(RawEthernetPacket * pkt, unsigned long seq_num); +int find_vtp_con(RawEthernetPacket * pkt); +int find_remote_vtp_con(RawEthernetPacket * pkt); + +/* Packet Handlers */ +int handle_fifo_pkt(RawEthernetPacket * pkt, struct in_addr server_addr); +int handle_tcp_pkt(RawEthernetPacket * pkt, struct in_addr server_addr); +int handle_rem_tcp_pkt(RawEthernetPacket * pkt); +int handle_control_pkt(RawEthernetPacket * pkt, struct in_addr server_addr); +int handle_config_pkt(RawEthernetPacket * pkt); + +/* Packet functions */ +int make_ack_pkt(RawEthernetPacket * pkt, int vcon_i); +int init_ack_template(RawEthernetPacket * pkt); + + +int main(int argc, char ** argv) { + + fd_set all_set, rset; + int maxfd = 0; + int conns; + timeval timeout; + timeval * tm_ptr; + RawEthernetPacket pkt; + RawEthernetPacket * recv_pkts; + int vtp_socket; + int i = 0; + + debug_init("/tmp/vtp.1"); + + JRLDBG("Starting VTP Daemon\n"); + + for (i = 0; i < MAX_VTP_CONS; i++) { + g_vtp_cons[i].rem_seq_num = 0; + g_vtp_cons[i].dest_ip = 0; + g_vtp_cons[i].src_ip = 0; + g_vtp_cons[i].src_port = 0; + g_vtp_cons[i].dest_port = 0; + g_vtp_cons[i].tcp_timestamp = 0; + g_vtp_cons[i].in_use = false; + g_vtp_cons[i].next = -1; + g_vtp_cons[i].prev = -1; + } + + g_last_vtp = -1; + g_first_vtp = -1; + + g_num_vtp_cons = 0; + + vtp_in_fd = open(VTP_FIFO_RECVFILE, O_WRONLY); + JRLDBG("Opened RECVFILE pipe\n"); + + vtp_out_fd = open(VTP_FIFO_SENDFILE, O_RDONLY); + JRLDBG("Opened SENDFILE pipe\n"); + + + if ((vtp_socket = vtp_init()) < 0) { + JRLDBG("VTP Transport Layer failed to initialize\n"); + exit(-1); + } + + FD_ZERO(&all_set); + FD_SET(vtp_out_fd, &all_set); + + if (vtp_socket > 0) { + FD_SET(vtp_socket, &all_set); + + maxfd = (vtp_out_fd > vtp_socket) ? vtp_out_fd : vtp_socket ; + + // block indefinately, because we have all the socks in the FDSET + tm_ptr = NULL; + } else { + timeout.tv_sec = 0; + timeout.tv_usec = 0; + + tm_ptr = &timeout; + } + + + while(1) { + int n_pkts_recvd = 0; + rset = all_set; + + conns = select(maxfd + 1, &rset, NULL, NULL, tm_ptr); + if ((conns > 0) && (FD_ISSET(vtp_out_fd, &rset))) { + struct in_addr server_addr; + JRLDBG("Reception on vtp_out_fd\n"); + // we got a packet on the FIFO + if (pkt.VtpUnserialize(vtp_out_fd, &server_addr) <= 0) { + JRLDBG("VNET Connection has closed. We are exiting\n"); + exit(0); + } + handle_fifo_pkt(&pkt, server_addr); + } + + //JRLDBG("Calling VTP Receive routine\n"); + if ((vtp_socket == 0) || ((conns > 0) && (vtp_socket > 0) && FD_ISSET(vtp_socket, &rset))) { + if ((n_pkts_recvd = vtp_recv(&recv_pkts)) > 0) { + int i = 0; + struct in_addr tmp; + JRLDBG("Receive returned %d packets\n", n_pkts_recvd); + + for (i = 0; i < n_pkts_recvd; i++) { + + if (is_tcp_pkt(&(recv_pkts[i])) == 1) { + JRLDBG("Received a TCP packet\n"); + if (g_do_local_ack == 1) { + handle_rem_tcp_pkt(&(recv_pkts[i])); + } + } + + JRLDBG("Serializing packet %d to VNET\n", i); + recv_pkts[i].VtpSerialize(vtp_in_fd, &tmp); + usleep(50000); + } + + //delete recv_pkts; + } + } + } + + fclose(logfile); + close(vtp_in_fd); + close(vtp_out_fd); + + return(0); +} + +int handle_fifo_pkt(RawEthernetPacket * pkt, struct in_addr server_addr) { + JRLDBG("Received a packet\n"); + // if (strncmp(pkt->type,"et",2) == 0) { + if ((pkt->type[0] == 'e') && (pkt->type[1] == 't')) { + JRLDBG("Packet is Ethernet\n"); + if (is_tcp_pkt(pkt) == 0) { + JRLDBG("Packet is a non-TCP Packet\n"); + vtp_send(pkt, server_addr); + } else { + JRLDBG("Packet is a TCP Packet\n"); + handle_tcp_pkt(pkt, server_addr); + } + + } else if (strncmp(pkt->type,"lc",2) == 0) { + JRLDBG("Packet is a Link Control Packet\n"); + handle_control_pkt(pkt, server_addr); + } else if (strncmp(pkt->type, "cf", 2) == 0) { + JRLDBG("Packet is a Configuration packet\n"); + handle_config_pkt(pkt); + } + return 0; +} + + +int handle_config_pkt(RawEthernetPacket * pkt) { + + return 0; +} + + +int handle_control_pkt(RawEthernetPacket* pkt, struct in_addr server_addr) { + if (strncmp(pkt->data,"con",3) == 0) { + struct in_addr con_addr; + unsigned short con_port = 0; + unsigned int offset = 3; +#ifdef DEBUG + char ip[256]; + do_binary_to_string((unsigned char*)(&server_addr),ip); + JRLDBG("Control Message: Connect to %s\n", ip); +#endif + memcpy(&con_addr, pkt->data + offset,sizeof(struct in_addr)); + offset += sizeof(struct in_addr); + con_port = *((unsigned short *)(pkt->data + offset)); + + vtp_connect(con_addr, con_port); + } else if (strncmp(pkt->data, "gwc", 3) == 0) { + struct in_addr con_addr; + unsigned short con_port; + unsigned int offset = 3; + + memcpy(&con_addr, pkt->data + offset, sizeof(struct in_addr)); + offset += sizeof(struct in_addr); + con_port = *((unsigned short *)(pkt->data + offset)); + + vtp_connect(con_addr, con_port); + + } else if (strncmp(pkt->data, "stop", 4) == 0) { + exit(0); + } + + return 0; +} + + +int handle_tcp_pkt(RawEthernetPacket *pkt, struct in_addr server_addr) { + + if (g_do_local_ack == 1) { + unsigned short ip_pkt_len = 0; + // unsigned char ip_hdr_len = (*(pkt->data + ETH_HDR_LEN) & 0x0f) << 2; + unsigned char ip_hdr_len = IP_HDR_LEN(pkt->data); + unsigned short * ip_pkt_len_ptr = (unsigned short *)(pkt->data + ETH_HDR_LEN + 2); + ip_pkt_len = ntohs(*ip_pkt_len_ptr); + + JRLDBG("IP Header Length = %d(%x)\n", ip_hdr_len, *(pkt->data + ETH_HDR_LEN)); + JRLDBG("IP Packet Length = %hu\n", ip_pkt_len); + + if (is_syn_pkt(pkt) == 0) { + // we don't mess with connection establishment + int vcon_i; + unsigned long payload_len = 0; + unsigned short tcp_hdr_len = 0; + struct in_addr tmp; + + + tcp_hdr_len = (*(pkt->data + ETH_HDR_LEN + ip_hdr_len + 12) & 0xf0) >> 2; + payload_len = ip_pkt_len - (ip_hdr_len + tcp_hdr_len); + + if ((payload_len == 0) && (is_ack_pkt(pkt) == 1)) { + // we just kill empty acks. + //return 0; + } + + vcon_i = find_remote_vtp_con(pkt); + + // Create ACK and send it. + make_ack_pkt(pkt, vcon_i); + + g_vtp_cons[vcon_i].ack_template.VtpSerialize(vtp_in_fd, &tmp); + + } else { + if(is_ack_pkt(pkt) == 1) { + int vcon_i = find_remote_vtp_con(pkt); + struct in_addr tmp; + make_ack_pkt(pkt, vcon_i); + + g_vtp_cons[vcon_i].ack_template.VtpSerialize(vtp_in_fd, &tmp); + } +#ifdef DEBUG + unsigned long * seq_num_ptr ; + unsigned long seq_num = 0; + unsigned long payload_len = 0; + unsigned short tcp_hdr_len = 0; + unsigned long ack = 0; + + JRLDBG("Packet is a Syn Packet\n"); + + seq_num_ptr = (unsigned long *)(pkt->data + ETH_HDR_LEN + ip_hdr_len + 4); + seq_num = ntohl(*seq_num_ptr); + JRLDBG("Sequence Number = %lu\n", seq_num); + + tcp_hdr_len = (*(pkt->data + ETH_HDR_LEN + ip_hdr_len + 12) & 0xf0) >> 2; + payload_len = ip_pkt_len - (ip_hdr_len + tcp_hdr_len); + + JRLDBG("TCP Header Length = %hu\n", tcp_hdr_len); + JRLDBG("Payload Length = %lu\n", payload_len); + + + + ack = (payload_len > 0) ? (seq_num + payload_len) : (seq_num + 1); + JRLDBG("Ack Num = %lu\n", ack); +#endif + } + + } + + vtp_send(pkt, server_addr); + + return 0; +} + +int handle_rem_tcp_pkt(RawEthernetPacket * pkt) { + unsigned long * seq_num_ptr; + unsigned long seq_num; + unsigned char ip_hdr_len = IP_HDR_LEN(pkt->data); + + seq_num_ptr = (unsigned long *)(pkt->data + ETH_HDR_LEN + ip_hdr_len + 4); + seq_num = ntohl(*seq_num_ptr); + JRLDBG("Received Packet, SeqNum = %lu\n", seq_num); + + if (is_syn_pkt(pkt) == 1) { + // syn packet + seq_num++; + add_vtp_con(pkt, seq_num); + JRLDBG("Received Syn Packet, SeqNum = %lu\n", seq_num); + } else { + unsigned short ip_pkt_len = 0; + unsigned short * ip_pkt_len_ptr = (unsigned short *)(pkt->data + ETH_HDR_LEN + 2); + unsigned long payload_len = 0; + unsigned short tcp_hdr_len = 0; + int i_vcon = find_vtp_con(pkt); + + ip_pkt_len = ntohs(*ip_pkt_len_ptr); + + tcp_hdr_len = (*(pkt->data + ETH_HDR_LEN + ip_hdr_len + 12) & 0xf0) >> 2; + + if (tcp_hdr_len > 20) { + unsigned long ts = get_tcp_timestamp(pkt->data + ETH_HDR_LEN + ip_hdr_len + 20, tcp_hdr_len - 20); + JRLDBG("TCP Timestamp = %lu(%lu)\n", ts, (unsigned long)ntohl(ts)); + g_vtp_cons[i_vcon].tcp_timestamp = ts; + } + + payload_len = ip_pkt_len - (ip_hdr_len + tcp_hdr_len); + seq_num += payload_len; + JRLDBG("Received Data Packet, SeqNum = %lu\n", seq_num); + g_vtp_cons[i_vcon].rem_seq_num = seq_num; + JRLDBG("Remote Sequence Number (con: %d) = %lu\n", i_vcon, seq_num); + +#if 0 + { + int offset = 0; + unsigned short tcp_cksum = 0; + // Zero Ack Field + *(unsigned long *)(pkt->data + ETH_HDR_LEN + ip_hdr_len + 8) = 0; + + // Zero Ack Flag + offset = ETH_HDR_LEN + ip_hdr_len + 13; + *(pkt->data + offset) &= 0xef; + + // Zero TCP chksum + *(unsigned short *)(pkt->data + ETH_HDR_LEN + ip_hdr_len + 16) = 0; + + // Get TCP chksum + tcp_cksum = get_tcp_checksum(pkt, ip_pkt_len - ip_hdr_len); + + // Set TCP chksum + *(unsigned short *)(pkt->data + ETH_HDR_LEN + ip_hdr_len + 16) = tcp_cksum; + } +#endif + + + } + return 0; +} + + + +int make_ack_pkt(RawEthernetPacket * pkt, int vcon_i) { + unsigned long * seq_num_ptr ; + unsigned long seq_num = 0; + unsigned long rem_seq_num = 0; + unsigned long payload_len = 0; + unsigned short tcp_hdr_len = 0; + unsigned long ack = 0; + unsigned long local_ts = 0; + unsigned short tcp_cksum = 0; + unsigned char ip_hdr_len = IP_HDR_LEN(pkt->data); + unsigned short ip_pkt_len = *(unsigned short *)(pkt->data + ETH_HDR_LEN + 2); + RawEthernetPacket * ack_pkt = &(g_vtp_cons[vcon_i].ack_template); + unsigned short ack_ip_pkt_len = *(unsigned short *)(ack_pkt->data + ETH_HDR_LEN + 2); + unsigned char ack_ip_hdr_len = IP_HDR_LEN(ack_pkt->data); + + ip_pkt_len = ntohs(ip_pkt_len); + ack_ip_pkt_len = ntohs(ack_ip_pkt_len); + + seq_num_ptr = (unsigned long *)(pkt->data + ETH_HDR_LEN + ip_hdr_len + 4); + seq_num = ntohl(*seq_num_ptr); + JRLDBG("Sequence Number = %lu\n", seq_num); + + tcp_hdr_len = (*(pkt->data + ETH_HDR_LEN + ip_hdr_len + 12) & 0xf0) >> 2; + + if (is_syn_pkt(pkt) == 1) { + ack = seq_num + 1; + } else { + payload_len = ip_pkt_len - (ip_hdr_len + tcp_hdr_len); + + JRLDBG("TCP Header Length = %hu\n", tcp_hdr_len); + JRLDBG("Payload Length = %lu\n", payload_len); + + ack = seq_num + payload_len; + JRLDBG("Ack Num = %lu\n", ack); + } + + // Set IP id + g_vtp_cons[vcon_i].ip_id--; + *(unsigned short *)(ack_pkt->data + ETH_HDR_LEN + 4) = htons(g_vtp_cons[vcon_i].ip_id); + + // Recompute IP checksum + *(unsigned short *)(ack_pkt->data + ETH_HDR_LEN + 10) = 0; + *(unsigned short *)(ack_pkt->data + ETH_HDR_LEN + 10) = get_ip_checksum(ack_pkt); + + //return 0; + // Set Sequence Number + rem_seq_num = htonl(g_vtp_cons[vcon_i].rem_seq_num); + *(unsigned long *)(ack_pkt->data + ETH_HDR_LEN + ack_ip_hdr_len + 4) = rem_seq_num; + + // Set ACK Number + ack = htonl(ack); + *(unsigned long *)(ack_pkt->data + ETH_HDR_LEN + ack_ip_hdr_len + 8) = ack; + + // Set TCP Timestamp option + local_ts = get_tcp_timestamp(pkt->data + ETH_HDR_LEN + ack_ip_hdr_len + 20, tcp_hdr_len - 20); + + /* We use this for debugging: + * If the TCPDump trace shows timestamps with the value of '5' then they are our packets + */ + + *(unsigned long *)(ack_pkt->data + ETH_HDR_LEN + ack_ip_hdr_len + 24) = g_vtp_cons[vcon_i].tcp_timestamp; + //*(unsigned long *)(ack_pkt->data + ETH_HDR_LEN + ip_hdr_len + 24) = htonl(5); + + + *(unsigned long *)(ack_pkt->data + ETH_HDR_LEN + ack_ip_hdr_len + 28) = local_ts; + + // Zero TCP chksum + *(unsigned short *)(ack_pkt->data + ETH_HDR_LEN + ack_ip_hdr_len + 16) = 0; + + // Get TCP chksum + tcp_cksum = get_tcp_checksum(ack_pkt, ack_ip_pkt_len - ack_ip_hdr_len); + + // Set TCP chksum + *(unsigned short *)(ack_pkt->data + ETH_HDR_LEN + ack_ip_hdr_len + 16) = tcp_cksum; + + return 0; +} + + + + + +/* Connection List Handling */ + +int find_vtp_con(RawEthernetPacket * pkt) { + int index = -1; + int i = 0; + unsigned long * src_addr; + unsigned long * dest_addr; + unsigned short * src_port; + unsigned short * dest_port; + unsigned char ip_hdr_len = IP_HDR_LEN(pkt->data); + + src_addr = (unsigned long *)(pkt->data + ETH_HDR_LEN + 12); + dest_addr = (unsigned long *)(pkt->data + ETH_HDR_LEN + 16); + src_port = (unsigned short *)(pkt->data + ETH_HDR_LEN + ip_hdr_len); + dest_port = (unsigned short *)(pkt->data + ETH_HDR_LEN + ip_hdr_len + 2); + + // for (i = 0; i < MAX_CONS; i++) { + FOREACH_VTP_CON(i,g_vtp_cons) { + if ((g_vtp_cons[i].dest_ip == *dest_addr) && (g_vtp_cons[i].src_ip == *src_addr) && + (g_vtp_cons[i].dest_port = *dest_port) && (g_vtp_cons[i].src_port == *src_port)) { + index = i; + break; + } + } + return index; +} + + +/* An received packet has the header fields reversed wrt src/dest + * So we have to be able to index remote packets as well + */ +int find_remote_vtp_con(RawEthernetPacket * pkt) { + int index = -1; + int i = 0; + unsigned long * src_addr; + unsigned long * dest_addr; + unsigned short * src_port; + unsigned short * dest_port; + unsigned char ip_hdr_len = IP_HDR_LEN(pkt->data); + + src_addr = (unsigned long *)(pkt->data + ETH_HDR_LEN + 12); + dest_addr = (unsigned long *)(pkt->data + ETH_HDR_LEN + 16); + src_port = (unsigned short *)(pkt->data + ETH_HDR_LEN + ip_hdr_len); + dest_port = (unsigned short *)(pkt->data + ETH_HDR_LEN + ip_hdr_len + 2); + + // for (i = 0; i < MAX_CONS; i++) { + FOREACH_VTP_CON(i,g_vtp_cons) { + if ((g_vtp_cons[i].src_ip == *dest_addr) && (g_vtp_cons[i].dest_ip == *src_addr) && + (g_vtp_cons[i].src_port = *dest_port) && (g_vtp_cons[i].dest_port == *src_port)) { + index = i; + break; + } + } + return index; +} + + +int add_vtp_con(RawEthernetPacket * pkt, unsigned long seq_num) { + int i; + unsigned long * src_addr; + unsigned long * dest_addr; + unsigned short * src_port; + unsigned short * dest_port; + unsigned char ip_hdr_len = IP_HDR_LEN(pkt->data); + unsigned short tcp_hdr_len = (*(pkt->data + ETH_HDR_LEN + ip_hdr_len + 12) & 0xf0) >> 2; + + src_addr = (unsigned long *)(pkt->data + ETH_HDR_LEN + 12); + dest_addr = (unsigned long *)(pkt->data + ETH_HDR_LEN + 16); + src_port = (unsigned short *)(pkt->data + ETH_HDR_LEN + ip_hdr_len); + dest_port = (unsigned short *)(pkt->data + ETH_HDR_LEN + ip_hdr_len + 2); + + for (i = 0; i < MAX_VTP_CONS; i++) { + if (!(g_vtp_cons[i].in_use)) { + JRLDBG("Adding connection in slot %d\n", i); + g_vtp_cons[i].rem_seq_num = seq_num; + + // ADD PACKET CONNECTION INFO + g_vtp_cons[i].dest_ip = *dest_addr; + g_vtp_cons[i].src_ip = *src_addr; + g_vtp_cons[i].src_port = *src_port; + g_vtp_cons[i].dest_port = *dest_port; + g_vtp_cons[i].ack_template = *pkt; + g_vtp_cons[i].ip_id = ntohs(*(unsigned short *)(pkt->data + ETH_HDR_LEN + 4)); + + init_ack_template(&(g_vtp_cons[i].ack_template)); + + if (tcp_hdr_len > 20) { + unsigned long ts = get_tcp_timestamp(pkt->data + ETH_HDR_LEN + ip_hdr_len + 20, tcp_hdr_len - 20); + JRLDBG("TCP Timestamp = %lu(%lu)\n", ts, (unsigned long)ntohl(ts)); + g_vtp_cons[i].tcp_timestamp = ts; + } + + g_vtp_cons[i].in_use = true; + + if (g_first_vtp == -1) + g_first_vtp = i; + + g_vtp_cons[i].prev = g_last_vtp; + g_vtp_cons[i].next = -1; + + if (g_last_vtp != -1) { + g_vtp_cons[g_last_vtp].next = i; + } + + g_last_vtp = i; + + g_num_vtp_cons++; + return 0; + } + } + return -1; +} + + +int init_ack_template(RawEthernetPacket * pkt) { + // We assume here that the ethernet and ip headers are ok, except for ip pkt length + // TCP is mostly right because its pulled off of a syn packet + // we need to zero the data, and reset the syn flag. + + unsigned short IP_PACKET_LEN = 52; + unsigned short TCP_HEADER_LEN = 32; + unsigned char ip_hdr_len = IP_HDR_LEN(pkt->data); + unsigned short ip_pkt_len = 0; + unsigned short tcp_hdr_len = 0; + unsigned short payload_len = 0; + unsigned short * ip_pkt_len_ptr = (unsigned short *)(pkt->data + ETH_HDR_LEN + 2); + unsigned int offset = 0; + unsigned short ip_chksum = 0; + + JRLDBG("--> Initializing ACK Template <--\n"); + + ip_pkt_len = ntohs(*ip_pkt_len_ptr); + JRLDBG("ip_pkt_len = %hu\n", ip_pkt_len); + + tcp_hdr_len = (*(pkt->data + ETH_HDR_LEN + ip_hdr_len + 12) & 0xf0) >> 2; + payload_len = ip_pkt_len - (ip_hdr_len + tcp_hdr_len); + JRLDBG("tcp_hdr_len = %hu\n", tcp_hdr_len); + JRLDBG("payload_len = %hu\n", payload_len); + + // set only the ack flags + offset = ETH_HDR_LEN + ip_hdr_len + 13; + *(pkt->data + offset) |= 0x10; + *(pkt->data + offset) &= 0xd0; + + // set up tcp options + offset = ETH_HDR_LEN + ip_hdr_len + 20; + *(pkt->data + offset) = 0x01; + offset++; + *(pkt->data + offset) = 0x01; + offset++; + *(pkt->data + offset) = 0x08; + offset++; + *(pkt->data + offset) = 0x0a; + + // Set Header Lengths + // IP HEADER = 20 (same) + // IP PACKET LEN = 52 + // TCP Header len = 32 + + ip_pkt_len = htons(IP_PACKET_LEN); + memcpy(pkt->data + ETH_HDR_LEN + 2, &ip_pkt_len, 2); + tcp_hdr_len = (TCP_HEADER_LEN << 2); + *(pkt->data + ETH_HDR_LEN + ip_hdr_len + 12) &= 0x0f; + *(pkt->data + ETH_HDR_LEN + ip_hdr_len + 12) |= tcp_hdr_len; + + JRLDBG("Setting TEMPLATE TCPLEN = %2x\n", *(pkt->data + ETH_HDR_LEN +ip_hdr_len + 12)); + + // Set IP Header chksum + *(unsigned short *)(pkt->data + ETH_HDR_LEN + 10) = 0; + ip_chksum = get_ip_checksum(pkt); + *(unsigned short *)(pkt->data + ETH_HDR_LEN + 10) = ip_chksum; + + + // Set RawEthernetPacket size + pkt->set_size(IP_PACKET_LEN + ETH_HDR_LEN); + pkt->set_type("et"); + + JRLDBG("--> ACK Template Initialized <--\n"); + + + return 0; +} +