📄 sp_respond2.c
字号:
{ if (p->tcph != NULL) { DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "%s: got RST candidate\n", MODNAME);); return 1; } return 0;}/** * Determine whether or not an ICMP Unreach response can be sent * * @param p pointer to a Snort packet structure * * @return 1 on success, 0 on failure */static INLINE int IsUNRCandidate(Packet *p){ if ((p->icmph == NULL) || (p->icmph->type == ICMP_ECHO) || (p->icmph->type == ICMP_TIMESTAMP) || (p->icmph->type == ICMP_INFO_REQUEST) || (p->icmph->type == ICMP_ADDRESS)) { DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "%s: got Unreach candidate\n", MODNAME);); return 1; } return 0;}/** * Determine if frame is IP encapsulated Ethernet * * @param p pointer to a Snort packet structure * * @return 1 on success, 0 on failure */static INLINE int IsLinkCandidate(Packet *p){ if (p->eh != NULL && ntohs(p->eh->ether_type) == ETHERNET_TYPE_IP) { DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "%s: got Link candidate\n", MODNAME);); return 1; } return 0;}/** * Generate a pool of random IP IDs at start-up. * * @param data pointer to a RESPOND2_CONFIG data structure * * @return random IP ID */static INLINE u_int16_t RandID(RESPOND2_CONFIG *conf){ if (ip_id_iterator >= (IPIDCOUNT - 1)) { rand_add(conf->randh, ip_id_pool, sizeof(u_int16_t) * IPIDCOUNT); ip_id_iterator = 0; } return *(u_int16_t *)(ip_id_pool + ip_id_iterator++);}/** * Calculate original IP TTL * * @param p pointer to a Snort packet structure * * @return calculated original TTL */static INLINE u_int8_t CalcOriginalTTL(Packet *p){ switch (p->iph->ip_ttl / 64) { case 3: return 255; case 2: return 192; case 1: return 128; default: return 64; }}/* ######## UTILITY section ######## *//** * Pre-cache TCP RST packet memory to improve response speed * * @return void function */static void PrecacheTCP(void){ EtherHdr *eth; IPHdr *iph; TCPHdr *tcp; int sz; /* allocates memory for the Ethernet header only when necessary */ sz = alignment + link_offset + IP_HDR_LEN + TCP_HDR_LEN; DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "%s: allocating %d bytes in " "PrecacheTCP().\n", MODNAME, sz);); tcp_pkt = SnortAlloc(sz); /* force alignment */ tcp_pkt += alignment; if (link_offset) { eth = (EtherHdr *)tcp_pkt; eth->ether_type = htons(ETH_TYPE_IP); } /* points to the start of the IP header */ iph = (IPHdr *)(tcp_pkt + link_offset); SET_IP_VER(iph, 4); SET_IP_HLEN(iph, (IP_HDR_LEN >> 2)); iph->ip_proto = IPPROTO_TCP; /* points to the start of the TCP header */ tcp = (TCPHdr *)(tcp_pkt + IP_HDR_LEN + link_offset); tcp->th_flags = TH_RST|TH_ACK; SET_TCP_OFFSET(tcp, (TCP_HDR_LEN >> 2)); return;}/** * Pre-cache ICMP unreachable packet memory to improve response speed * * @return void function */static void PrecacheICMP(void){ EtherHdr *eth; IPHdr *iph; ICMPHdr *icmp; int sz; /* allocates memory for the Ethernet header only when necessary * additional 68 bytes are allocated to accomodate an IP header with * options -Jeff */ sz = alignment + link_offset + IP_HDR_LEN + ICMP_LEN_MIN + 68; DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "%s: allocating %d bytes in " "PrecacheICMP().\n", MODNAME, sz);); icmp_pkt = SnortAlloc(sz); /* force alignment */ icmp_pkt += alignment; if (link_offset) { eth = (EtherHdr *)icmp_pkt; eth->ether_type = htons(ETH_TYPE_IP); } /* points to the start of the IP header */ iph = (IPHdr *)(icmp_pkt + link_offset); SET_IP_VER(iph, 4); SET_IP_HLEN(iph, (IP_HDR_LEN >> 2)); iph->ip_proto = IPPROTO_ICMP; /* points to the start of the ICMP header */ icmp = (ICMPHdr *)(icmp_pkt + IP_HDR_LEN + link_offset); icmp->type = ICMP_UNREACH; return;}/** * Generate a pool of random IP IDs at start-up. * * @param data pointer to a RESPOND2_CONFIG data structure * * @return void function */static void GenRandIPID(RESPOND2_CONFIG *conf){ if ((conf->randh = rand_open()) == NULL) FatalError("%s: Unable to open random device handle.\n", MODNAME); ip_id_pool = SnortAlloc(sizeof(u_int16_t) * IPIDCOUNT); rand_get(conf->randh, ip_id_pool, sizeof(u_int16_t) * IPIDCOUNT); return;}/** * Set link-layer offset * * @return void function */static void SetLinkInfo(void){ if (pv.respond2_link) { link_offset = ETH_HDR_LEN; alignment = 2; } else { link_offset = 0; alignment = 0; } return;}/** * Set number of responses per triggered event * * @param data pointer to a RESPOND2_CONFIG data structure * * @return void function */static void SetRespAttempts(RESPOND2_CONFIG *conf){ if (pv.respond2_attempts > 4 && pv.respond2_attempts < 21) conf->respond_attempts = pv.respond2_attempts; else conf->respond_attempts = 4; return;}/** * Set number of rows in response cache hash table * * @param data pointer to a RESPOND2_CONFIG data structure * * @return void function */static void SetRespCacheRows(RESPOND2_CONFIG *conf){ conf->rows = DEFAULT_ROWS; if (pv.respond2_rows) conf->rows = pv.respond2_rows; return;}/** * Set memcap of response cache hash table * * @param data pointer to a RESPOND2_CONFIG data structure * * @return void function */static void SetRespCacheMemcap(RESPOND2_CONFIG *conf){ conf->memcap = DEFAULT_MEMCAP; if (pv.respond2_memcap) conf->memcap = pv.respond2_memcap; return;}/* ######## HASH section ######## *//** * Initialize response cache at start-up. * * @param respcachep response cache pointer * @param data pointer to a RESPOND2_CONFIG data structure * * @return 0 on success, 1 on error */static int respcache_init(SFXHASH **cache, RESPOND2_CONFIG *conf){ if (conf->memcap <= (sizeof(time_t) + sizeof(response) + sizeof(SFXHASH_NODE))) { /* without sufficient memory to store one node, return an error */ return 1; } if (conf->rows < 1) return 1; *cache = sfxhash_new(conf->rows, sizeof(response), /* size of hash key */ sizeof(time_t), /* size of data */ conf->memcap, 1, /* auto recover nodes */ NULL, NULL, 1); /* recycle old nodes */ if (*cache == NULL) return 1; return 0;}/** * normalize response packets for a hash lookup * * @param key pointer to hash key * @param p pointer to a Snort packet structure * * @return 0 on success, 1 on error */static INLINE int respkey_make(RESPKEY *hashkey, Packet *p){ hashkey->sip = p->iph->ip_src.s_addr; hashkey->dip = p->iph->ip_dst.s_addr; hashkey->proto = p->iph->ip_proto; switch (hashkey->proto) { case IPPROTO_ICMP: hashkey->sport = p->icmph->type; hashkey->dport = p->icmph->code; break; case IPPROTO_TCP: hashkey->sport = p->tcph->th_sport; hashkey->dport = p->tcph->th_dport; break; case IPPROTO_UDP: hashkey->sport = p->udph->uh_sport; hashkey->dport = p->udph->uh_dport; break; } return 0;}/** * dampen responses if they're occuring too quickly * * @param p pointer to a Snort packet structure * * @return 0 on success, 1 on error */static INLINE int dampen_response(Packet *p){ int ret; time_t pkt_time = p->pkth->ts.tv_sec; time_t *resp_time; RESPKEY tmpkey; memset((void *)&tmpkey, 0, sizeof(response)); /* normalize the packet for a hash lookup */ respkey_make(&tmpkey, p); /* sfxhash_add uses sfxhash_find internally, optimize with this in mind * by always trying to add. If the key already exists, use its data. */ ret = sfxhash_add(respcache, (void *)&tmpkey, (void *)&pkt_time); switch(ret) { case SFXHASH_OK: ret = 0; break; case SFXHASH_NOMEM: ret = 1; break; case SFXHASH_INTABLE: resp_time = (time_t *)respcache->cnode->data; if ((pkt_time - *resp_time) < CACHETIME) { /* dampen this response because sp_respond2 observed this * response < CACHETIME seconds ago. */ DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "%s: dampening " "response\n", MODNAME);); ret = 1; } else { /* sp_respond2 has sent this response > CACHETIME seconds * ago. In this case, replace the hash data and proceed. */ ret = 0; if ((sfxhash_remove(respcache, (void *)&tmpkey)) != SFXHASH_OK) ret = 1; else if ((sfxhash_add(respcache, (void *)&tmpkey, (void *)&pkt_time)) != SFXHASH_OK) ret = 1; } break; } return ret;}#endif /* ENABLE_RESPONSE2 && !ENABLE_RESPONSE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -