Credit:
The information has been provided by fryxar.
Details
Snortcheck is a simple program that is useful for checking if snort (working as
NIDS) is running correctly over a Linux box.
The program works by sending an ICMP echo-request packet (even if the sniffing
interface is in stealth mode) specially prepared to generate a token alert by
using a rule that identify the combination of Origin IP / Destination IP / ICMP
echo-reply message.
By running the program periodically, its possible to check if the following
items are running correctly:
- The snort process
- The output snort plugin (for example, the delivery of automatics mails of
alerts)
- The SPAN (or mirroring) switching port.
Code:
/*
* snortcheck: Check if snort its running
* Based on etherpingtest.c
* by: Fryxar (fryxar at yahoo.com.ar)
*
*/
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <net/if.h>
#include <net/ethernet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/ip_icmp.h>
#include <netinet/if_ether.h>
#include <netpacket/packet.h>
struct addr {
uint32_t ip;
char mac[ETH_ALEN];
};
struct dev {
uint32_t index;
char name[IFNAMSIZ];
};
int send_echorequest(int, struct dev *, struct addr *, struct addr *);
int mac_aton(char *, char *);
int in_cksum(u_short *, int);
void usage(char *);
int main(int argc, char *argv[]) {
int sock = 0;
struct dev dev;
struct addr src, dst;
if (argc < 6) {
usage(argv[0]);
return -1;
}
/* device */
memset(&dev, 0, sizeof(dev));
strncpy(dev.name, argv[1], IFNAMSIZ-1);
if((dev.index = if_nametoindex(dev.name)) == 0) {
perror(argv[1]);
exit(-1);
}
/* source ip & mac */
memset(&src, 0, sizeof(src));
if (inet_aton(argv[2], (struct in_addr *)&src.ip) == 0) {
fprintf(stderr, "%s: invalid src ip address
", argv[2]);
exit(-1);
}
if (mac_aton(argv[3], src.mac) < 0) {
fprintf(stderr, "%s: invalid src hardware address
", argv[3]);
exit(-1);
}
/* destination ip & mac */
memset(&dst, 0, sizeof(dst));
if (inet_aton(argv[4], (struct in_addr *)&dst.ip) == 0) {
fprintf(stderr, "%s: invalid ip address
", argv[2]);
exit(-1);
}
if (mac_aton(argv[5], dst.mac) < 0) {
fprintf(stderr, "%s: invalid hardware address
", argv[3]);
exit(-1);
}
/* socket */
if ((sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0) {
perror("socket");
exit(-1);
}
/* send icmp echo request */
if (send_echorequest(sock, &dev, &src, &dst) < 0) {
perror("send");
exit(-1);
}
close(sock);
return 0;
}
int send_echorequest(int sock, struct dev *dev, struct addr *src, struct addr
*dst) {
struct sockaddr_ll sll;
struct ether_header *eth;
struct iphdr *ip;
struct icmphdr *icmp;
char buf[sizeof(struct ether_header) + sizeof(struct iphdr) + sizeof(struct
icmphdr)];
memset(&sll, 0, sizeof(sll));
sll.sll_family = PF_PACKET;
sll.sll_ifindex = dev->index;
sll.sll_halen = ETH_ALEN;
memcpy(&sll.sll_addr, dst->mac, ETH_ALEN);
memset(buf, 0, sizeof(buf));
eth = (struct ether_header *)buf;
ip = (struct iphdr *)((char *)eth + sizeof(struct ether_header));
icmp = (struct icmphdr *)((char *)ip + sizeof(struct iphdr));
/* icmp header */
icmp->type = ICMP_ECHO;
icmp->checksum = in_cksum((u_short *)icmp, sizeof(struct icmphdr));
/* ip header */
ip->version = 4;
ip->ihl = 5;
ip->tot_len = htons(sizeof(struct iphdr) + sizeof(struct icmphdr));
ip->id = rand() & 0xffff;
ip->ttl = 0;
ip->protocol = IPPROTO_ICMP;
ip->saddr = src->ip;
ip->daddr = dst->ip;
ip->check = in_cksum((u_short *)ip, sizeof(struct iphdr));
/* ether_header */
memcpy(eth->ether_shost, src->mac, ETH_ALEN);
memcpy(eth->ether_dhost, dst->mac, ETH_ALEN);
eth->ether_type = htons(ETH_P_IP);
/* send to icmp echo packet */
return sendto(sock, buf, sizeof(buf), 0, (struct sockaddr *)&sll, sizeof(sll));
}
int mac_aton(char *amac, char *nmac) {
char c;
int i;
unsigned int val;
i = 0;
while ((*amac != ) && (i < ETH_ALEN)) {
val = 0;
c = *amac++;
if (c >= 0 && c <= 9) {
val = c - 0;
}
else if (c >= a && c <= f) {
val = c - a + 10;
}
else if (c >= A && c <= F) {
val = c - A + 10;
}
else {
errno = EINVAL;
return -1;
}
val <<= 4;
c = *amac;
if (c >= 0 && c <= 9) {
val |= c - 0;
}
else if (c >= a && c <= f) {
val |= c - a + 10;
}
else if (c >= A && c <= F) {
val |= c - A + 10;
}
else if (c == : || c == ) {
val >>= 4;
}
else {
errno = EINVAL;
return -1;
}
if (c != 0) {
amac++;
}
*nmac++ = val & 0xff;
i++;
/* We might get a semicolon here - not required. */
if (*amac == :) {
amac++;
}
}
return 0;
}
int in_cksum(u_short *addr, int len) {
int nleft = len;
u_short *w = addr;
int sum = 0;
u_short answer = 0;
while (nleft > 1) {
sum += *w++;
nleft -= 2;
}
if (nleft == 1) {
*(u_char *)(&answer) = *(u_char *)w;
sum += answer;
}
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
answer = ~sum;
return answer;
}
void usage(char *cmd) {
fprintf(stderr, "usage: %s dev srcip srcmac dstip dstmac
", cmd);
}
/* EOF */ |