1*a71a9546SAutomerger Merge Worker /*
2*a71a9546SAutomerger Merge Worker * Copyright (c) 2003+ Evgeniy Polyakov <[email protected]>
3*a71a9546SAutomerger Merge Worker *
4*a71a9546SAutomerger Merge Worker *
5*a71a9546SAutomerger Merge Worker * This program is free software; you can redistribute it and/or modify
6*a71a9546SAutomerger Merge Worker * it under the terms of the GNU General Public License as published by
7*a71a9546SAutomerger Merge Worker * the Free Software Foundation; either version 2 of the License, or
8*a71a9546SAutomerger Merge Worker * (at your option) any later version.
9*a71a9546SAutomerger Merge Worker *
10*a71a9546SAutomerger Merge Worker * This program is distributed in the hope that it will be useful,
11*a71a9546SAutomerger Merge Worker * but WITHOUT ANY WARRANTY; without even the implied warranty of
12*a71a9546SAutomerger Merge Worker * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13*a71a9546SAutomerger Merge Worker * GNU General Public License for more details.
14*a71a9546SAutomerger Merge Worker *
15*a71a9546SAutomerger Merge Worker * You should have received a copy of the GNU General Public License
16*a71a9546SAutomerger Merge Worker * along with this program; if not, write to the Free Software
17*a71a9546SAutomerger Merge Worker * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18*a71a9546SAutomerger Merge Worker */
19*a71a9546SAutomerger Merge Worker
20*a71a9546SAutomerger Merge Worker /*
21*a71a9546SAutomerger Merge Worker * xtables interface for OS fingerprint matching module.
22*a71a9546SAutomerger Merge Worker */
23*a71a9546SAutomerger Merge Worker #include <stdio.h>
24*a71a9546SAutomerger Merge Worker #include <string.h>
25*a71a9546SAutomerger Merge Worker #include <xtables.h>
26*a71a9546SAutomerger Merge Worker #include <netinet/ip.h>
27*a71a9546SAutomerger Merge Worker #include <netinet/tcp.h>
28*a71a9546SAutomerger Merge Worker #include <linux/netfilter/xt_osf.h>
29*a71a9546SAutomerger Merge Worker
30*a71a9546SAutomerger Merge Worker enum {
31*a71a9546SAutomerger Merge Worker O_GENRE = 0,
32*a71a9546SAutomerger Merge Worker O_TTL,
33*a71a9546SAutomerger Merge Worker O_LOGLEVEL,
34*a71a9546SAutomerger Merge Worker };
35*a71a9546SAutomerger Merge Worker
osf_help(void)36*a71a9546SAutomerger Merge Worker static void osf_help(void)
37*a71a9546SAutomerger Merge Worker {
38*a71a9546SAutomerger Merge Worker printf("OS fingerprint match options:\n"
39*a71a9546SAutomerger Merge Worker "[!] --genre string Match a OS genre by passive fingerprinting.\n"
40*a71a9546SAutomerger Merge Worker "--ttl level Use some TTL check extensions to determine OS:\n"
41*a71a9546SAutomerger Merge Worker " 0 true ip and fingerprint TTL comparison. Works for LAN.\n"
42*a71a9546SAutomerger Merge Worker " 1 check if ip TTL is less than fingerprint one. Works for global addresses.\n"
43*a71a9546SAutomerger Merge Worker " 2 do not compare TTL at all. This allows NMAP detection, but can produce false results.\n"
44*a71a9546SAutomerger Merge Worker "--log level Log determined genres into dmesg even if they do not match desired one:\n"
45*a71a9546SAutomerger Merge Worker " 0 log all matched or unknown signatures.\n"
46*a71a9546SAutomerger Merge Worker " 1 log only first one.\n"
47*a71a9546SAutomerger Merge Worker " 2 log all known matched signatures.\n"
48*a71a9546SAutomerger Merge Worker );
49*a71a9546SAutomerger Merge Worker }
50*a71a9546SAutomerger Merge Worker
51*a71a9546SAutomerger Merge Worker #define s struct xt_osf_info
52*a71a9546SAutomerger Merge Worker static const struct xt_option_entry osf_opts[] = {
53*a71a9546SAutomerger Merge Worker {.name = "genre", .id = O_GENRE, .type = XTTYPE_STRING,
54*a71a9546SAutomerger Merge Worker .flags = XTOPT_MAND | XTOPT_INVERT | XTOPT_PUT,
55*a71a9546SAutomerger Merge Worker XTOPT_POINTER(s, genre)},
56*a71a9546SAutomerger Merge Worker {.name = "ttl", .id = O_TTL, .type = XTTYPE_UINT32,
57*a71a9546SAutomerger Merge Worker .flags = XTOPT_PUT, XTOPT_POINTER(s, ttl), .min = 0, .max = 2},
58*a71a9546SAutomerger Merge Worker {.name = "log", .id = O_LOGLEVEL, .type = XTTYPE_UINT32,
59*a71a9546SAutomerger Merge Worker .flags = XTOPT_PUT, XTOPT_POINTER(s, loglevel), .min = 0, .max = 2},
60*a71a9546SAutomerger Merge Worker XTOPT_TABLEEND,
61*a71a9546SAutomerger Merge Worker };
62*a71a9546SAutomerger Merge Worker #undef s
63*a71a9546SAutomerger Merge Worker
osf_parse(struct xt_option_call * cb)64*a71a9546SAutomerger Merge Worker static void osf_parse(struct xt_option_call *cb)
65*a71a9546SAutomerger Merge Worker {
66*a71a9546SAutomerger Merge Worker struct xt_osf_info *info = cb->data;
67*a71a9546SAutomerger Merge Worker
68*a71a9546SAutomerger Merge Worker xtables_option_parse(cb);
69*a71a9546SAutomerger Merge Worker switch (cb->entry->id) {
70*a71a9546SAutomerger Merge Worker case O_GENRE:
71*a71a9546SAutomerger Merge Worker if (cb->invert)
72*a71a9546SAutomerger Merge Worker info->flags |= XT_OSF_INVERT;
73*a71a9546SAutomerger Merge Worker info->len = strlen(info->genre);
74*a71a9546SAutomerger Merge Worker break;
75*a71a9546SAutomerger Merge Worker case O_TTL:
76*a71a9546SAutomerger Merge Worker info->flags |= XT_OSF_TTL;
77*a71a9546SAutomerger Merge Worker break;
78*a71a9546SAutomerger Merge Worker case O_LOGLEVEL:
79*a71a9546SAutomerger Merge Worker info->flags |= XT_OSF_LOG;
80*a71a9546SAutomerger Merge Worker break;
81*a71a9546SAutomerger Merge Worker }
82*a71a9546SAutomerger Merge Worker }
83*a71a9546SAutomerger Merge Worker
osf_print(const void * ip,const struct xt_entry_match * match,int numeric)84*a71a9546SAutomerger Merge Worker static void osf_print(const void *ip, const struct xt_entry_match *match, int numeric)
85*a71a9546SAutomerger Merge Worker {
86*a71a9546SAutomerger Merge Worker const struct xt_osf_info *info = (const struct xt_osf_info*) match->data;
87*a71a9546SAutomerger Merge Worker
88*a71a9546SAutomerger Merge Worker printf(" OS fingerprint match %s%s", (info->flags & XT_OSF_INVERT) ? "! " : "", info->genre);
89*a71a9546SAutomerger Merge Worker }
90*a71a9546SAutomerger Merge Worker
osf_save(const void * ip,const struct xt_entry_match * match)91*a71a9546SAutomerger Merge Worker static void osf_save(const void *ip, const struct xt_entry_match *match)
92*a71a9546SAutomerger Merge Worker {
93*a71a9546SAutomerger Merge Worker const struct xt_osf_info *info = (const struct xt_osf_info*) match->data;
94*a71a9546SAutomerger Merge Worker
95*a71a9546SAutomerger Merge Worker if (info->flags & XT_OSF_INVERT)
96*a71a9546SAutomerger Merge Worker printf(" !");
97*a71a9546SAutomerger Merge Worker
98*a71a9546SAutomerger Merge Worker printf(" --genre %s", info->genre);
99*a71a9546SAutomerger Merge Worker if (info->flags & XT_OSF_TTL)
100*a71a9546SAutomerger Merge Worker printf(" --ttl %u", info->ttl);
101*a71a9546SAutomerger Merge Worker if (info->flags & XT_OSF_LOG)
102*a71a9546SAutomerger Merge Worker printf(" --log %u", info->loglevel);
103*a71a9546SAutomerger Merge Worker }
104*a71a9546SAutomerger Merge Worker
105*a71a9546SAutomerger Merge Worker static struct xtables_match osf_match = {
106*a71a9546SAutomerger Merge Worker .name = "osf",
107*a71a9546SAutomerger Merge Worker .version = XTABLES_VERSION,
108*a71a9546SAutomerger Merge Worker .size = XT_ALIGN(sizeof(struct xt_osf_info)),
109*a71a9546SAutomerger Merge Worker .userspacesize = XT_ALIGN(sizeof(struct xt_osf_info)),
110*a71a9546SAutomerger Merge Worker .help = osf_help,
111*a71a9546SAutomerger Merge Worker .x6_parse = osf_parse,
112*a71a9546SAutomerger Merge Worker .print = osf_print,
113*a71a9546SAutomerger Merge Worker .save = osf_save,
114*a71a9546SAutomerger Merge Worker .x6_options = osf_opts,
115*a71a9546SAutomerger Merge Worker .family = NFPROTO_IPV4,
116*a71a9546SAutomerger Merge Worker };
117*a71a9546SAutomerger Merge Worker
_init(void)118*a71a9546SAutomerger Merge Worker void _init(void)
119*a71a9546SAutomerger Merge Worker {
120*a71a9546SAutomerger Merge Worker xtables_register_match(&osf_match);
121*a71a9546SAutomerger Merge Worker }
122