- if(hash_table[hash_result] == -1) {
-#ifdef DEBUG
- if(debug) printk(KERN_INFO RECENT_NAME ": match(): New table entry. (hr: %d,ha: %u)\n",
- hash_result, addr);
-#endif
-
- /* New item found and IPT_RECENT_SET, so we need to add it */
- location = time_info[curr_table->time_pos].position;
- hash_table[r_list[location].hash_entry] = -1;
- hash_table[hash_result] = location;
- memset(r_list[location].last_pkts,0,ip_pkt_list_tot*sizeof(u_int32_t));
- r_list[location].time_pos = curr_table->time_pos;
- r_list[location].addr = addr;
- r_list[location].ttl = ttl;
- r_list[location].last_seen = now;
- r_list[location].oldest_pkt = 1;
- r_list[location].last_pkts[0] = now;
- r_list[location].hash_entry = hash_result;
- time_info[curr_table->time_pos].time = r_list[location].last_seen;
- curr_table->time_pos = (curr_table->time_pos + 1) % ip_list_tot;
-
- ans = !info->invert;
- } else {
-#ifdef DEBUG
- if(debug) printk(KERN_INFO RECENT_NAME ": match(): Existing table entry. (hr: %d,ha: %u)\n",
- hash_result,
- addr);
-#endif
-
- /* Existing item found */
- location = hash_table[hash_result];
- /* We have a match on address, now to make sure it meets all requirements for a
- * full match. */
- if(info->check_set & IPT_RECENT_CHECK || info->check_set & IPT_RECENT_UPDATE) {
- if(!info->seconds && !info->hit_count) ans = !info->invert; else ans = info->invert;
- if(info->seconds && !info->hit_count) {
- if(time_before_eq(now,r_list[location].last_seen+info->seconds*HZ)) ans = !info->invert; else ans = info->invert;
- }
- if(info->seconds && info->hit_count) {
- for(pkt_count = 0, hits_found = 0; pkt_count < ip_pkt_list_tot; pkt_count++) {
- if(time_before_eq(now,r_list[location].last_pkts[pkt_count]+info->seconds*HZ)) hits_found++;
- }
- if(hits_found >= info->hit_count) ans = !info->invert; else ans = info->invert;
- }
- if(info->hit_count && !info->seconds) {
- for(pkt_count = 0, hits_found = 0; pkt_count < ip_pkt_list_tot; pkt_count++) {
- if(r_list[location].last_pkts[pkt_count] == 0) break;
- hits_found++;
- }
- if(hits_found >= info->hit_count) ans = !info->invert; else ans = info->invert;
- }
- }
-#ifdef DEBUG
- if(debug) {
- if(ans)
- printk(KERN_INFO RECENT_NAME ": match(): match addr: %u\n",addr);
- else
- printk(KERN_INFO RECENT_NAME ": match(): no match addr: %u\n",addr);
- }
-#endif
-
- /* If and only if we have been asked to SET, or to UPDATE (on match) do we add the
- * current timestamp to the last_seen. */
- if((info->check_set & IPT_RECENT_SET && (ans = !info->invert)) || (info->check_set & IPT_RECENT_UPDATE && ans)) {
-#ifdef DEBUG
- if(debug) printk(KERN_INFO RECENT_NAME ": match(): SET or UPDATE; updating time info.\n");
-#endif
- /* Have to update our time info */
- time_loc = r_list[location].time_pos;
- time_info[time_loc].time = now;
- time_info[time_loc].position = location;
- while((time_info[(time_loc+1) % ip_list_tot].time < time_info[time_loc].time) && ((time_loc+1) % ip_list_tot) != curr_table->time_pos) {
- time_temp = time_info[time_loc].time;
- time_info[time_loc].time = time_info[(time_loc+1)%ip_list_tot].time;
- time_info[(time_loc+1)%ip_list_tot].time = time_temp;
- time_temp = time_info[time_loc].position;
- time_info[time_loc].position = time_info[(time_loc+1)%ip_list_tot].position;
- time_info[(time_loc+1)%ip_list_tot].position = time_temp;
- r_list[time_info[time_loc].position].time_pos = time_loc;
- r_list[time_info[(time_loc+1)%ip_list_tot].position].time_pos = (time_loc+1)%ip_list_tot;
- time_loc = (time_loc+1) % ip_list_tot;
- }
- r_list[location].time_pos = time_loc;
- r_list[location].ttl = ttl;
- r_list[location].last_pkts[r_list[location].oldest_pkt] = now;
- r_list[location].oldest_pkt = ++r_list[location].oldest_pkt % ip_pkt_list_tot;
- r_list[location].last_seen = now;
- }
- /* If we have been asked to remove the entry from the list, just set it to 0 */
- if(info->check_set & IPT_RECENT_REMOVE) {
-#ifdef DEBUG
- if(debug) printk(KERN_INFO RECENT_NAME ": match(): REMOVE; clearing entry (or: %d, hr: %d).\n",orig_hash_result,hash_result);
-#endif
- /* Check if this is part of a collision chain */
- while(hash_table[(orig_hash_result+1) % ip_list_hash_size] != -1) {
- orig_hash_result++;
- if(hash_func(r_list[hash_table[orig_hash_result]].addr,ip_list_hash_size) == hash_result) {
- /* Found collision chain, how deep does this rabbit hole go? */
-#ifdef DEBUG
- if(debug) printk(KERN_INFO RECENT_NAME ": match(): REMOVE; found collision chain.\n");
-#endif
- end_collision_chain = orig_hash_result;
- }
- }
- if(end_collision_chain != -1) {
-#ifdef DEBUG
- if(debug) printk(KERN_INFO RECENT_NAME ": match(): REMOVE; part of collision chain, moving to end.\n");
-#endif
- /* Part of a collision chain, swap it with the end of the chain
- * before removing. */
- r_list[hash_table[end_collision_chain]].hash_entry = hash_result;
- temp = hash_table[end_collision_chain];
- hash_table[end_collision_chain] = hash_table[hash_result];
- hash_table[hash_result] = temp;
- time_info[r_list[hash_table[hash_result]].time_pos].position = hash_table[hash_result];
- hash_result = end_collision_chain;
- r_list[hash_table[hash_result]].hash_entry = hash_result;
- time_info[r_list[hash_table[hash_result]].time_pos].position = hash_table[hash_result];
- }
- location = hash_table[hash_result];
- hash_table[r_list[location].hash_entry] = -1;
- time_loc = r_list[location].time_pos;
- time_info[time_loc].time = 0;
- time_info[time_loc].position = location;
- while((time_info[(time_loc+1) % ip_list_tot].time < time_info[time_loc].time) && ((time_loc+1) % ip_list_tot) != curr_table->time_pos) {
- time_temp = time_info[time_loc].time;
- time_info[time_loc].time = time_info[(time_loc+1)%ip_list_tot].time;
- time_info[(time_loc+1)%ip_list_tot].time = time_temp;
- time_temp = time_info[time_loc].position;
- time_info[time_loc].position = time_info[(time_loc+1)%ip_list_tot].position;
- time_info[(time_loc+1)%ip_list_tot].position = time_temp;
- r_list[time_info[time_loc].position].time_pos = time_loc;
- r_list[time_info[(time_loc+1)%ip_list_tot].position].time_pos = (time_loc+1)%ip_list_tot;
- time_loc = (time_loc+1) % ip_list_tot;