Quoting manu@...:
> We do not need that: we have source and destination IP and ports.
> Do you have an URL with detailed documentation about this internal
> method?
Ok, the point of using udp was for spamass/amavis running on a
different machine could get that same data (unless we place a header
in the email with this data in it ourselfs so they don't need to fetch
it), but from a pure greylisting standpoint, I don't see why the
milter and p0f would ever be on seperate boxes.
All this code is taken directly from the p0f source package that
includes samples in a few languages. The header file isn't moved into
a normal include directoy for inclusion easily :(
#define QUERY_MAGIC 0x0defaced
#define NO_SCORE -100
/* Masquerade detection flags: */
#define D_GENRE 0x0001
#define D_DETAIL 0x0002
#define D_LINK 0x0004
#define D_DIST 0x0008
#define D_NAT 0x0010
#define D_FW 0x0020
#define D_NAT2_1 0x0040
#define D_FW2_1 0x0080
#define D_NAT2_2 0x0100
#define D_FW2_2 0x0200
#define D_FAST 0x0400
#define D_TNEG 0x0800
#define D_TIME 0x4000
#define D_FAR 0x8000
#define QTYPE_FINGERPRINT 1
#define QTYPE_STATUS 2
struct p0f_query {
_u32 magic; /* must be set to QUERY_MAGIC */
_u8 type; /* QTYPE_* */
_u32 id; /* Unique query ID */
_u32 src_ad,dst_ad; /* src address, local dst addr */
_u16 src_port,dst_port; /* src and dst ports */
};
#define RESP_OK 0 /* Response OK */
#define RESP_BADQUERY 1 /* Query malformed */
#define RESP_NOMATCH 2 /* No match for src-dst data */
#define RESP_STATUS 255 /* Status information */
struct p0f_response {
_u32 magic; /* QUERY_MAGIC */
_u32 id; /* Query ID (copied from p0f_query) */
_u8 type; /* RESP_* */
_u8 genre[20]; /* OS genre (empty if no match) */
_u8 detail[40]; /* OS version (empty if no match) */
_s8 dist; /* Distance (-1 if unknown ) */
_u8 link[30]; /* Link type (empty if unknown) */
_u8 tos[30]; /* Traffic type (empty if unknown) */
_u8 fw,nat; /* firewall and NAT flags flags */
_u8 real; /* A real operating system? */
_s16 score; /* Masquerade score (or NO_SCORE) */
_u16 mflags; /* Masquerade flags (D_*) */
_s32 uptime; /* Uptime in hours (-1 = unknown) */
};
struct p0f_status {
_u32 magic; /* QUERY_MAGIC */
_u32 id; /* Query ID (copied from p0f_query) */
_u8 type; /* RESP_STATUS */
_u8 version[16]; /* p0f version */
_u8 mode; /* p0f mode (S - SYN; A - SYN+ACK, R
- RST, O - stray) */
_u32 fp_cksum; /* Fingerprint file checksum */
_u32 cache; /* p0f query cache size */
_u32 packets; /* Total number of all packet received */
_u32 matched; /* Total number of packets matched */
_u32 queries; /* Total number of queries handled */
_u32 cmisses; /* Total number of cache query misses */
_u32 uptime; /* Process uptime in seconds */
};
struct sockaddr_un x;
struct p0f_query p;
struct p0f_response r;
_u32 s,d,sp,dp;
_s32 sock;
if (argc != 6) {
debug("Usage: %s p0f_socket src_ip src_port dst_ip dst_port\n",
argv[0]);
exit(1);
}
s = inet_addr(argv[2]);
sp = atoi(argv[3]);
d = inet_addr(argv[4]);
dp = atoi(argv[5]);
if (!sp || !dp || s == INADDR_NONE || d == INADDR_NONE)
fatal("Bad IP/port values.\n");
sock = socket(PF_UNIX,SOCK_STREAM,0);
if (sock < 0) pfatal("socket");
memset(&x,0,sizeof(x));
x.sun_family=AF_UNIX;
strncpy(x.sun_path,argv[1],63);
if (connect(sock,(struct sockaddr*)&x,sizeof(x))) pfatal(argv[1]);
p.magic = QUERY_MAGIC;
p.id = 0x12345678;
p.type = QTYPE_FINGERPRINT;
p.src_ad = s;
p.dst_ad = d;
p.src_port = sp;
p.dst_port = dp;
if (write(sock,&p,sizeof(p)) != sizeof(p))
fatal("Socket write error (timeout?).\n");
if (read(sock,&r,sizeof(r)) != sizeof(r))
fatal("Response read error (timeout?).\n");
if (r.magic != QUERY_MAGIC)
fatal("Bad response magic.\n");
if (r.type == RESP_BADQUERY)
fatal("P0f did not honor our query.\n");
if (r.type == RESP_NOMATCH) {
printf("This connection is not (no longer?) in the cache.\n");
exit(3);
}
if (!r.genre[0]) {
printf("Genre and OS details not recognized.\n");
} else {
printf("Genre : %s\n",r.genre);
printf("Details : %s\n",r.detail);
if (r.dist != -1) printf("Distance : %d hops\n",r.dist);
}
if (r.link[0]) printf("Link : %s\n",r.link);
if (r.tos[0]) printf("Service : %s\n",r.tos);
if (r.uptime != -1) printf("Uptime : %d hrs\n",r.uptime);
if (r.score != NO_SCORE)
printf("M-Score : %d%% (flags %x).\n",r.score,r.mflags);
if (r.fw) printf("The host is behind a firewall.\n");
if (r.nat) printf("The host is behind NAT or such.\n");
shutdown(sock,2);
close(sock);Message
Re: [milter-greylist] P0f support
2008-08-31 by Patrick Domack
Attachments
- No local attachments were found for this message.