summaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorJoel Sing <jsing@cvs.openbsd.org>2010-10-17 12:14:29 +0000
committerJoel Sing <jsing@cvs.openbsd.org>2010-10-17 12:14:29 +0000
commit337bb5882fccf6bbf5a88a8036b5d93f772f73e4 (patch)
tree5582b16f5fef61bc2129aaee7cdd0526ffe821df /sbin
parentb5b9e5143e75a188c4164b69c4d89a93cf07373e (diff)
Add quirks support to operating system fingerprinting. tcpdump part
by mcbride@. ok mcbride@ henning@
Diffstat (limited to 'sbin')
-rw-r--r--sbin/pfctl/pfctl_osfp.c91
1 files changed, 82 insertions, 9 deletions
diff --git a/sbin/pfctl/pfctl_osfp.c b/sbin/pfctl/pfctl_osfp.c
index d7531e55f02..22f8b5add91 100644
--- a/sbin/pfctl/pfctl_osfp.c
+++ b/sbin/pfctl/pfctl_osfp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl_osfp.c,v 1.16 2009/12/24 10:06:35 sobrado Exp $ */
+/* $OpenBSD: pfctl_osfp.c,v 1.17 2010/10/17 12:14:28 jsing Exp $ */
/*
* Copyright (c) 2003 Mike Frantzen <frantzen@openbsd.org>
@@ -79,6 +79,8 @@ int get_str(char **, size_t *, char **, const char *, int,
int get_tcpopts(const char *, int, const char *,
pf_tcpopts_t *, int *, int *, int *, int *, int *,
int *);
+int get_quirks(const char *, int, const char *,
+ u_int16_t *);
void import_fingerprint(struct pf_osfp_ioctl *);
const char *print_ioctl(struct pf_osfp_ioctl *);
void print_name_list(int, struct name_list *, const char *);
@@ -96,7 +98,7 @@ pfctl_file_fingerprints(int dev, int opts, const char *fp_filename)
int window, w_mod, ttl, df, psize, p_mod, mss, mss_mod, wscale,
wscale_mod, optcnt, ts0;
pf_tcpopts_t packed_tcpopts;
- char *class, *version, *subtype, *desc, *tcpopts;
+ char *class, *version, *subtype, *desc, *tcpopts, *quirks;
struct pf_osfp_ioctl fp;
pfctl_flush_my_fingerprints(&classes);
@@ -105,7 +107,7 @@ pfctl_file_fingerprints(int dev, int opts, const char *fp_filename)
warn("%s", fp_filename);
return (1);
}
- class = version = subtype = desc = tcpopts = NULL;
+ class = version = subtype = desc = tcpopts = quirks = NULL;
if ((opts & PF_OPT_NOACTION) == 0)
pfctl_clear_fingerprints(dev, opts);
@@ -122,7 +124,9 @@ pfctl_file_fingerprints(int dev, int opts, const char *fp_filename)
free(desc);
if (tcpopts)
free(tcpopts);
- class = version = subtype = desc = tcpopts = NULL;
+ if (quirks)
+ free(quirks);
+ class = version = subtype = desc = tcpopts = quirks = NULL;
memset(&fp, 0, sizeof(fp));
/* Chop off comment */
@@ -158,20 +162,26 @@ pfctl_file_fingerprints(int dev, int opts, const char *fp_filename)
GET_INT(psize, &p_mod, "overall packet size", T_MOD|T_DC,
8192) ||
GET_STR(tcpopts, "TCP Options", 1) ||
+ GET_STR(quirks, "Quirks", 1) ||
GET_STR(class, "OS class", 1) ||
GET_STR(version, "OS version", 0) ||
GET_STR(subtype, "OS subtype", 0) ||
GET_STR(desc, "OS description", 2))
continue;
- if (get_tcpopts(fp_filename, lineno, tcpopts, &packed_tcpopts,
- &optcnt, &mss, &mss_mod, &wscale, &wscale_mod, &ts0))
- continue;
+
if (len != 0) {
fprintf(stderr, "%s:%d excess field\n", fp_filename,
lineno);
continue;
}
+ if (get_tcpopts(fp_filename, lineno, tcpopts, &packed_tcpopts,
+ &optcnt, &mss, &mss_mod, &wscale, &wscale_mod, &ts0))
+ continue;
+
+ if (get_quirks(fp_filename, lineno, quirks, &fp.fp_quirks))
+ continue;
+
fp.fp_ttl = ttl;
if (df)
fp.fp_flags |= PF_OSFP_DF;
@@ -202,7 +212,6 @@ pfctl_file_fingerprints(int dev, int opts, const char *fp_filename)
}
fp.fp_psize = psize;
-
switch (wscale_mod) {
case T_DC:
fp.fp_flags |= PF_OSFP_WSCALE_DC;
@@ -687,7 +696,6 @@ import_fingerprint(struct pf_osfp_ioctl *fp)
}
}
-
fingerprint_count++;
DEBUG(fp, "import signature %d:%d:%d", class, version, subtype);
}
@@ -976,6 +984,71 @@ get_tcpopts(const char *filename, int lineno, const char *tcpopts,
return (0);
}
+int
+get_quirks(const char *filename, int lineno, const char *quirkstr,
+ u_int16_t *quirks)
+{
+ int i, opt;
+
+ *quirks = 0;
+
+ if (strcmp(quirkstr, ".") == 0)
+ return (0);
+
+ for (i = 0; quirkstr[i];) {
+ switch ((opt = toupper(quirkstr[i++]))) {
+ case 'D':
+ fprintf(stderr, "%s:%d quirk %c not yet supported\n",
+ filename, lineno, opt);
+ *quirks |= PF_OSFP_QUIRK_DATA;
+ break;
+ case 'Q':
+ *quirks |= PF_OSFP_QUIRK_SEQEQ;
+ break;
+ case '0':
+ *quirks |= PF_OSFP_QUIRK_SEQZERO;
+ break;
+ case 'P':
+ fprintf(stderr, "%s:%d quirk %c not yet supported\n",
+ filename, lineno, opt);
+ *quirks |= PF_OSFP_QUIRK_PAST;
+ break;
+ case 'Z':
+ *quirks |= PF_OSFP_QUIRK_ZEROID;
+ break;
+ case 'I':
+ *quirks |= PF_OSFP_QUIRK_IPOPT;
+ break;
+ case 'U':
+ *quirks |= PF_OSFP_QUIRK_URG;
+ break;
+ case 'X':
+ *quirks |= PF_OSFP_QUIRK_X2;
+ break;
+ case 'A':
+ *quirks |= PF_OSFP_QUIRK_ACKNO;
+ break;
+ case 'T':
+ *quirks |= PF_OSFP_QUIRK_TS2;
+ break;
+ case 'F':
+ *quirks |= PF_OSFP_QUIRK_FLAGS;
+ break;
+ case '!':
+ fprintf(stderr, "%s:%d quirk %c not yet supported\n",
+ filename, lineno, opt);
+ *quirks |= PF_OSFP_QUIRK_BROKEN;
+ break;
+ default:
+ fprintf(stderr, "%s:%d unknown quirk %c\n",
+ filename, lineno, opt);
+ return (1);
+ }
+ }
+
+ return (0);
+}
+
/* rip the next field out of a formatted config file line */
char *
get_field(char **line, size_t *len, int *fieldlen)