/*- * Copyright (c) 2001-2005 Christian S.J. Peron * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include #include #include #include #include #ifndef lint static const char rcsid[] = "@(#) $Header: /usr/cvs/ipex/bstream.c,v 1.6 2005/03/02 04:27:09 modulus Exp $"; #endif #if (!defined(MAX)) #define MAX(a, b) ((a) > (b) ? (a) : (b)) #endif struct bin { u_char *b_pattern; u_long b_len; struct bin *b_next; }; static struct bin *header = NULL; void strip(char *from, char *to, int max) { int counter = 0; while (*from) { if (counter >= max) break; if (*from != ' ') *to++ = *from++; else from++; counter++; } *to = '\0'; } unsigned char hex2binary(char *digits) { unsigned char result = 0; if (!isxdigit(digits[0]) || !isxdigit(digits[1])) errx(1, "string non hex characters at `%s'", digits); result = ((digits[0] >= 'A' && digits[0] <= 'F') ? (digits[0] & 7) + 9 : digits[0] - '0') << 4; result += (digits[1] >= 'A' && digits[1] <= 'F') ? (digits[1] & 7) + 9 : digits[1] - '0'; return (result); } char * upcase(char *str) { char *ptr, *hptr; ptr = malloc(strlen(str)+1); hptr = ptr; while (*str != '\0') *ptr++ = toupper(*str++); *ptr = '\0'; return (hptr); } int ln_pattern(char *hexspec) { struct bin *b; int I, L, L2; L = strlen(hexspec); I = 0; strip(hexspec, hexspec, L); hexspec = upcase(hexspec); L = strlen(hexspec); if (L % 2 != 0) errx(1, "padding required. I.E. '02' instead of '2' for octet value."); L2 = L / 2; if ((b = malloc(sizeof(*b))) == 0) errx(1, "malloc failed."); b->b_next = header; b->b_len = L2; b->b_pattern = malloc(b->b_len); memset(b->b_pattern, 0, b->b_len); header = b; while (*hexspec) { b->b_pattern[I] = hex2binary(hexspec); hexspec += 2; I++; } return (0); } static int bmatch(u_char *pld, size_t pldlen, u_char *pt, size_t ptlen) { int i; short match; match = 0; for (i = 0; i < pldlen; i++) if (pld[i] == *pt) if (memcmp(pld + i, pt, ptlen) == 0) { match = 1; break; } return (match ? 0 : -1); } int detectpattern(u_char *p, size_t len) { struct bin *b; int match; for (b = header; b != '\0'; b = b->b_next) { match = bmatch(p, len, b->b_pattern, b->b_len); if (match == 0) return (1); } return (0); }