static inline int GetFlowAddresses(Flow *f, Address *ip_src, Address *ip_dst) { memset(ip_src, 0, sizeof(*ip_src)); memset(ip_dst, 0, sizeof(*ip_dst)); if (FLOW_IS_IPV4(f)) { FLOW_COPY_IPV4_ADDR_TO_PACKET(&f->src, ip_src); FLOW_COPY_IPV4_ADDR_TO_PACKET(&f->dst, ip_dst); } else if (FLOW_IS_IPV6(f)) { FLOW_COPY_IPV6_ADDR_TO_PACKET(&f->src, ip_src); FLOW_COPY_IPV6_ADDR_TO_PACKET(&f->dst, ip_dst); } else { return -1; } return 0; }
/** * \internal * \brief Pseudo packet setup for flow forced reassembly. * * \param direction Direction of the packet. 0 indicates toserver and 1 * indicates toclient. * \param f Pointer to the flow. * \param ssn Pointer to the tcp session. * \param dummy Indicates to create a dummy pseudo packet. Not all pseudo * packets need to force reassembly, in which case we just * set dummy ack/seq values. */ static inline Packet *FlowForceReassemblyPseudoPacketSetup(Packet *p, int direction, Flow *f, TcpSession *ssn, int dummy) { p->datalink = DLT_RAW; p->proto = IPPROTO_TCP; FlowReference(&p->flow, f); p->flags |= PKT_STREAM_EST; p->flags |= PKT_STREAM_EOF; p->flags |= PKT_HAS_FLOW; p->flags |= PKT_PSEUDO_STREAM_END; if (direction == 0) p->flowflags |= FLOW_PKT_TOSERVER; else p->flowflags |= FLOW_PKT_TOCLIENT; p->flowflags |= FLOW_PKT_ESTABLISHED; p->payload = NULL; p->payload_len = 0; if (FLOW_IS_IPV4(f)) { if (direction == 0) { FLOW_COPY_IPV4_ADDR_TO_PACKET(&f->src, &p->src); FLOW_COPY_IPV4_ADDR_TO_PACKET(&f->dst, &p->dst); p->sp = f->sp; p->dp = f->dp; } else { FLOW_COPY_IPV4_ADDR_TO_PACKET(&f->src, &p->dst); FLOW_COPY_IPV4_ADDR_TO_PACKET(&f->dst, &p->src); p->sp = f->dp; p->dp = f->sp; } /* set the ip header */ p->ip4h = (IPV4Hdr *)GET_PKT_DATA(p); /* version 4 and length 20 bytes for the tcp header */ p->ip4h->ip_verhl = 0x45; p->ip4h->ip_tos = 0; p->ip4h->ip_len = htons(40); p->ip4h->ip_id = 0; p->ip4h->ip_off = 0; p->ip4h->ip_ttl = 64; p->ip4h->ip_proto = IPPROTO_TCP; //p->ip4h->ip_csum = if (direction == 0) { p->ip4h->s_ip_src.s_addr = f->src.addr_data32[0]; p->ip4h->s_ip_dst.s_addr = f->dst.addr_data32[0]; } else { p->ip4h->s_ip_src.s_addr = f->dst.addr_data32[0]; p->ip4h->s_ip_dst.s_addr = f->src.addr_data32[0]; } /* set the tcp header */ p->tcph = (TCPHdr *)((uint8_t *)GET_PKT_DATA(p) + 20); SET_PKT_LEN(p, 40); /* ipv4 hdr + tcp hdr */ } else if (FLOW_IS_IPV6(f)) { if (direction == 0) { FLOW_COPY_IPV6_ADDR_TO_PACKET(&f->src, &p->src); FLOW_COPY_IPV6_ADDR_TO_PACKET(&f->dst, &p->dst); p->sp = f->sp; p->dp = f->dp; } else { FLOW_COPY_IPV6_ADDR_TO_PACKET(&f->src, &p->dst); FLOW_COPY_IPV6_ADDR_TO_PACKET(&f->dst, &p->src); p->sp = f->dp; p->dp = f->sp; } /* set the ip header */ p->ip6h = (IPV6Hdr *)GET_PKT_DATA(p); /* version 6 */ p->ip6h->s_ip6_vfc = 0x60; p->ip6h->s_ip6_flow = 0; p->ip6h->s_ip6_nxt = IPPROTO_TCP; p->ip6h->s_ip6_plen = htons(20); p->ip6h->s_ip6_hlim = 64; if (direction == 0) { p->ip6h->s_ip6_src[0] = f->src.addr_data32[0]; p->ip6h->s_ip6_src[1] = f->src.addr_data32[1]; p->ip6h->s_ip6_src[2] = f->src.addr_data32[2]; p->ip6h->s_ip6_src[3] = f->src.addr_data32[3]; p->ip6h->s_ip6_dst[0] = f->dst.addr_data32[0]; p->ip6h->s_ip6_dst[1] = f->dst.addr_data32[1]; p->ip6h->s_ip6_dst[2] = f->dst.addr_data32[2]; p->ip6h->s_ip6_dst[3] = f->dst.addr_data32[3]; } else { p->ip6h->s_ip6_src[0] = f->dst.addr_data32[0]; p->ip6h->s_ip6_src[1] = f->dst.addr_data32[1]; p->ip6h->s_ip6_src[2] = f->dst.addr_data32[2]; p->ip6h->s_ip6_src[3] = f->dst.addr_data32[3]; p->ip6h->s_ip6_dst[0] = f->src.addr_data32[0]; p->ip6h->s_ip6_dst[1] = f->src.addr_data32[1]; p->ip6h->s_ip6_dst[2] = f->src.addr_data32[2]; p->ip6h->s_ip6_dst[3] = f->src.addr_data32[3]; } /* set the tcp header */ p->tcph = (TCPHdr *)((uint8_t *)GET_PKT_DATA(p) + 40); SET_PKT_LEN(p, 60); /* ipv6 hdr + tcp hdr */ } p->tcph->th_offx2 = 0x50; p->tcph->th_flags |= TH_ACK; p->tcph->th_win = 10; p->tcph->th_urp = 0; /* to server */ if (direction == 0) { p->tcph->th_sport = htons(f->sp); p->tcph->th_dport = htons(f->dp); if (dummy) { p->tcph->th_seq = htonl(ssn->client.next_seq); p->tcph->th_ack = htonl(ssn->server.last_ack); } else { p->tcph->th_seq = htonl(ssn->client.next_seq); p->tcph->th_ack = htonl(ssn->server.seg_list_tail->seq + ssn->server.seg_list_tail->payload_len); } /* to client */ } else { p->tcph->th_sport = htons(f->dp); p->tcph->th_dport = htons(f->sp); if (dummy) { p->tcph->th_seq = htonl(ssn->server.next_seq); p->tcph->th_ack = htonl(ssn->client.last_ack); } else { p->tcph->th_seq = htonl(ssn->server.next_seq); p->tcph->th_ack = htonl(ssn->client.seg_list_tail->seq + ssn->client.seg_list_tail->payload_len); } } if (FLOW_IS_IPV4(f)) { p->tcph->th_sum = TCPCalculateChecksum(p->ip4h->s_ip_addrs, (uint16_t *)p->tcph, 20); /* calc ipv4 csum as we may log it and barnyard might reject * a wrong checksum */ p->ip4h->ip_csum = IPV4CalculateChecksum((uint16_t *)p->ip4h, IPV4_GET_RAW_HLEN(p->ip4h)); } else if (FLOW_IS_IPV6(f)) { p->tcph->th_sum = TCPCalculateChecksum(p->ip6h->s_ip6_addrs, (uint16_t *)p->tcph, 20); } memset(&p->ts, 0, sizeof(struct timeval)); TimeGet(&p->ts); AppLayerSetEOF(f); return p; }