static int Syslog_FormatIPHeaderLog(OpSyslog_Data *data, Packet *p) { unsigned int s, d, proto, ver, hlen, tos, len, id, off, ttl, csum; s=d=proto=ver=hlen=tos=len=id=off=ttl=csum=0; if(p->iph) { if(p->iph->ip_src.s_addr) s = ntohl( p->iph->ip_src.s_addr); if(p->iph->ip_dst.s_addr) d = ntohl( p->iph->ip_dst.s_addr); if(p->iph->ip_proto) proto = p->iph->ip_proto; if(IP_VER(p->iph)) ver = IP_VER(p->iph); if(IP_HLEN(p->iph)) ver = IP_HLEN(p->iph); if(p->iph->ip_tos) tos = p->iph->ip_tos; if(p->iph->ip_len) len = ntohs(p->iph->ip_len); if(p->iph->ip_id) id = ntohs(p->iph->ip_id); if(p->iph->ip_off) off = (p->iph->ip_off); if(p->iph->ip_ttl) ttl = (p->iph->ip_ttl); if(p->iph->ip_csum) ttl = htons(p->iph->ip_csum); } if( (data->format_current_pos += snprintf(data->formatBuffer,SYSLOG_MAX_QUERY_SIZE, "%u%c%u%c%u%c%u%c%u%c%u%c%u%c%u%c%u%c%u%c%u%c%u", proto,data->field_separators, s, data->field_separators, d, data->field_separators, ver, data->field_separators, hlen, data->field_separators, tos, data->field_separators, len, data->field_separators, id, data->field_separators, #if defined(WORDS_BIGENDIAN) ((off & 0xE000) >> 13),data->field_separators, htons(off & 0x1FFF),data->field_separators, #else ((off & 0x00E0) >> 5),data->field_separators, htons(off & 0xFF1F), data->field_separators, #endif ttl,data->field_separators, csum)) >= SYSLOG_MAX_QUERY_SIZE) { /* XXX */ return 1; } return OpSyslog_Concat(data); }
int InsertIPData(OpAcidDb_Data *op_data, Packet *p) { if(op_data->detail) { if(snprintf(sql_buffer, MAX_QUERY_SIZE, "INSERT INTO iphdr(sid, cid, ip_src, ip_dst, ip_proto, " "ip_ver, ip_hlen, ip_tos, ip_len, ip_id, ip_flags, ip_off, " "ip_ttl, ip_csum) VALUES('%u', '%u', '%u', '%u', '%u', " "'%u', '%u', '%u', '%u', '%u', '%u', '%u', " "'%u', '%u')", op_data->sensor_id, op_data->event_id, ntohl(p->iph->ip_src.s_addr), ntohl(p->iph->ip_dst.s_addr), p->iph->ip_proto, IP_VER(p->iph), IP_HLEN(p->iph), p->iph->ip_tos, ntohs(p->iph->ip_len), ntohs(p->iph->ip_id), #if defined(WORDS_BIGENDIAN) ((p->iph->ip_off & 0xE000) >> 13), htons(p->iph->ip_off & 0x1FFF), #else ((p->iph->ip_off & 0x00E0) >> 5), htons(p->iph->ip_off & 0xFF1F), #endif p->iph->ip_ttl, htons(p->iph->ip_csum)) < MAX_QUERY_SIZE) { Insert(op_data, sql_buffer, NULL); /* XXX: Error Checking */ } /* XXX: IP Options not handled */ } else { if(snprintf(sql_buffer, MAX_QUERY_SIZE,
void print_packet(const struct sniff_ethernet *eth, const struct sniff_ip *ip, const struct sniff_tcp *tcp) { /* Ethernet */ printf("DADDR:"); print_ethernet_addr(eth->dest_host); printf("SADDR:"); print_ethernet_addr(eth->src_host); printf("TYPE:%u\n", eth->ether_type); /* IP */ printf( "\tVERSION: %u\n" "\tHEADER LENGTH: %u\n" "\tTOTAL LENGTH: %u\n" "\tTOS: %u\n" "\tTTL: %u\n", IP_VER(ip), IP_HL(ip), ip->ip_len, ip->ip_tos, ip->ip_ttl); /* TCP */ printf( "\t\tSPORT: %u\n" "\t\tDPORT: %u\n" "\t\tSEQ: %u\n" "\t\tACK: %u\n", ntohs(tcp->th_sport), ntohs(tcp->th_dport), tcp->th_seq, tcp->th_ack); }
bool dhd_tcpdata_info_get(dhd_pub_t *dhdp, void *pkt) { uint8 *ether_hdr; /* Ethernet header of the new packet */ uint16 ether_type; /* Ethernet type of the new packet */ uint8 *ip_hdr; /* IP header of the new packet */ uint8 *tcp_hdr; /* TCP header of the new packet */ uint32 ip_hdr_len; /* IP header length of the new packet */ uint32 cur_framelen; uint16 ip_total_len; /* Total length of IP packet for the new packet */ uint32 tcp_hdr_len; /* TCP header length of the new packet */ uint32 tcp_seq_num; /* TCP sequence number of the new packet */ uint16 tcp_data_len; /* TCP DATA length that excludes IP and TCP headers */ uint32 end_tcp_seq_num; /* TCP seq number of the last byte in the new packet */ tcpack_sup_module_t *tcpack_sup_mod; tcpdata_info_t *tcpdata_info = NULL; tdata_psh_info_t *tdata_psh_info; int i; bool ret = FALSE; if (dhdp->tcpack_sup_mode != TCPACK_SUP_DELAYTX) goto exit; ether_hdr = PKTDATA(dhdp->osh, pkt); cur_framelen = PKTLEN(dhdp->osh, pkt); ether_type = ether_hdr[12] << 8 | ether_hdr[13]; if (ether_type != ETHER_TYPE_IP) { DHD_TRACE(("%s %d: Not a IP packet 0x%x\n", __FUNCTION__, __LINE__, ether_type)); goto exit; } DHD_TRACE(("%s %d: IP pkt! 0x%x\n", __FUNCTION__, __LINE__, ether_type)); ip_hdr = ether_hdr + ETHER_HDR_LEN; cur_framelen -= ETHER_HDR_LEN; ASSERT(cur_framelen >= IPV4_MIN_HEADER_LEN); ip_hdr_len = IPV4_HLEN(ip_hdr); if (IP_VER(ip_hdr) != IP_VER_4 || IPV4_PROT(ip_hdr) != IP_PROT_TCP) { DHD_TRACE(("%s %d: Not IPv4 nor TCP! ip ver %d, prot %d\n", __FUNCTION__, __LINE__, IP_VER(ip_hdr), IPV4_PROT(ip_hdr))); goto exit; } tcp_hdr = ip_hdr + ip_hdr_len; cur_framelen -= ip_hdr_len; ASSERT(cur_framelen >= TCP_MIN_HEADER_LEN); DHD_TRACE(("%s %d: TCP pkt!\n", __FUNCTION__, __LINE__)); ip_total_len = ntoh16_ua(&ip_hdr[IPV4_PKTLEN_OFFSET]); tcp_hdr_len = 4 * TCP_HDRLEN(tcp_hdr[TCP_HLEN_OFFSET]); /* This packet is mere TCP ACK, so do nothing */ if (ip_total_len == ip_hdr_len + tcp_hdr_len) { DHD_TRACE(("%s %d: Do nothing for no data TCP ACK\n", __FUNCTION__, __LINE__)); goto exit; } ASSERT(ip_total_len > ip_hdr_len + tcp_hdr_len); if ((tcp_hdr[TCP_FLAGS_OFFSET] & TCP_FLAG_PSH) == 0) { DHD_TRACE(("%s %d: Not interested TCP DATA packet\n", __FUNCTION__, __LINE__)); goto exit; } DHD_TRACE(("%s %d: TCP DATA with nonzero DATA length" " IP addr "IPV4_ADDR_STR" "IPV4_ADDR_STR" TCP port %d %d, flag 0x%x\n", __FUNCTION__, __LINE__, IPV4_ADDR_TO_STR(ntoh32_ua(&ip_hdr[IPV4_SRC_IP_OFFSET])), IPV4_ADDR_TO_STR(ntoh32_ua(&ip_hdr[IPV4_DEST_IP_OFFSET])), ntoh16_ua(&tcp_hdr[TCP_SRC_PORT_OFFSET]), ntoh16_ua(&tcp_hdr[TCP_DEST_PORT_OFFSET]), tcp_hdr[TCP_FLAGS_OFFSET])); dhd_os_tcpacklock(dhdp); tcpack_sup_mod = dhdp->tcpack_sup_module; if (!tcpack_sup_mod) { DHD_ERROR(("%s %d: tcpack suppress module NULL!!\n", __FUNCTION__, __LINE__)); ret = BCME_ERROR; dhd_os_tcpackunlock(dhdp); goto exit; } /* Look for tcpdata_info that has the same ip src/dst addrs and tcp src/dst ports */ i = 0; while (i < tcpack_sup_mod->tcpdata_info_cnt) { tcpdata_info_t *tdata_info_tmp = &tcpack_sup_mod->tcpdata_info_tbl[i]; uint32 now_in_ms = OSL_SYSUPTIME(); DHD_TRACE(("%s %d: data info[%d], IP addr "IPV4_ADDR_STR" "IPV4_ADDR_STR " TCP port %d %d\n", __FUNCTION__, __LINE__, i, IPV4_ADDR_TO_STR(ntoh32_ua(tdata_info_tmp->src_ip_addr)), IPV4_ADDR_TO_STR(ntoh32_ua(tdata_info_tmp->dst_ip_addr)), ntoh16_ua(tdata_info_tmp->src_tcp_port), ntoh16_ua(tdata_info_tmp->dst_tcp_port))); /* If both IP address and TCP port number match, we found it so break. */ if (memcmp(&ip_hdr[IPV4_SRC_IP_OFFSET], tdata_info_tmp->src_ip_addr, IPV4_ADDR_LEN * 2) == 0 && memcmp(&tcp_hdr[TCP_SRC_PORT_OFFSET], tdata_info_tmp->src_tcp_port, TCP_PORT_LEN * 2) == 0) { tcpdata_info = tdata_info_tmp; tcpdata_info->last_used_time = now_in_ms; break; } if (now_in_ms - tdata_info_tmp->last_used_time > TCPDATA_INFO_TIMEOUT) { tdata_psh_info_t *tdata_psh_info_tmp; tcpdata_info_t *last_tdata_info; while ((tdata_psh_info_tmp = tdata_info_tmp->tdata_psh_info_head)) { tdata_info_tmp->tdata_psh_info_head = tdata_psh_info_tmp->next; tdata_psh_info_tmp->next = NULL; DHD_TRACE(("%s %d: Clean tdata_psh_info(end_seq %u)!\n", __FUNCTION__, __LINE__, tdata_psh_info_tmp->end_seq)); _tdata_psh_info_pool_enq(tcpack_sup_mod, tdata_psh_info_tmp); } #ifdef DHDTCPACK_SUP_DBG DHD_ERROR(("%s %d: PSH INFO ENQ %d\n", __FUNCTION__, __LINE__, tcpack_sup_mod->psh_info_enq_num)); #endif /* DHDTCPACK_SUP_DBG */ tcpack_sup_mod->tcpdata_info_cnt--; ASSERT(tcpack_sup_mod->tcpdata_info_cnt >= 0); last_tdata_info = &tcpack_sup_mod->tcpdata_info_tbl[tcpack_sup_mod->tcpdata_info_cnt]; if (i < tcpack_sup_mod->tcpdata_info_cnt) { ASSERT(last_tdata_info != tdata_info_tmp); bcopy(last_tdata_info, tdata_info_tmp, sizeof(tcpdata_info_t)); } bzero(last_tdata_info, sizeof(tcpdata_info_t)); DHD_TRACE(("%s %d: tcpdata_info(idx %d) is aged out. ttl cnt is now %d\n", __FUNCTION__, __LINE__, i, tcpack_sup_mod->tcpdata_info_cnt)); /* Don't increase "i" here, so that the prev last tcpdata_info is checked */ } else i++; } tcp_seq_num = ntoh32_ua(&tcp_hdr[TCP_SEQ_NUM_OFFSET]); tcp_data_len = ip_total_len - ip_hdr_len - tcp_hdr_len; end_tcp_seq_num = tcp_seq_num + tcp_data_len; if (tcpdata_info == NULL) { ASSERT(i == tcpack_sup_mod->tcpdata_info_cnt); if (i >= TCPDATA_INFO_MAXNUM) { DHD_TRACE(("%s %d: tcp_data_info_tbl FULL! %d %d" " IP addr "IPV4_ADDR_STR" "IPV4_ADDR_STR" TCP port %d %d\n", __FUNCTION__, __LINE__, i, tcpack_sup_mod->tcpdata_info_cnt, IPV4_ADDR_TO_STR(ntoh32_ua(&ip_hdr[IPV4_SRC_IP_OFFSET])), IPV4_ADDR_TO_STR(ntoh32_ua(&ip_hdr[IPV4_DEST_IP_OFFSET])), ntoh16_ua(&tcp_hdr[TCP_SRC_PORT_OFFSET]), ntoh16_ua(&tcp_hdr[TCP_DEST_PORT_OFFSET]))); dhd_os_tcpackunlock(dhdp); goto exit; } tcpdata_info = &tcpack_sup_mod->tcpdata_info_tbl[i]; /* No TCP flow with the same IP addr and TCP port is found * in tcp_data_info_tbl. So add this flow to the table. */ DHD_TRACE(("%s %d: Add data info to tbl[%d]: IP addr "IPV4_ADDR_STR" "IPV4_ADDR_STR " TCP port %d %d\n", __FUNCTION__, __LINE__, tcpack_sup_mod->tcpdata_info_cnt, IPV4_ADDR_TO_STR(ntoh32_ua(&ip_hdr[IPV4_SRC_IP_OFFSET])), IPV4_ADDR_TO_STR(ntoh32_ua(&ip_hdr[IPV4_DEST_IP_OFFSET])), ntoh16_ua(&tcp_hdr[TCP_SRC_PORT_OFFSET]), ntoh16_ua(&tcp_hdr[TCP_DEST_PORT_OFFSET]))); bcopy(&ip_hdr[IPV4_SRC_IP_OFFSET], tcpdata_info->src_ip_addr, IPV4_ADDR_LEN * 2); bcopy(&tcp_hdr[TCP_SRC_PORT_OFFSET], tcpdata_info->src_tcp_port, TCP_PORT_LEN * 2); tcpdata_info->last_used_time = OSL_SYSUPTIME(); tcpack_sup_mod->tcpdata_info_cnt++; } ASSERT(tcpdata_info != NULL); tdata_psh_info = _tdata_psh_info_pool_deq(tcpack_sup_mod); #ifdef DHDTCPACK_SUP_DBG DHD_TRACE(("%s %d: PSH INFO ENQ %d\n", __FUNCTION__, __LINE__, tcpack_sup_mod->psh_info_enq_num)); #endif /* DHDTCPACK_SUP_DBG */ if (tdata_psh_info == NULL) { DHD_ERROR(("%s %d: No more free tdata_psh_info!!\n", __FUNCTION__, __LINE__)); ret = BCME_ERROR; dhd_os_tcpackunlock(dhdp); goto exit; } tdata_psh_info->end_seq = end_tcp_seq_num; #if defined(DEBUG_COUNTER) && defined(DHDTCPACK_SUP_DBG) tack_tbl.cnt[4]++; #endif /* DEBUG_COUNTER && DHDTCPACK_SUP_DBG */ DHD_TRACE(("%s %d: TCP PSH DATA recvd! end seq %u\n", __FUNCTION__, __LINE__, tdata_psh_info->end_seq)); ASSERT(tdata_psh_info->next == NULL); if (tcpdata_info->tdata_psh_info_head == NULL) tcpdata_info->tdata_psh_info_head = tdata_psh_info; else { ASSERT(tcpdata_info->tdata_psh_info_tail); tcpdata_info->tdata_psh_info_tail->next = tdata_psh_info; } tcpdata_info->tdata_psh_info_tail = tdata_psh_info; dhd_os_tcpackunlock(dhdp); exit: return ret; }
bool dhd_tcpack_suppress(dhd_pub_t *dhdp, void *pkt) { uint8 *new_ether_hdr; /* Ethernet header of the new packet */ uint16 new_ether_type; /* Ethernet type of the new packet */ uint8 *new_ip_hdr; /* IP header of the new packet */ uint8 *new_tcp_hdr; /* TCP header of the new packet */ uint32 new_ip_hdr_len; /* IP header length of the new packet */ uint32 cur_framelen; uint32 new_tcp_ack_num; /* TCP acknowledge number of the new packet */ uint16 new_ip_total_len; /* Total length of IP packet for the new packet */ uint32 new_tcp_hdr_len; /* TCP header length of the new packet */ tcpack_sup_module_t *tcpack_sup_mod; tcpack_info_t *tcpack_info_tbl; int i; bool ret = FALSE; bool set_dotxinrx = TRUE; if (dhdp->tcpack_sup_mode == TCPACK_SUP_OFF) goto exit; new_ether_hdr = PKTDATA(dhdp->osh, pkt); cur_framelen = PKTLEN(dhdp->osh, pkt); if (cur_framelen < TCPACKSZMIN || cur_framelen > TCPACKSZMAX) { DHD_TRACE(("%s %d: Too short or long length %d to be TCP ACK\n", __FUNCTION__, __LINE__, cur_framelen)); goto exit; } new_ether_type = new_ether_hdr[12] << 8 | new_ether_hdr[13]; if (new_ether_type != ETHER_TYPE_IP) { DHD_TRACE(("%s %d: Not a IP packet 0x%x\n", __FUNCTION__, __LINE__, new_ether_type)); goto exit; } DHD_TRACE(("%s %d: IP pkt! 0x%x\n", __FUNCTION__, __LINE__, new_ether_type)); new_ip_hdr = new_ether_hdr + ETHER_HDR_LEN; cur_framelen -= ETHER_HDR_LEN; ASSERT(cur_framelen >= IPV4_MIN_HEADER_LEN); new_ip_hdr_len = IPV4_HLEN(new_ip_hdr); if (IP_VER(new_ip_hdr) != IP_VER_4 || IPV4_PROT(new_ip_hdr) != IP_PROT_TCP) { DHD_TRACE(("%s %d: Not IPv4 nor TCP! ip ver %d, prot %d\n", __FUNCTION__, __LINE__, IP_VER(new_ip_hdr), IPV4_PROT(new_ip_hdr))); goto exit; } new_tcp_hdr = new_ip_hdr + new_ip_hdr_len; cur_framelen -= new_ip_hdr_len; ASSERT(cur_framelen >= TCP_MIN_HEADER_LEN); DHD_TRACE(("%s %d: TCP pkt!\n", __FUNCTION__, __LINE__)); /* is it an ack ? Allow only ACK flag, not to suppress others. */ if (new_tcp_hdr[TCP_FLAGS_OFFSET] != TCP_FLAG_ACK) { DHD_TRACE(("%s %d: Do not touch TCP flag 0x%x\n", __FUNCTION__, __LINE__, new_tcp_hdr[TCP_FLAGS_OFFSET])); goto exit; } new_ip_total_len = ntoh16_ua(&new_ip_hdr[IPV4_PKTLEN_OFFSET]); new_tcp_hdr_len = 4 * TCP_HDRLEN(new_tcp_hdr[TCP_HLEN_OFFSET]); /* This packet has TCP data, so just send */ if (new_ip_total_len > new_ip_hdr_len + new_tcp_hdr_len) { DHD_TRACE(("%s %d: Do nothing for TCP DATA\n", __FUNCTION__, __LINE__)); goto exit; } ASSERT(new_ip_total_len == new_ip_hdr_len + new_tcp_hdr_len); new_tcp_ack_num = ntoh32_ua(&new_tcp_hdr[TCP_ACK_NUM_OFFSET]); DHD_TRACE(("%s %d: TCP ACK with zero DATA length" " IP addr "IPV4_ADDR_STR" "IPV4_ADDR_STR" TCP port %d %d\n", __FUNCTION__, __LINE__, IPV4_ADDR_TO_STR(ntoh32_ua(&new_ip_hdr[IPV4_SRC_IP_OFFSET])), IPV4_ADDR_TO_STR(ntoh32_ua(&new_ip_hdr[IPV4_DEST_IP_OFFSET])), ntoh16_ua(&new_tcp_hdr[TCP_SRC_PORT_OFFSET]), ntoh16_ua(&new_tcp_hdr[TCP_DEST_PORT_OFFSET]))); /* Look for tcp_ack_info that has the same ip src/dst addrs and tcp src/dst ports */ dhd_os_tcpacklock(dhdp); #if defined(DEBUG_COUNTER) && defined(DHDTCPACK_SUP_DBG) counter_printlog(&tack_tbl); tack_tbl.cnt[0]++; #endif /* DEBUG_COUNTER && DHDTCPACK_SUP_DBG */ tcpack_sup_mod = dhdp->tcpack_sup_module; tcpack_info_tbl = tcpack_sup_mod->tcpack_info_tbl; if (!tcpack_sup_mod) { DHD_ERROR(("%s %d: tcpack suppress module NULL!!\n", __FUNCTION__, __LINE__)); ret = BCME_ERROR; dhd_os_tcpackunlock(dhdp); goto exit; } if (dhd_tcpdata_psh_acked(dhdp, new_ip_hdr, new_tcp_hdr, new_tcp_ack_num)) { /* This TCPACK is ACK to TCPDATA PSH pkt, so keep set_dotxinrx TRUE */ #if defined(DEBUG_COUNTER) && defined(DHDTCPACK_SUP_DBG) tack_tbl.cnt[5]++; #endif /* DEBUG_COUNTER && DHDTCPACK_SUP_DBG */ } else set_dotxinrx = FALSE; for (i = 0; i < tcpack_sup_mod->tcpack_info_cnt; i++) { void *oldpkt; /* TCPACK packet that is already in txq or DelayQ */ uint8 *old_ether_hdr, *old_ip_hdr, *old_tcp_hdr; uint32 old_ip_hdr_len, old_tcp_hdr_len; uint32 old_tcpack_num; /* TCP ACK number of old TCPACK packet in Q */ if ((oldpkt = tcpack_info_tbl[i].pkt_in_q) == NULL) { DHD_ERROR(("%s %d: Unexpected error!! cur idx %d, ttl cnt %d\n", __FUNCTION__, __LINE__, i, tcpack_sup_mod->tcpack_info_cnt)); break; } if (PKTDATA(dhdp->osh, oldpkt) == NULL) { DHD_ERROR(("%s %d: oldpkt data NULL!! cur idx %d, ttl cnt %d\n", __FUNCTION__, __LINE__, i, tcpack_sup_mod->tcpack_info_cnt)); break; } old_ether_hdr = tcpack_info_tbl[i].pkt_ether_hdr; old_ip_hdr = old_ether_hdr + ETHER_HDR_LEN; old_ip_hdr_len = IPV4_HLEN(old_ip_hdr); old_tcp_hdr = old_ip_hdr + old_ip_hdr_len; old_tcp_hdr_len = 4 * TCP_HDRLEN(old_tcp_hdr[TCP_HLEN_OFFSET]); DHD_TRACE(("%s %d: oldpkt %p[%d], IP addr "IPV4_ADDR_STR" "IPV4_ADDR_STR " TCP port %d %d\n", __FUNCTION__, __LINE__, oldpkt, i, IPV4_ADDR_TO_STR(ntoh32_ua(&old_ip_hdr[IPV4_SRC_IP_OFFSET])), IPV4_ADDR_TO_STR(ntoh32_ua(&old_ip_hdr[IPV4_DEST_IP_OFFSET])), ntoh16_ua(&old_tcp_hdr[TCP_SRC_PORT_OFFSET]), ntoh16_ua(&old_tcp_hdr[TCP_DEST_PORT_OFFSET]))); /* If either of IP address or TCP port number does not match, skip. */ if (memcmp(&new_ip_hdr[IPV4_SRC_IP_OFFSET], &old_ip_hdr[IPV4_SRC_IP_OFFSET], IPV4_ADDR_LEN * 2) || memcmp(&new_tcp_hdr[TCP_SRC_PORT_OFFSET], &old_tcp_hdr[TCP_SRC_PORT_OFFSET], TCP_PORT_LEN * 2)) continue; old_tcpack_num = ntoh32_ua(&old_tcp_hdr[TCP_ACK_NUM_OFFSET]); if (IS_TCPSEQ_GT(new_tcp_ack_num, old_tcpack_num)) { /* New packet has higher TCP ACK number, so it replaces the old packet */ if (new_ip_hdr_len == old_ip_hdr_len && new_tcp_hdr_len == old_tcp_hdr_len) { ASSERT(memcmp(new_ether_hdr, old_ether_hdr, ETHER_HDR_LEN) == 0); bcopy(new_ip_hdr, old_ip_hdr, new_ip_total_len); PKTFREE(dhdp->osh, pkt, FALSE); DHD_TRACE(("%s %d: TCP ACK replace %u -> %u\n", __FUNCTION__, __LINE__, old_tcpack_num, new_tcp_ack_num)); #if defined(DEBUG_COUNTER) && defined(DHDTCPACK_SUP_DBG) tack_tbl.cnt[2]++; #endif /* DEBUG_COUNTER && DHDTCPACK_SUP_DBG */ ret = TRUE; } else { #if defined(DEBUG_COUNTER) && defined(DHDTCPACK_SUP_DBG) tack_tbl.cnt[6]++; #endif /* DEBUG_COUNTER && DHDTCPACK_SUP_DBG */ DHD_TRACE(("%s %d: lenth mismatch %d != %d || %d != %d" " ACK %u -> %u\n", __FUNCTION__, __LINE__, new_ip_hdr_len, old_ip_hdr_len, new_tcp_hdr_len, old_tcp_hdr_len, old_tcpack_num, new_tcp_ack_num)); } } else if (new_tcp_ack_num == old_tcpack_num) { set_dotxinrx = TRUE; /* TCPACK retransmission */ #if defined(DEBUG_COUNTER) && defined(DHDTCPACK_SUP_DBG) tack_tbl.cnt[3]++; #endif /* DEBUG_COUNTER && DHDTCPACK_SUP_DBG */ } else { DHD_TRACE(("%s %d: ACK number reverse old %u(0x%p) new %u(0x%p)\n", __FUNCTION__, __LINE__, old_tcpack_num, oldpkt, new_tcp_ack_num, pkt)); } dhd_os_tcpackunlock(dhdp); goto exit; } if (i == tcpack_sup_mod->tcpack_info_cnt && i < TCPACK_INFO_MAXNUM) { /* No TCPACK packet with the same IP addr and TCP port is found * in tcp_ack_info_tbl. So add this packet to the table. */ DHD_TRACE(("%s %d: Add pkt 0x%p(ether_hdr 0x%p) to tbl[%d]\n", __FUNCTION__, __LINE__, pkt, new_ether_hdr, tcpack_sup_mod->tcpack_info_cnt)); tcpack_info_tbl[tcpack_sup_mod->tcpack_info_cnt].pkt_in_q = pkt; tcpack_info_tbl[tcpack_sup_mod->tcpack_info_cnt].pkt_ether_hdr = new_ether_hdr; tcpack_sup_mod->tcpack_info_cnt++; #if defined(DEBUG_COUNTER) && defined(DHDTCPACK_SUP_DBG) tack_tbl.cnt[1]++; #endif /* DEBUG_COUNTER && DHDTCPACK_SUP_DBG */ } else { ASSERT(i == tcpack_sup_mod->tcpack_info_cnt); DHD_TRACE(("%s %d: No empty tcp ack info tbl\n", __FUNCTION__, __LINE__)); } dhd_os_tcpackunlock(dhdp); exit: /* Unless TCPACK_SUP_DELAYTX, dotxinrx is alwasy TRUE, so no need to set here */ if (dhdp->tcpack_sup_mode == TCPACK_SUP_DELAYTX && set_dotxinrx) dhd_bus_set_dotxinrx(dhdp->bus, TRUE); return ret; }
pkt_frag_t pkt_frag_info(osl_t *osh, void *p) { uint8 *frame; int length; uint8 *pt; /* Pointer to type field */ uint16 ethertype; struct ipv4_hdr *iph; /* IP frame pointer */ int ipl; /* IP frame length */ uint16 iph_frag; ASSERT(osh && p); frame = PKTDATA(osh, p); length = PKTLEN(osh, p); /* Process Ethernet II or SNAP-encapsulated 802.3 frames */ if (length < ETHER_HDR_LEN) { DHD_INFO(("%s: short eth frame (%d)\n", __FUNCTION__, length)); return DHD_PKT_FRAG_NONE; } else if (ntoh16(*(uint16 *)(frame + ETHER_TYPE_OFFSET)) >= ETHER_TYPE_MIN) { /* Frame is Ethernet II */ pt = frame + ETHER_TYPE_OFFSET; } else if (length >= ETHER_HDR_LEN + SNAP_HDR_LEN + ETHER_TYPE_LEN && !bcmp(llc_snap_hdr, frame + ETHER_HDR_LEN, SNAP_HDR_LEN)) { pt = frame + ETHER_HDR_LEN + SNAP_HDR_LEN; } else { DHD_INFO(("%s: non-SNAP 802.3 frame\n", __FUNCTION__)); return DHD_PKT_FRAG_NONE; } ethertype = ntoh16(*(uint16 *)pt); /* Skip VLAN tag, if any */ if (ethertype == ETHER_TYPE_8021Q) { pt += VLAN_TAG_LEN; if (pt + ETHER_TYPE_LEN > frame + length) { DHD_INFO(("%s: short VLAN frame (%d)\n", __FUNCTION__, length)); return DHD_PKT_FRAG_NONE; } ethertype = ntoh16(*(uint16 *)pt); } if (ethertype != ETHER_TYPE_IP) { DHD_INFO(("%s: non-IP frame (ethertype 0x%x, length %d)\n", __FUNCTION__, ethertype, length)); return DHD_PKT_FRAG_NONE; } iph = (struct ipv4_hdr *)(pt + ETHER_TYPE_LEN); ipl = (uint)(length - (pt + ETHER_TYPE_LEN - frame)); /* We support IPv4 only */ if ((ipl < IPV4_OPTIONS_OFFSET) || (IP_VER(iph) != IP_VER_4)) { DHD_INFO(("%s: short frame (%d) or non-IPv4\n", __FUNCTION__, ipl)); return DHD_PKT_FRAG_NONE; } iph_frag = ntoh16(iph->frag); if (iph_frag & IPV4_FRAG_DONT) { return DHD_PKT_FRAG_NONE; } else if ((iph_frag & IPV4_FRAG_MORE) == 0) { return DHD_PKT_FRAG_LAST; } else { return (iph_frag & IPV4_FRAG_OFFSET_MASK)? DHD_PKT_FRAG_CONT : DHD_PKT_FRAG_FIRST; } }
static int packet_to_data(Packet *p, Event *event, idmef_alert_t *alert) { int i; if ( ! p ) return 0; add_int_data(alert, "snort_rule_sid", event->sig_id); add_int_data(alert, "snort_rule_rev", event->sig_rev); if ( p->iph ) { add_int_data(alert, "ip_ver", IP_VER(p->iph)); add_int_data(alert, "ip_hlen", IP_HLEN(p->iph)); add_int_data(alert, "ip_tos", p->iph->ip_tos); add_int_data(alert, "ip_len", ntohs(p->iph->ip_len)); add_int_data(alert, "ip_id", ntohs(p->iph->ip_id)); add_int_data(alert, "ip_off", ntohs(p->iph->ip_off)); add_int_data(alert, "ip_ttl", p->iph->ip_ttl); add_int_data(alert, "ip_proto", p->iph->ip_proto); add_int_data(alert, "ip_sum", ntohs(p->iph->ip_csum)); for ( i = 0; i < p->ip_option_count; i++ ) { add_int_data(alert, "ip_option_code", p->ip_options[i].code); add_byte_data(alert, "ip_option_data", p->ip_options[i].data, p->ip_options[i].len); } } if ( p->tcph ) { add_int_data(alert, "tcp_seq", ntohl(p->tcph->th_seq)); add_int_data(alert, "tcp_ack", ntohl(p->tcph->th_ack)); add_int_data(alert, "tcp_off", TCP_OFFSET(p->tcph)); add_int_data(alert, "tcp_res", TCP_X2(p->tcph)); add_int_data(alert, "tcp_flags", p->tcph->th_flags); add_int_data(alert, "tcp_win", ntohs(p->tcph->th_win)); add_int_data(alert, "tcp_sum", ntohs(p->tcph->th_sum)); add_int_data(alert, "tcp_urp", ntohs(p->tcph->th_urp)); for ( i = 0; i < p->tcp_option_count; i++ ) { add_int_data(alert, "tcp_option_code", p->tcp_options[i].code); add_byte_data(alert, "tcp_option_data", p->tcp_options[i].data, p->tcp_options[i].len); } } else if ( p->udph ) { add_int_data(alert, "udp_len", ntohs(p->udph->uh_len)); add_int_data(alert, "udp_sum", ntohs(p->udph->uh_chk)); } else if ( p->icmph ) { add_int_data(alert, "icmp_type", p->icmph->type); add_int_data(alert, "icmp_code", p->icmph->code); add_int_data(alert, "icmp_sum", ntohs(p->icmph->csum)); switch ( p->icmph->type ) { case ICMP_ECHO: case ICMP_ECHOREPLY: case ICMP_INFO_REQUEST: case ICMP_INFO_REPLY: case ICMP_ADDRESS: case ICMP_TIMESTAMP: add_int_data(alert, "icmp_id", ntohs(p->icmph->s_icmp_id)); add_int_data(alert, "icmp_seq", ntohs(p->icmph->s_icmp_seq)); break; case ICMP_ADDRESSREPLY: add_int_data(alert, "icmp_id", ntohs(p->icmph->s_icmp_id)); add_int_data(alert, "icmp_seq", ntohs(p->icmph->s_icmp_seq)); add_int_data(alert, "icmp_mask", (uint32_t) ntohl(p->icmph->s_icmp_mask)); break; case ICMP_REDIRECT: add_string_data(alert, "icmp_gwaddr", inet_ntoa(p->icmph->s_icmp_gwaddr)); break; case ICMP_ROUTER_ADVERTISE: add_int_data(alert, "icmp_num_addrs", p->icmph->s_icmp_num_addrs); add_int_data(alert, "icmp_wpa", p->icmph->s_icmp_wpa); add_int_data(alert, "icmp_lifetime", ntohs(p->icmph->s_icmp_lifetime)); break; case ICMP_TIMESTAMPREPLY: add_int_data(alert, "icmp_id", ntohs(p->icmph->s_icmp_id)); add_int_data(alert, "icmp_seq", ntohs(p->icmph->s_icmp_seq)); add_int_data(alert, "icmp_otime", p->icmph->s_icmp_otime); add_int_data(alert, "icmp_rtime", p->icmph->s_icmp_rtime); add_int_data(alert, "icmp_ttime", p->icmph->s_icmp_ttime); break; } } add_byte_data(alert, "payload", p->data, p->dsize); return 0; }
static int event_to_source_target(Packet *p, idmef_alert_t *alert) { int ret; idmef_node_t *node; idmef_source_t *source; idmef_target_t *target; idmef_address_t *address; idmef_service_t *service; prelude_string_t *string; static char saddr[128], daddr[128]; if ( !p ) return 0; if ( ! p->iph ) return 0; ret = idmef_alert_new_source(alert, &source, IDMEF_LIST_APPEND); if ( ret < 0 ) return ret; if ( pv.interface ) { ret = idmef_source_new_interface(source, &string); if ( ret < 0 ) return ret; prelude_string_set_ref(string, pv.interface); } ret = idmef_source_new_service(source, &service); if ( ret < 0 ) return ret; if ( p->tcph || p->udph ) idmef_service_set_port(service, p->sp); idmef_service_set_ip_version(service, IP_VER(p->iph)); idmef_service_set_iana_protocol_number(service, p->iph->ip_proto); ret = idmef_source_new_node(source, &node); if ( ret < 0 ) return ret; ret = idmef_node_new_address(node, &address, IDMEF_LIST_APPEND); if ( ret < 0 ) return ret; ret = idmef_address_new_address(address, &string); if ( ret < 0 ) return ret; SnortSnprintf(saddr, sizeof(saddr), "%s", inet_ntoa(p->iph->ip_src)); prelude_string_set_ref(string, saddr); ret = idmef_alert_new_target(alert, &target, IDMEF_LIST_APPEND); if ( ret < 0 ) return ret; if ( pv.interface ) { ret = idmef_target_new_interface(target, &string); if ( ret < 0 ) return ret; prelude_string_set_ref(string, pv.interface); } ret = idmef_target_new_service(target, &service); if ( ! ret < 0 ) return ret; if ( p->tcph || p->udph ) idmef_service_set_port(service, p->dp); idmef_service_set_ip_version(service, IP_VER(p->iph)); idmef_service_set_iana_protocol_number(service, p->iph->ip_proto); ret = idmef_target_new_node(target, &node); if ( ret < 0 ) return ret; ret = idmef_node_new_address(node, &address, IDMEF_LIST_APPEND); if ( ret < 0 ) return ret; ret = idmef_address_new_address(address, &string); if ( ret < 0 ) return ret; SnortSnprintf(daddr, sizeof(daddr), "%s", inet_ntoa(p->iph->ip_dst)); prelude_string_set_ref(string, daddr); return 0; }
void * netdev_tnl_ip_extract_tnl_md(struct dp_packet *packet, struct flow_tnl *tnl, unsigned int *hlen) { void *nh; struct ip_header *ip; struct ovs_16aligned_ip6_hdr *ip6; void *l4; int l3_size; nh = dp_packet_l3(packet); ip = nh; ip6 = nh; l4 = dp_packet_l4(packet); if (!nh || !l4) { return NULL; } *hlen = sizeof(struct eth_header); l3_size = dp_packet_size(packet) - ((char *)nh - (char *)dp_packet_data(packet)); if (IP_VER(ip->ip_ihl_ver) == 4) { ovs_be32 ip_src, ip_dst; if (csum(ip, IP_IHL(ip->ip_ihl_ver) * 4)) { VLOG_WARN_RL(&err_rl, "ip packet has invalid checksum"); return NULL; } if (ntohs(ip->ip_tot_len) > l3_size) { VLOG_WARN_RL(&err_rl, "ip packet is truncated (IP length %d, actual %d)", ntohs(ip->ip_tot_len), l3_size); return NULL; } if (IP_IHL(ip->ip_ihl_ver) * 4 > sizeof(struct ip_header)) { VLOG_WARN_RL(&err_rl, "ip options not supported on tunnel packets " "(%d bytes)", IP_IHL(ip->ip_ihl_ver) * 4); return NULL; } ip_src = get_16aligned_be32(&ip->ip_src); ip_dst = get_16aligned_be32(&ip->ip_dst); tnl->ip_src = ip_src; tnl->ip_dst = ip_dst; tnl->ip_tos = ip->ip_tos; tnl->ip_ttl = ip->ip_ttl; *hlen += IP_HEADER_LEN; } else if (IP_VER(ip->ip_ihl_ver) == 6) { ovs_be32 tc_flow = get_16aligned_be32(&ip6->ip6_flow); memcpy(tnl->ipv6_src.s6_addr, ip6->ip6_src.be16, sizeof ip6->ip6_src); memcpy(tnl->ipv6_dst.s6_addr, ip6->ip6_dst.be16, sizeof ip6->ip6_dst); tnl->ip_tos = ntohl(tc_flow) >> 20; tnl->ip_ttl = ip6->ip6_hlim; *hlen += IPV6_HEADER_LEN; } else {
bool dhd_tcpack_hold(dhd_pub_t *dhdp, void *pkt, int ifidx) { uint8 *new_ether_hdr; /* Ethernet header of the new packet */ uint16 new_ether_type; /* Ethernet type of the new packet */ uint8 *new_ip_hdr; /* IP header of the new packet */ uint8 *new_tcp_hdr; /* TCP header of the new packet */ uint32 new_ip_hdr_len; /* IP header length of the new packet */ uint32 cur_framelen; uint32 new_tcp_ack_num; /* TCP acknowledge number of the new packet */ uint16 new_ip_total_len; /* Total length of IP packet for the new packet */ uint32 new_tcp_hdr_len; /* TCP header length of the new packet */ tcpack_sup_module_t *tcpack_sup_mod; tcpack_info_t *tcpack_info_tbl; int i, free_slot = TCPACK_INFO_MAXNUM; bool hold = FALSE; unsigned long flags; if (dhdp->tcpack_sup_mode != TCPACK_SUP_HOLD) { goto exit; } if (dhdp->tcpack_sup_ratio == 1) { goto exit; } new_ether_hdr = PKTDATA(dhdp->osh, pkt); cur_framelen = PKTLEN(dhdp->osh, pkt); if (cur_framelen < TCPACKSZMIN || cur_framelen > TCPACKSZMAX) { DHD_TRACE(("%s %d: Too short or long length %d to be TCP ACK\n", __FUNCTION__, __LINE__, cur_framelen)); goto exit; } new_ether_type = new_ether_hdr[12] << 8 | new_ether_hdr[13]; if (new_ether_type != ETHER_TYPE_IP) { DHD_TRACE(("%s %d: Not a IP packet 0x%x\n", __FUNCTION__, __LINE__, new_ether_type)); goto exit; } DHD_TRACE(("%s %d: IP pkt! 0x%x\n", __FUNCTION__, __LINE__, new_ether_type)); new_ip_hdr = new_ether_hdr + ETHER_HDR_LEN; cur_framelen -= ETHER_HDR_LEN; ASSERT(cur_framelen >= IPV4_MIN_HEADER_LEN); new_ip_hdr_len = IPV4_HLEN(new_ip_hdr); if (IP_VER(new_ip_hdr) != IP_VER_4 || IPV4_PROT(new_ip_hdr) != IP_PROT_TCP) { DHD_TRACE(("%s %d: Not IPv4 nor TCP! ip ver %d, prot %d\n", __FUNCTION__, __LINE__, IP_VER(new_ip_hdr), IPV4_PROT(new_ip_hdr))); goto exit; } new_tcp_hdr = new_ip_hdr + new_ip_hdr_len; cur_framelen -= new_ip_hdr_len; ASSERT(cur_framelen >= TCP_MIN_HEADER_LEN); DHD_TRACE(("%s %d: TCP pkt!\n", __FUNCTION__, __LINE__)); /* is it an ack ? Allow only ACK flag, not to suppress others. */ if (new_tcp_hdr[TCP_FLAGS_OFFSET] != TCP_FLAG_ACK) { DHD_TRACE(("%s %d: Do not touch TCP flag 0x%x\n", __FUNCTION__, __LINE__, new_tcp_hdr[TCP_FLAGS_OFFSET])); goto exit; } new_ip_total_len = ntoh16_ua(&new_ip_hdr[IPV4_PKTLEN_OFFSET]); new_tcp_hdr_len = 4 * TCP_HDRLEN(new_tcp_hdr[TCP_HLEN_OFFSET]); /* This packet has TCP data, so just send */ if (new_ip_total_len > new_ip_hdr_len + new_tcp_hdr_len) { DHD_TRACE(("%s %d: Do nothing for TCP DATA\n", __FUNCTION__, __LINE__)); goto exit; } ASSERT(new_ip_total_len == new_ip_hdr_len + new_tcp_hdr_len); new_tcp_ack_num = ntoh32_ua(&new_tcp_hdr[TCP_ACK_NUM_OFFSET]); DHD_TRACE(("%s %d: TCP ACK with zero DATA length" " IP addr "IPV4_ADDR_STR" "IPV4_ADDR_STR" TCP port %d %d\n", __FUNCTION__, __LINE__, IPV4_ADDR_TO_STR(ntoh32_ua(&new_ip_hdr[IPV4_SRC_IP_OFFSET])), IPV4_ADDR_TO_STR(ntoh32_ua(&new_ip_hdr[IPV4_DEST_IP_OFFSET])), ntoh16_ua(&new_tcp_hdr[TCP_SRC_PORT_OFFSET]), ntoh16_ua(&new_tcp_hdr[TCP_DEST_PORT_OFFSET]))); /* Look for tcp_ack_info that has the same ip src/dst addrs and tcp src/dst ports */ flags = dhd_os_tcpacklock(dhdp); tcpack_sup_mod = dhdp->tcpack_sup_module; tcpack_info_tbl = tcpack_sup_mod->tcpack_info_tbl; if (!tcpack_sup_mod) { DHD_ERROR(("%s %d: tcpack suppress module NULL!!\n", __FUNCTION__, __LINE__)); dhd_os_tcpackunlock(dhdp, flags); goto exit; } hold = TRUE; for (i = 0; i < TCPACK_INFO_MAXNUM; i++) { void *oldpkt; /* TCPACK packet that is already in txq or DelayQ */ uint8 *old_ether_hdr, *old_ip_hdr, *old_tcp_hdr; uint32 old_ip_hdr_len, old_tcp_hdr_len; uint32 old_tcpack_num; /* TCP ACK number of old TCPACK packet in Q */ if ((oldpkt = tcpack_info_tbl[i].pkt_in_q) == NULL) { if (free_slot == TCPACK_INFO_MAXNUM) { free_slot = i; } continue; } if (PKTDATA(dhdp->osh, oldpkt) == NULL) { DHD_ERROR(("%s %d: oldpkt data NULL!! cur idx %d\n", __FUNCTION__, __LINE__, i)); hold = FALSE; dhd_os_tcpackunlock(dhdp, flags); goto exit; } old_ether_hdr = tcpack_info_tbl[i].pkt_ether_hdr; old_ip_hdr = old_ether_hdr + ETHER_HDR_LEN; old_ip_hdr_len = IPV4_HLEN(old_ip_hdr); old_tcp_hdr = old_ip_hdr + old_ip_hdr_len; old_tcp_hdr_len = 4 * TCP_HDRLEN(old_tcp_hdr[TCP_HLEN_OFFSET]); DHD_TRACE(("%s %d: oldpkt %p[%d], IP addr "IPV4_ADDR_STR" "IPV4_ADDR_STR " TCP port %d %d\n", __FUNCTION__, __LINE__, oldpkt, i, IPV4_ADDR_TO_STR(ntoh32_ua(&old_ip_hdr[IPV4_SRC_IP_OFFSET])), IPV4_ADDR_TO_STR(ntoh32_ua(&old_ip_hdr[IPV4_DEST_IP_OFFSET])), ntoh16_ua(&old_tcp_hdr[TCP_SRC_PORT_OFFSET]), ntoh16_ua(&old_tcp_hdr[TCP_DEST_PORT_OFFSET]))); /* If either of IP address or TCP port number does not match, skip. */ if (memcmp(&new_ip_hdr[IPV4_SRC_IP_OFFSET], &old_ip_hdr[IPV4_SRC_IP_OFFSET], IPV4_ADDR_LEN * 2) || memcmp(&new_tcp_hdr[TCP_SRC_PORT_OFFSET], &old_tcp_hdr[TCP_SRC_PORT_OFFSET], TCP_PORT_LEN * 2)) { continue; } old_tcpack_num = ntoh32_ua(&old_tcp_hdr[TCP_ACK_NUM_OFFSET]); if (IS_TCPSEQ_GE(new_tcp_ack_num, old_tcpack_num)) { tcpack_info_tbl[i].supp_cnt++; if (tcpack_info_tbl[i].supp_cnt >= dhdp->tcpack_sup_ratio) { tcpack_info_tbl[i].pkt_in_q = NULL; tcpack_info_tbl[i].pkt_ether_hdr = NULL; tcpack_info_tbl[i].ifidx = 0; tcpack_info_tbl[i].supp_cnt = 0; hold = FALSE; } else { tcpack_info_tbl[i].pkt_in_q = pkt; tcpack_info_tbl[i].pkt_ether_hdr = new_ether_hdr; tcpack_info_tbl[i].ifidx = ifidx; } PKTFREE(dhdp->osh, oldpkt, TRUE); } else { PKTFREE(dhdp->osh, pkt, TRUE); } dhd_os_tcpackunlock(dhdp, flags); if (!hold) { del_timer_sync(&tcpack_info_tbl[i].timer); } goto exit; } if (free_slot < TCPACK_INFO_MAXNUM) { /* No TCPACK packet with the same IP addr and TCP port is found * in tcp_ack_info_tbl. So add this packet to the table. */ DHD_TRACE(("%s %d: Add pkt 0x%p(ether_hdr 0x%p) to tbl[%d]\n", __FUNCTION__, __LINE__, pkt, new_ether_hdr, free_slot)); tcpack_info_tbl[free_slot].pkt_in_q = pkt; tcpack_info_tbl[free_slot].pkt_ether_hdr = new_ether_hdr; tcpack_info_tbl[free_slot].ifidx = ifidx; tcpack_info_tbl[free_slot].supp_cnt = 1; mod_timer(&tcpack_sup_mod->tcpack_info_tbl[free_slot].timer, jiffies + msecs_to_jiffies(dhdp->tcpack_sup_delay)); tcpack_sup_mod->tcpack_info_cnt++; } else { DHD_TRACE(("%s %d: No empty tcp ack info tbl\n", __FUNCTION__, __LINE__)); } dhd_os_tcpackunlock(dhdp, flags); exit: return hold; }
uint8_t orig_ip4_ret_ver(const Packet *p) { return IP_VER(p->orig_iph); }
uint8_t ip4_ret_ver(const Packet *p) { return IP_VER(p->iph); }
bool dhd_tcpack_suppress(dhd_pub_t *dhdp, void *pkt) { uint8 *new_ether_hdr; /* Ethernet header of the new packet */ uint16 new_ether_type; /* Ethernet type of the new packet */ uint8 *new_ip_hdr; /* IP header of the new packet */ uint8 *new_tcp_hdr; /* TCP header of the new packet */ uint32 new_ip_hdr_len; /* IP header length of the new packet */ uint32 cur_framelen; #if defined(DHD_DEBUG) uint32 new_tcp_seq_num; /* TCP sequence number of the new packet */ #endif uint32 new_tcp_ack_num; /* TCP acknowledge number of the new packet */ uint16 new_ip_total_len; /* Total length of IP packet for the new packet */ uint32 new_tcp_hdr_len; /* TCP header length of the new packet */ int i; bool ret = FALSE; if (!dhdp->tcpack_sup_enabled) goto exit; new_ether_hdr = PKTDATA(dhdp->osh, pkt); cur_framelen = PKTLEN(dhdp->osh, pkt); if (cur_framelen < TCPACKSZMIN || cur_framelen > TCPACKSZMAX) { DHD_TRACE(("%s %d: Too short or long length %d to be TCP ACK\n", __FUNCTION__, __LINE__, cur_framelen)); goto exit; } new_ether_type = new_ether_hdr[12] << 8 | new_ether_hdr[13]; if (new_ether_type != ETHER_TYPE_IP) { DHD_TRACE(("%s %d: Not a IP packet 0x%x\n", __FUNCTION__, __LINE__, new_ether_type)); goto exit; } DHD_TRACE(("%s %d: IP pkt! 0x%x\n", __FUNCTION__, __LINE__, new_ether_type)); new_ip_hdr = new_ether_hdr + ETHER_HDR_LEN; cur_framelen -= ETHER_HDR_LEN; ASSERT(cur_framelen >= IPV4_MIN_HEADER_LEN); new_ip_hdr_len = IPV4_HLEN(new_ip_hdr); if (IP_VER(new_ip_hdr) != IP_VER_4 || IPV4_PROT(new_ip_hdr) != IP_PROT_TCP) { DHD_TRACE(("%s %d: Not IPv4 nor TCP! ip ver %d, prot %d\n", __FUNCTION__, __LINE__, IP_VER(new_ip_hdr), IPV4_PROT(new_ip_hdr))); goto exit; } new_tcp_hdr = new_ip_hdr + new_ip_hdr_len; cur_framelen -= new_ip_hdr_len; ASSERT(cur_framelen >= TCP_MIN_HEADER_LEN); DHD_TRACE(("%s %d: TCP pkt!\n", __FUNCTION__, __LINE__)); /* is it an ack ? Allow only ACK flag, not to suppress others. */ if (new_tcp_hdr[TCP_FLAGS_OFFSET] != TCP_FLAG_ACK) { DHD_TRACE(("%s %d: Do not touch TCP flag 0x%x\n", __FUNCTION__, __LINE__, new_tcp_hdr[TCP_FLAGS_OFFSET])); goto exit; } new_ip_total_len = ntoh16_ua(&new_ip_hdr[IPV4_PKTLEN_OFFSET]); new_tcp_hdr_len = 4 * TCP_HDRLEN(new_tcp_hdr[TCP_HLEN_OFFSET]); /* This packet has TCP data, so just send */ if (new_ip_total_len > new_ip_hdr_len + new_tcp_hdr_len) { DHD_TRACE(("%s %d: Do nothing for TCP DATA\n", __FUNCTION__, __LINE__)); goto exit; } ASSERT(new_ip_total_len == new_ip_hdr_len + new_tcp_hdr_len); new_tcp_ack_num = ntoh32_ua(&new_tcp_hdr[TCP_ACK_NUM_OFFSET]); #if defined(DHD_DEBUG) new_tcp_seq_num = ntoh32_ua(&new_tcp_hdr[TCP_SEQ_NUM_OFFSET]); DHD_TRACE(("%s %d: TCP ACK seq %u ack %u\n", __FUNCTION__, __LINE__, new_tcp_seq_num, new_tcp_ack_num)); #endif DHD_TRACE(("%s %d: TCP ACK with zero DATA length" " IP addr "IPv4_ADDR_STR" "IPv4_ADDR_STR" TCP port %d %d\n", __FUNCTION__, __LINE__, IPv4_ADDR_TO_STR(ntoh32_ua(&new_ip_hdr[IPV4_SRC_IP_OFFSET])), IPv4_ADDR_TO_STR(ntoh32_ua(&new_ip_hdr[IPV4_DEST_IP_OFFSET])), ntoh16_ua(&new_tcp_hdr[TCP_SRC_PORT_OFFSET]), ntoh16_ua(&new_tcp_hdr[TCP_DEST_PORT_OFFSET]))); /* Look for tcp_ack_info that has the same ip src/dst addrs and tcp src/dst ports */ dhd_os_tcpacklock(dhdp); for (i = 0; i < dhdp->tcp_ack_info_cnt; i++) { void *oldpkt; /* TCPACK packet that is already in txq or DelayQ */ uint8 *old_ether_hdr, *old_ip_hdr, *old_tcp_hdr; uint32 old_ip_hdr_len, old_tcp_hdr_len; uint32 old_tcpack_num; /* TCP ACK number of old TCPACK packet in Q */ if ((oldpkt = dhdp->tcp_ack_info_tbl[i].pkt_in_q) == NULL) { DHD_ERROR(("%s %d: Unexpected error!! cur idx %d, ttl cnt %d\n", __FUNCTION__, __LINE__, i, dhdp->tcp_ack_info_cnt)); break; } if (PKTDATA(dhdp->osh, oldpkt) == NULL) { DHD_ERROR(("%s %d: oldpkt data NULL!! cur idx %d, ttl cnt %d\n", __FUNCTION__, __LINE__, i, dhdp->tcp_ack_info_cnt)); break; } old_ether_hdr = dhdp->tcp_ack_info_tbl[i].pkt_ether_hdr; old_ip_hdr = old_ether_hdr + ETHER_HDR_LEN; old_ip_hdr_len = IPV4_HLEN(old_ip_hdr); old_tcp_hdr = old_ip_hdr + old_ip_hdr_len; old_tcp_hdr_len = 4 * TCP_HDRLEN(old_tcp_hdr[TCP_HLEN_OFFSET]); DHD_TRACE(("%s %d: oldpkt %p[%d], IP addr "IPv4_ADDR_STR" "IPv4_ADDR_STR " TCP port %d %d\n", __FUNCTION__, __LINE__, oldpkt, i, IPv4_ADDR_TO_STR(ntoh32_ua(&old_ip_hdr[IPV4_SRC_IP_OFFSET])), IPv4_ADDR_TO_STR(ntoh32_ua(&old_ip_hdr[IPV4_DEST_IP_OFFSET])), ntoh16_ua(&old_tcp_hdr[TCP_SRC_PORT_OFFSET]), ntoh16_ua(&old_tcp_hdr[TCP_DEST_PORT_OFFSET]))); /* If either of IP address or TCP port number does not match, skip. */ if (memcmp(&new_ip_hdr[IPV4_SRC_IP_OFFSET], &old_ip_hdr[IPV4_SRC_IP_OFFSET], IPV4_ADDR_LEN * 2) || memcmp(&new_tcp_hdr[TCP_SRC_PORT_OFFSET], &old_tcp_hdr[TCP_SRC_PORT_OFFSET], TCP_PORT_LEN * 2)) continue; old_tcpack_num = ntoh32_ua(&old_tcp_hdr[TCP_ACK_NUM_OFFSET]); if (new_tcp_ack_num > old_tcpack_num) { /* New packet has higher TCP ACK number, so it replaces the old packet */ if (new_ip_hdr_len == old_ip_hdr_len && new_tcp_hdr_len == old_tcp_hdr_len) { ASSERT(memcmp(new_ether_hdr, old_ether_hdr, ETHER_HDR_LEN) == 0); bcopy(new_ip_hdr, old_ip_hdr, new_ip_total_len); PKTFREE(dhdp->osh, pkt, FALSE); DHD_TRACE(("%s %d: TCP ACK replace %u -> %u\n", __FUNCTION__, __LINE__, old_tcpack_num, new_tcp_ack_num)); ret = TRUE; } else DHD_TRACE(("%s %d: lenth mismatch %d != %d || %d != %d\n", __FUNCTION__, __LINE__, new_ip_hdr_len, old_ip_hdr_len, new_tcp_hdr_len, old_tcp_hdr_len)); } else { DHD_TRACE(("%s %d: ACK number reverse old %u(0x%p) new %u(0x%p)\n", __FUNCTION__, __LINE__, old_tcpack_num, oldpkt, new_tcp_ack_num, pkt)); #ifdef TCPACK_TEST if (new_ip_hdr_len == old_ip_hdr_len && new_tcp_hdr_len == old_tcp_hdr_len) { PKTFREE(dhdp->osh, pkt, FALSE); ret = TRUE; } #endif } dhd_os_tcpackunlock(dhdp); goto exit; } if (i == dhdp->tcp_ack_info_cnt && i < MAXTCPSTREAMS) { /* No TCPACK packet with the same IP addr and TCP port is found * in tcp_ack_info_tbl. So add this packet to the table. */ DHD_TRACE(("%s %d: Add pkt 0x%p(ether_hdr 0x%p) to tbl[%d]\n", __FUNCTION__, __LINE__, pkt, new_ether_hdr, dhdp->tcp_ack_info_cnt)); dhdp->tcp_ack_info_tbl[dhdp->tcp_ack_info_cnt].pkt_in_q = pkt; dhdp->tcp_ack_info_tbl[dhdp->tcp_ack_info_cnt].pkt_ether_hdr = new_ether_hdr; dhdp->tcp_ack_info_cnt++; } else { ASSERT(i == dhdp->tcp_ack_info_cnt); DHD_TRACE(("%s %d: No empty tcp ack info tbl\n", __FUNCTION__, __LINE__)); } dhd_os_tcpackunlock(dhdp); exit: return ret; }
/* sguil only uses log */ int OpSguil_Log(void *context, void *data) { char timestamp[TIMEBUF_SIZE]; char syslogMessage[SYSLOG_BUF]; char eventInfo[SYSLOG_BUF]; //int MAX_INSERT_LEN = 1024; char insertColumns[MAX_QUERY_SIZE]; char insertValues[MAX_QUERY_SIZE]; char valuesTemp[MAX_QUERY_SIZE]; char ipInfo[38]; char portInfo[16]; char *esc_message; Sid *sid = NULL; ClassType *class_type; UnifiedLogRecord *record = (UnifiedLogRecord *)data; OpSguil_Data *op_data = (OpSguil_Data *)context; Packet p; bzero(syslogMessage, SYSLOG_BUF); bzero(insertColumns, MAX_QUERY_SIZE); bzero(insertValues, MAX_QUERY_SIZE); #if 0 /* this is broken */ /* skip tagged packets, since the db does not have a mechanism to * deal with them properly */ if(record->log.event.event_reference) { LogMessage("Skipping tagged packet %i\n", record->log.event.event_reference); return 0; } #endif RenderTimestamp(record->log.pkth.ts.tv_sec, timestamp, TIMEBUF_SIZE); //fprintf(stdout, "Timestamp: %lu\n", GetMilliseconds()); //fflush(stdout); sid = GetSid(record->log.event.sig_generator, record->log.event.sig_id); if(sid == NULL) sid = FakeSid(record->log.event.sig_generator, record->log.event.sig_id); class_type = GetClassType(record->log.event.classification); //sgBeginTransaction(op_data); /* XXX: Error checking */ /* Build the event insert. */ snprintf(insertColumns, MAX_QUERY_SIZE, "INSERT INTO event (status, sid, cid, signature_id, signature_rev, signature, timestamp, priority, class"); esc_message = malloc(strlen(sid->msg)*2+1); mysql_real_escape_string(op_data->mysql, esc_message, sid->msg, strlen(sid->msg)); if(class_type == NULL) { snprintf(valuesTemp, MAX_QUERY_SIZE, "VALUES ('0', '%u', '%u', '%d', '%d', '%s', '%s', '%u', 'unknown'", op_data->sensor_id, op_data->event_id, sid->sid, sid->rev, esc_message, timestamp, record->log.event.priority); snprintf(eventInfo, SYSLOG_BUF, "RTEvent |0|%u|unknown|%s|%s|%u|%u|%s", record->log.event.priority, pv.hostname, timestamp, op_data->sensor_id, op_data->event_id, sid->msg); } else { snprintf(valuesTemp, MAX_QUERY_SIZE, "VALUES ('0', '%u', '%u', '%d', '%d', '%s', '%s', '%u', '%s'", op_data->sensor_id, op_data->event_id, sid->sid, sid->rev, esc_message, timestamp, record->log.event.priority, class_type->type); snprintf(eventInfo, SYSLOG_BUF, "RTEvent |0|%u|%s|%s|%s|%u|%u|%s", record->log.event.priority, class_type->type, pv.hostname, timestamp, op_data->sensor_id, op_data->event_id, sid->msg); } free(esc_message); insertValues[0] = '\0'; strcat(insertValues, valuesTemp); syslogMessage[0] = '\0'; strcat(syslogMessage, eventInfo); /* decode the packet */ if(DecodePacket(&p, &record->log.pkth, record->pkt + 2) == 0) { if(p.iph) { /* Insert ip header information */ //InsertIPData(op_data, &p); strcat(insertColumns, ",src_ip, dst_ip, ip_proto, ip_ver, ip_hlen, ip_tos, ip_len, ip_id, ip_flags, ip_off, ip_ttl, ip_csum"); snprintf(valuesTemp, MAX_QUERY_SIZE, ",'%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u'", ntohl(p.iph->ip_src.s_addr), ntohl(p.iph->ip_dst.s_addr), p.iph->ip_proto, IP_VER(p.iph), IP_HLEN(p.iph), p.iph->ip_tos, ntohs(p.iph->ip_len), ntohs(p.iph->ip_id), #if defined(WORDS_BIGENDIAN) ((p.iph->ip_off & 0xE000) >> 13), htons(p.iph->ip_off & 0x1FFF), #else ((p.iph->ip_off & 0x00E0) >> 5), htons(p.iph->ip_off & 0xFF1F), #endif p.iph->ip_ttl, htons(p.iph->ip_csum) < MAX_QUERY_SIZE); strcat(insertValues, valuesTemp); /* SYSLOG - Changed to SguilSendEvent*/ snprintf(ipInfo, 38, "|%u.%u.%u.%u|%u.%u.%u.%u|%u", #if defined(WORDS_BIGENDIAN) (p.iph->ip_src.s_addr & 0xff000000) >> 24, (p.iph->ip_src.s_addr & 0x00ff0000) >> 16, (p.iph->ip_src.s_addr & 0x0000ff00) >> 8, (p.iph->ip_src.s_addr & 0x000000ff), (p.iph->ip_dst.s_addr & 0xff000000) >> 24, (p.iph->ip_dst.s_addr & 0x00ff0000) >> 16, (p.iph->ip_dst.s_addr & 0x0000ff00) >> 8, (p.iph->ip_dst.s_addr & 0x000000ff), #else (p.iph->ip_src.s_addr & 0x000000ff), (p.iph->ip_src.s_addr & 0x0000ff00) >> 8, (p.iph->ip_src.s_addr & 0x00ff0000) >> 16, (p.iph->ip_src.s_addr & 0xff000000) >> 24, (p.iph->ip_dst.s_addr & 0x000000ff), (p.iph->ip_dst.s_addr & 0x0000ff00) >> 8, (p.iph->ip_dst.s_addr & 0x00ff0000) >> 16, (p.iph->ip_dst.s_addr & 0xff000000) >> 24, #endif p.iph->ip_proto); strcat(syslogMessage, ipInfo); /* store layer 4 data for non fragmented packets */ if(!(p.pkt_flags & PKT_FRAG_FLAG)) { switch(p.iph->ip_proto) { case IPPROTO_ICMP: snprintf(portInfo, 16, "|||"); if(!p.icmph) break; strcat(insertColumns, ", icmp_type, icmp_code)"); snprintf(valuesTemp, MAX_QUERY_SIZE, ", '%u', '%u')", p.icmph->icmp_type, p.icmph->icmp_code); strcat(insertValues, valuesTemp); strcat(insertColumns, insertValues); sgInsert(op_data, insertColumns, NULL); sgInsertICMPData(op_data, &p); break; case IPPROTO_TCP: strcat(insertColumns, ", src_port, dst_port)"); snprintf(valuesTemp, MAX_QUERY_SIZE, ", '%u', '%u')", p.sp, p.dp); strcat(insertValues, valuesTemp); strcat(insertColumns, insertValues); sgInsert(op_data, insertColumns, NULL); sgInsertTCPData(op_data, &p); snprintf(portInfo, 16, "|%u|%u|", p.sp, p.dp); break; case IPPROTO_UDP: strcat(insertColumns, ", src_port, dst_port)"); snprintf(valuesTemp, MAX_QUERY_SIZE, ", '%u', '%u')", p.sp, p.dp); strcat(insertValues, valuesTemp); strcat(insertColumns, insertValues); sgInsert(op_data, insertColumns, NULL); sgInsertUDPData(op_data, &p); snprintf(portInfo, 16, "|%u|%u|", p.sp, p.dp); break; } strcat(syslogMessage, portInfo); } else { strcat(syslogMessage, "|||"); } /* Insert payload data */ sgInsertPayloadData(op_data, &p); } else {