需求:Snort 同時啟用 fast 與 unsock 輸出模式,自定義 Unix Socket 傳輸內容,包含警訊訊息、來源 IP、目的 IP、埠號、時間戳。
struct in_addr:32 位 IPv4 地址容器。memcpy(dest, src, n):記憶體區塊複製。sendto(s, buf, len, flags, addr, addrlen):UDP/Unix Socket 發送,flags=0 正常模式。fwrite(ptr, size, count, stream):二進位寫入檔案/流,返回寫入區塊數。memset(ptr, val, n):記憶體區塊填充值(常用初始化)。p->ip 關鍵字搜尋 LogIpAddrs 函數,發現 GET_SRC_ADDR(p)、GET_DST_ADDR(p) 宏提取來源/目的地址。printf("SRC=%s:%d\n", inet_ntoax(GET_SRC_ADDR(p)), p->sp); 可直接印出來源 IP:Port。inet_ntoax 為 Snort 內部封裝的 inet_ntoa 變體。p->iph->ip_src、p->ip4_header->source 均儲存來源 IP。LogTimeStamp(data->log, p) 處理,同理可攔截格式化。typedef struct AlertPktTxt {
char msg[256];
char src_ip[16];
char dst_ip[16];
uint16_t src_port;
uint16_t dst_port;
time_t timestamp;
} AlertPktTxt;
unsock 輸出模組(spo_unsock.c)建立上述結構體實例。Packet *p 提取欄位填充結構體。sendto() 將結構體二進位傳送至 Unix Domain Socket。recvfrom() 解析處理。AlertPktTxt alert_pkt; snprintf(alert_pkt.msg, sizeof(alert_pkt.msg), "%s", pv->msg); inet_ntop(AF_INET, GET_SRC_ADDR(p), alert_pkt.src_ip, sizeof(alert_pkt.src_ip)); inet_ntop(AF_INET, GET_DST_ADDR(p), alert_pkt.dst_ip, sizeof(alert_pkt.dst_ip)); alert_pkt.src_port = ntohs(p->sp); alert_pkt.dst_port = ntohs(p->dp); alert_pkt.timestamp = time(NULL); sendto(unsock_fd, &alert_pkt, sizeof(alert_pkt), 0, (struct sockaddr *)&sun, sizeof(sun));
#pragma pack(1) 強制 1 字節對齊。ntohs() 轉主機序,IP 用 inet_ntop() 直接轉點分十進位字串。chmod 666 /var/run/snort_alert.sock 確保接收進程可連線。