diff --git a/server/fwknopd_common.h b/server/fwknopd_common.h index c89cade5..5a4103bb 100644 --- a/server/fwknopd_common.h +++ b/server/fwknopd_common.h @@ -417,9 +417,11 @@ typedef struct acc_stanza typedef struct spa_pkt_info { unsigned int packet_data_len; + unsigned int packet_proto; unsigned int packet_src_ip; unsigned int packet_dst_ip; - unsigned short packet_dest_port; + unsigned short packet_src_port; + unsigned short packet_dst_port; unsigned char packet_data[MAX_SPA_PACKET_LEN+1]; } spa_pkt_info_t; diff --git a/server/process_packet.c b/server/process_packet.c index 7da19c56..c8c692c2 100644 --- a/server/process_packet.c +++ b/server/process_packet.c @@ -53,11 +53,12 @@ process_packet(unsigned char *args, const struct pcap_pkthdr *packet_header, unsigned int ip_hdr_words; + unsigned char proto; unsigned int src_ip; unsigned int dst_ip; unsigned short src_port; - unsigned short dest_port; + unsigned short dst_port; unsigned short eth_type; @@ -136,27 +137,29 @@ process_packet(unsigned char *args, const struct pcap_pkthdr *packet_header, src_ip = iph_p->saddr; dst_ip = iph_p->daddr; - if (iph_p->protocol == IPPROTO_TCP) + proto = iph_p->protocol; + + if (proto == IPPROTO_TCP) { /* Process TCP packet */ tcph_p = (struct tcphdr*)((unsigned char*)iph_p + (ip_hdr_words << 2)); - src_port = ntohs(tcph_p->source); - dest_port = ntohs(tcph_p->dest); + src_port = ntohs(tcph_p->source); + dst_port = ntohs(tcph_p->dest); pkt_data = ((unsigned char*)(tcph_p+1))+((tcph_p->doff)<<2)-sizeof(struct tcphdr); pkt_data_len = (pkt_end-(unsigned char*)iph_p)-(pkt_data-(unsigned char*)iph_p); } - else if (iph_p->protocol == IPPROTO_UDP) + else if (proto == IPPROTO_UDP) { /* Process UDP packet */ udph_p = (struct udphdr*)((unsigned char*)iph_p + (ip_hdr_words << 2)); - src_port = ntohs(udph_p->source); - dest_port = ntohs(udph_p->dest); + src_port = ntohs(udph_p->source); + dst_port = ntohs(udph_p->dest); pkt_data = ((unsigned char*)(udph_p + 1)); pkt_data_len = (pkt_end-(unsigned char*)iph_p)-(pkt_data-(unsigned char*)iph_p); @@ -180,10 +183,12 @@ process_packet(unsigned char *args, const struct pcap_pkthdr *packet_header, /* Put the data in our 1-entry queue. */ strlcpy((char *)opts->spa_pkt.packet_data, (char *)pkt_data, pkt_data_len+1); - opts->spa_pkt.packet_data_len = pkt_data_len; - opts->spa_pkt.packet_src_ip = src_ip; - opts->spa_pkt.packet_dst_ip = dst_ip; - opts->spa_pkt.packet_dest_port = dest_port; + opts->spa_pkt.packet_data_len = pkt_data_len; + opts->spa_pkt.packet_proto = proto; + opts->spa_pkt.packet_src_ip = src_ip; + opts->spa_pkt.packet_dst_ip = dst_ip; + opts->spa_pkt.packet_src_port = src_port; + opts->spa_pkt.packet_dst_port = dst_port; return; } diff --git a/server/replay_cache.c b/server/replay_cache.c index a75f7207..6a784671 100644 --- a/server/replay_cache.c +++ b/server/replay_cache.c @@ -277,7 +277,9 @@ replay_check_file_cache(fko_srv_options_t *opts, fko_ctx_t ctx) { char *digest = NULL; char src_ip[INET_ADDRSTRLEN+1] = {0}; + char orig_src_ip[INET_ADDRSTRLEN+1] = {0}; char dst_ip[INET_ADDRSTRLEN+1] = {0}; + char created[18]; int res = 0, digest_len = 0; FILE *digest_file_cache_ptr = NULL; @@ -300,8 +302,27 @@ replay_check_file_cache(fko_srv_options_t *opts, fko_ctx_t ctx) digest_list_ptr != NULL; digest_list_ptr = digest_list_ptr->next) { if (strncmp(digest_list_ptr->cache_info.digest, digest, digest_len) == 0) { + + /* Convert the IPs to a human readable form + */ + inet_ntop(AF_INET, &(opts->spa_pkt.packet_src_ip), + src_ip, INET_ADDRSTRLEN); + inet_ntop(AF_INET, &(opts->spa_pkt.packet_src_ip), + orig_src_ip, INET_ADDRSTRLEN); + + strftime(created, 18, "%D %H:%M:%S", + localtime(&(digest_list_ptr->cache_info.created))); + /* Detected a replay attack - bail */ + log_msg(LOG_WARNING, + "Replay detected from source IP: %s\n" + " Original source IP: %s\n" + " Entry created: %s\n", + src_ip, + orig_src_ip, + created + ); return(SPA_MSG_REPLAY); } } @@ -326,8 +347,11 @@ replay_check_file_cache(fko_srv_options_t *opts, fko_ctx_t ctx) } strlcpy(digest_elm->cache_info.digest, digest, digest_len+1); - digest_elm->cache_info.src_ip = opts->spa_pkt.packet_src_ip; - digest_elm->cache_info.dst_ip = opts->spa_pkt.packet_dst_ip; + digest_elm->cache_info.proto = opts->spa_pkt.packet_proto; + digest_elm->cache_info.src_ip = opts->spa_pkt.packet_src_ip; + digest_elm->cache_info.dst_ip = opts->spa_pkt.packet_dst_ip; + digest_elm->cache_info.src_port = opts->spa_pkt.packet_src_port; + digest_elm->cache_info.dst_port = opts->spa_pkt.packet_dst_port; digest_elm->cache_info.created = time(NULL); /* First, add the digest at the head of the in-memory list @@ -348,8 +372,14 @@ replay_check_file_cache(fko_srv_options_t *opts, fko_ctx_t ctx) src_ip, INET_ADDRSTRLEN); inet_ntop(AF_INET, &(digest_elm->cache_info.dst_ip), dst_ip, INET_ADDRSTRLEN); - fprintf(digest_file_cache_ptr, "%s %s %s %d\n", - digest, src_ip, dst_ip, (int) digest_elm->cache_info.created); + fprintf(digest_file_cache_ptr, "%s %d %s %d %s %d %d\n", + digest, + digest_elm->cache_info.proto, + src_ip, + (int) digest_elm->cache_info.src_port, + dst_ip, + digest_elm->cache_info.dst_port, + (int) digest_elm->cache_info.created); fclose(digest_file_cache_ptr); diff --git a/server/replay_cache.h b/server/replay_cache.h index 1972f771..bfa278b3 100644 --- a/server/replay_cache.h +++ b/server/replay_cache.h @@ -40,6 +40,9 @@ typedef struct digest_cache_info { #if USE_FILE_CACHE char *digest; unsigned int dst_ip; + unsigned short src_port; + unsigned short dst_port; + unsigned char proto; #else time_t first_replay; time_t last_replay;