dsniff  2.4b2
About: A collection of tools for network auditing
  Fossies Dox: dsniff-2.4b2.tar.gz  ("inofficial" and yet experimental doxygen-generated source code documentation)  

magic.c
Go to the documentation of this file.
1 /*
2  * magic.c
3  *
4  * Network application protocol identification, based on file(1) magic.
5  *
6  * Copyright (c) 2000 Dug Song <dugsong@monkey.org>
7  * Copyright (c) 1987 Ian F. Darwin
8  *
9  * This software is not subject to any license of the American Telephone
10  * and Telegraph Company or of the Regents of the University of California.
11  *
12  * Permission is granted to anyone to use this software for any purpose on
13  * any computer system, and to alter it and redistribute it freely, subject
14  * to the following restrictions:
15  *
16  * 1. The author is not responsible for the consequences of use of this
17  * software, no matter how awful, even if they arise from flaws in it.
18  *
19  * 2. The origin of this software must not be misrepresented, either by
20  * explicit claim or by omission. Since few users ever read sources,
21  * credits must appear in the documentation.
22  *
23  * 3. Altered versions must be plainly marked as such, and must not be
24  * misrepresented as being the original software. Since few users
25  * ever read sources, credits must appear in the documentation.
26  *
27  * 4. This notice may not be removed or altered.
28  *
29  * $Id: magic.c,v 1.9 2001/03/15 08:33:04 dugsong Exp $
30  */
31 
32 #include "config.h"
33 
34 #include <sys/types.h>
35 
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <ctype.h>
40 #include <time.h>
41 #include <err.h>
42 
43 #include "options.h"
44 #include "magic.h"
45 
46 #define LOWCASE(p) (isupper((u_char) (p)) ? tolower((u_char) (p)) : (p))
47 
48 #define INDIR 1 /* if '>(...)' appears, */
49 #define UNSIGNED 2 /* comparison is unsigned */
50 #define ADD 4 /* if '>&' appears, */
51 
52 #define BYTE 1
53 #define SHORT 2
54 #define LONG 4
55 #define STRING 5
56 #define DATE 6
57 #define BESHORT 7
58 #define BELONG 8
59 #define BEDATE 9
60 #define LESHORT 10
61 #define LELONG 11
62 #define LEDATE 12
63 
64 struct magic {
65  short flag;
66  short cont_level;
67  struct {
68  int8_t type; /* byte short long */
69  int32_t offset; /* offset from indirection */
70  } in;
71  int32_t offset; /* offset to magic number. */
72  u_char reln; /* relation (0=eq, '>'=gt, etc.) */
73  int8_t type; /* int, short, long or string */
74  char vallen; /* length of string value, if any */
75  union VALUETYPE {
76  u_char b;
77  u_short h;
78  u_int32_t l;
79  char s[32];
80  u_char hs[2]; /* 2 bytes of a fixed-endian "short" */
81  u_char hl[4]; /* 4 bytes of a fixed-endian "long" */
82  } value; /* either number or string */
83  u_int32_t mask; /* mask before comparison with value */
84  char desc[50]; /* description */
85 };
86 
87 static char *Magictypes[12] = {
88  "byte",
89  "short",
90  "null",
91  "long",
92  "string",
93  "date",
94  "beshort",
95  "belong",
96  "bedate",
97  "leshort",
98  "lelong",
99  "ledate",
100 };
101 
102 static struct magic Magic[512];
103 static int Magiccnt = 0;
104 static int Magicmax = sizeof(Magic) / sizeof(Magic[0]);
105 static char Match[128];
106 
107 static void
108 eatsize(char **p)
109 {
110  char *l = *p;
111 
112  if (LOWCASE(*l) == 'u')
113  l++;
114 
115  switch (LOWCASE(*l)) {
116  case 'l': /* long */
117  case 's': /* short */
118  case 'h': /* short */
119  case 'b': /* char/byte */
120  case 'c': /* char/byte */
121  l++;
122  /*FALLTHROUGH*/
123  default:
124  break;
125  }
126  *p = l;
127 }
128 
129 /* Single hex char to int; -1 if not a hex char. */
130 static int
131 hextoint(int c)
132 {
133  if (!isascii((u_char) c)) return (-1);
134  if (isdigit((u_char) c)) return (c - '0');
135  if ((c >= 'a') && (c <= 'f')) return (c + 10 - 'a');
136  if ((c >= 'A') && (c <= 'F')) return (c + 10 - 'A');
137  return (-1);
138 }
139 
140 /*
141  * Convert a string containing C character escapes. Stop at an unescaped
142  * space or tab.
143  * Copy the converted version to "p", returning its length in *slen.
144  * Return updated scan pointer as function result.
145  */
146 static char *
147 getstr(char *s, char *p, int plen, int *slen)
148 {
149  char *origs = s, *origp = p;
150  char *pmax = p + plen - 1;
151  int c;
152  int val;
153 
154  while ((c = *s++) != '\0') {
155  if (isspace((u_char) c))
156  break;
157  if (p >= pmax) {
158  warnx("getstr: string too long: %s", origs);
159  break;
160  }
161  if (c == '\\') {
162  switch ((c = *s++)) {
163  case '\0':
164  goto out;
165  default:
166  *p++ = (char) c;
167  break;
168  case 'n':
169  *p++ = '\n';
170  break;
171  case 'r':
172  *p++ = '\r';
173  break;
174  case 'b':
175  *p++ = '\b';
176  break;
177  case 't':
178  *p++ = '\t';
179  break;
180  case 'f':
181  *p++ = '\f';
182  break;
183  case 'v':
184  *p++ = '\v';
185  break;
186  /* \ and up to 3 octal digits */
187  case '0':
188  case '1':
189  case '2':
190  case '3':
191  case '4':
192  case '5':
193  case '6':
194  case '7':
195  val = c - '0';
196  c = *s++; /* try for 2 */
197  if (c >= '0' && c <= '7') {
198  val = (val << 3) | (c - '0');
199  c = *s++; /* try for 3 */
200  if (c >= '0' && c <= '7')
201  val = (val << 3) | (c - '0');
202  else --s;
203  }
204  else --s;
205  *p++ = (char) val;
206  break;
207 
208  /* \x and up to 2 hex digits */
209  case 'x':
210  val = 'x'; /* Default if no digits */
211  c = hextoint(*s++); /* Get next char */
212  if (c >= 0) {
213  val = c;
214  c = hextoint(*s++);
215  if (c >= 0) val = (val << 4) + c;
216  else --s;
217  }
218  else --s;
219  *p++ = (char) val;
220  break;
221  }
222  }
223  else *p++ = (char) c;
224  }
225  out:
226  *p = '\0';
227  *slen = p - origp;
228 
229  return (s);
230 }
231 
232 /* Extend the sign bit if the comparison is to be signed. */
233 static u_int32_t
234 signextend(struct magic *m, u_int32_t v)
235 {
236  if (!(m->flag & UNSIGNED))
237  return (v);
238 
239  switch(m->type) {
240  /*
241  * Do not remove the casts below. They are
242  * vital. When later compared with the data,
243  * the sign extension must have happened.
244  */
245  case BYTE:
246  v = (char) v;
247  break;
248  case SHORT:
249  case BESHORT:
250  case LESHORT:
251  v = (short) v;
252  break;
253  case DATE:
254  case BEDATE:
255  case LEDATE:
256  case LONG:
257  case BELONG:
258  case LELONG:
259  v = (int32_t) v;
260  break;
261  case STRING:
262  break;
263  default:
264  warnx("sign_extend: can't happen: m->type = %d",
265  m->type);
266  return (-1);
267  }
268  return (v);
269 }
270 
271 /*
272  * Read a numeric value from a pointer, into the value union of a magic
273  * pointer, according to the magic type. Update the string pointer to point
274  * just after the number read. Return 0 for success, non-zero for failure.
275  */
276 static int
277 getvalue(struct magic *m, char **p)
278 {
279  int slen;
280 
281  if (m->type == STRING) {
282  *p = getstr(*p, m->value.s, sizeof(m->value.s), &slen);
283  m->vallen = slen;
284  }
285  else if (m->reln != 'x') {
286  m->value.l = signextend(m, strtoul(*p, p, 0));
287  eatsize(p);
288  }
289  return (0);
290 }
291 
292 #define SZOF(a) (sizeof(a) / sizeof(a[0]))
293 
294 static void
295 mdump(struct magic *m)
296 {
297  static char *typ[] = { "invalid", "byte", "short", "invalid",
298  "long", "string", "date", "beshort",
299  "belong", "bedate", "leshort", "lelong",
300  "ledate" };
301  (void) fputc('[', stderr);
302  (void) fprintf(stderr, ">>>>>>>> %d" + 8 - (m->cont_level & 7),
303  m->offset);
304 
305  if (m->flag & INDIR)
306  (void) fprintf(stderr, "(%s,%d),",
307  (m->in.type >= 0 && m->in.type < SZOF(typ)) ?
308  typ[(unsigned char) m->in.type] :
309  "*bad*",
310  m->in.offset);
311 
312  (void) fprintf(stderr, " %s%s", (m->flag & UNSIGNED) ? "u" : "",
313  (m->type >= 0 && m->type < SZOF(typ)) ?
314  typ[(unsigned char) m->type] :
315  "*bad*");
316  if (m->mask != ~0)
317  (void) fprintf(stderr, " & %.8x", m->mask);
318 
319  (void) fprintf(stderr, ",%c", m->reln);
320  if (m->reln != 'x') {
321  switch (m->type) {
322  case BYTE:
323  case SHORT:
324  case LONG:
325  case LESHORT:
326  case LELONG:
327  case BESHORT:
328  case BELONG:
329  (void) fprintf(stderr, "%d", m->value.l);
330  break;
331  case STRING:
332  fprintf(stderr, "%s", m->value.s);
333  break;
334  case DATE:
335  case LEDATE:
336  case BEDATE:
337  {
338  char *rt, *pp = ctime((time_t*) &m->value.l);
339  if ((rt = strchr(pp, '\n')) != NULL)
340  *rt = '\0';
341  (void) fprintf(stderr, "%s,", pp);
342  if (rt)
343  *rt = '\n';
344  }
345  break;
346  default:
347  (void) fputs("*bad*", stderr);
348  break;
349  }
350  }
351  (void) fprintf(stderr, ",\"%s\"]\n", m->desc);
352 }
353 
354 static int
355 magic_parse(char *p)
356 {
357  struct magic *m;
358  char *t, *s;
359  int i, j;
360 
361  if (Magiccnt + 1 > Magicmax)
362  errx(1, "magic_parse: magic table full");
363 
364  m = &Magic[Magiccnt];
365  m->flag = 0;
366  m->cont_level = 0;
367 
368  while (*p == '>') {
369  p++; /* step over */
370  m->cont_level++;
371  }
372  if (m->cont_level != 0 && *p == '(') {
373  p++; /* step over */
374  m->flag |= INDIR;
375  }
376  if (m->cont_level != 0 && *p == '&') {
377  p++; /* step over */
378  m->flag |= ADD;
379  }
380  /* Get offset, then skip over it. */
381  m->offset = (int) strtoul(p, &t, 0);
382  if (p == t)
383  errx(1, "magic_parse: offset %s invalid", p);
384  p = t;
385 
386  if (m->flag & INDIR) {
387  m->in.type = LONG;
388  m->in.offset = 0;
389 
390  /* read [.lbs][+-]nnnnn) */
391  if (*p == '.') {
392  p++;
393  switch (LOWCASE(*p)) {
394  case 'l':
395  m->in.type = LONG;
396  break;
397  case 'h':
398  case 's':
399  m->in.type = SHORT;
400  break;
401  case 'c':
402  case 'b':
403  m->in.type = BYTE;
404  break;
405  default:
406  errx(1, "magic_parse: indirect offset "
407  "type '%c' invalid", *p);
408  break;
409  }
410  p++;
411  }
412  s = p;
413  if (*p == '+' || *p == '-') p++;
414 
415  if (isdigit((u_char) *p)) {
416  m->in.offset = strtoul(p, &t, 0);
417  if (*s == '-') m->in.offset = - m->in.offset;
418  }
419  else t = p;
420 
421  if (*t++ != ')')
422  errx(1, "magic_parse: missing ')' in indirect offset");
423  p = t;
424  }
425 
426  while (isascii((u_char) *p) && isdigit((u_char) *p)) p++;
427  while (isascii((u_char) *p) && isspace((u_char) *p)) p++;
428 
429  if (*p == 'u') {
430  p++;
431  m->flag |= UNSIGNED;
432  }
433  /* Get type, skip it. */
434  t = p;
435  for (i = 0; i < 12; i++) {
436  j = strlen(Magictypes[i]);
437  if (strncmp(p, Magictypes[i], j) == 0) {
438  m->type = i + 1;
439  p += j;
440  break;
441  }
442  }
443  if (p == t)
444  errx(1, "magic_parse: type %s invalid", p);
445 
446  /* New-style and'ing: "0 byte&0x80 =0x80 dynamically linked" */
447  if (*p == '&') {
448  p++;
449  m->mask = signextend(m, strtoul(p, &p, 0));
450  eatsize(&p);
451  }
452  else m->mask = ~0L;
453 
454  while (isascii((u_char) *p) && isspace((u_char) *p)) p++;
455 
456  switch(*p) {
457  case '>':
458  case '<':
459  /* Old-style and'ing: "0 byte &0x80 dynamically linked" */
460  case '&':
461  case '^':
462  case '=':
463  m->reln = *p;
464  p++;
465  break;
466  case '!':
467  if (m->type != STRING) {
468  m->reln = *p;
469  p++;
470  break;
471  }
472  /* FALLTHRU */
473  default:
474  if (*p == 'x' && isascii((u_char) p[1]) &&
475  isspace((u_char) p[1])) {
476  m->reln = *p;
477  p++;
478  goto parse_get_desc; /* Bill The Cat */
479  }
480  m->reln = '=';
481  break;
482  }
483  while (isascii((u_char) *p) && isspace((u_char) *p)) p++;
484 
485  if (getvalue(m, &p))
486  return (0);
487 
488  parse_get_desc:
489  /* Now get last part - the description. */
490  while (isascii((u_char) *p) && isspace((u_char) *p)) p++;
491 
492  strlcpy(m->desc, p, sizeof(m->desc));
493 
494  if (Opt_debug) {
495  mdump(m);
496  }
497  Magiccnt++;
498  return (1);
499 }
500 
501 void
502 magic_init(char *filename)
503 {
504  FILE *f;
505  char buf[BUFSIZ];
506 
507  if ((f = fopen(filename, "r")) == NULL) {
508  err(1, "magic_init");
509  }
510  memset(&Magic, 0, sizeof(Magic));
511 
512  while (fgets(buf, sizeof(buf), f) != NULL) {
513  if (buf[0] == '#')
514  continue;
515  if (strlen(buf) <= 1)
516  continue;
517  buf[strlen(buf) - 1] = '\0';
518 
519  magic_parse(buf);
520  }
521  fclose(f);
522 }
523 
524 /* Convert the byte order of the data we are looking at */
525 static int
526 mconvert(union VALUETYPE *p, struct magic *m)
527 {
528  switch (m->type) {
529  case BYTE:
530  case SHORT:
531  case LONG:
532  case DATE:
533  return (1);
534  case STRING:
535  {
536  char *ptr;
537 
538  /* Null terminate and eat the return */
539  p->s[sizeof(p->s) - 1] = '\0';
540  if ((ptr = strchr(p->s, '\n')) != NULL)
541  *ptr = '\0';
542  return (1);
543  }
544  case BESHORT:
545  p->h = (short)((p->hs[0]<<8)|(p->hs[1]));
546  return (1);
547  case BELONG:
548  case BEDATE:
549  p->l = (int32_t)((p->hl[0]<<24)|(p->hl[1]<<16)|
550  (p->hl[2]<<8)|(p->hl[3]));
551  return (1);
552  case LESHORT:
553  p->h = (short)((p->hs[1]<<8)|(p->hs[0]));
554  return (1);
555  case LELONG:
556  case LEDATE:
557  p->l = (int32_t)((p->hl[3]<<24)|(p->hl[2]<<16)|
558  (p->hl[1]<<8)|(p->hl[0]));
559  return (1);
560  default:
561  errx(1, "mconvert: invalid type %d", m->type);
562  }
563  return (0);
564 }
565 
566 static int
567 mget(union VALUETYPE* p, u_char *s, struct magic *m, int nbytes)
568 {
569  int32_t offset = m->offset;
570 
571  if (offset + sizeof(union VALUETYPE) <= nbytes)
572  memcpy(p, s + offset, sizeof(*p));
573  else {
574  /*
575  * the usefulness of padding with zeroes eludes me, it
576  * might even cause problems
577  */
578  int32_t have = nbytes - offset;
579  memset(p, 0, sizeof(*p));
580  if (have > 0)
581  memcpy(p, s + offset, have);
582  }
583  if (!mconvert(p, m))
584  return (0);
585 
586  if (m->flag & INDIR) {
587  switch (m->in.type) {
588  case BYTE:
589  offset = p->b + m->in.offset;
590  break;
591  case SHORT:
592  offset = p->h + m->in.offset;
593  break;
594  case LONG:
595  offset = p->l + m->in.offset;
596  break;
597  }
598  if (offset + sizeof(*p) > nbytes)
599  return (0);
600 
601  memcpy(p, s + offset, sizeof(*p));
602 
603  if (!mconvert(p, m))
604  return (0);
605  }
606  return (1);
607 }
608 
609 static int
610 mcheck(union VALUETYPE* p, struct magic *m)
611 {
612  register u_int32_t l = m->value.l;
613  register u_int32_t v = 0;
614  int matched;
615 
616  if ( (m->value.s[0] == 'x') && (m->value.s[1] == '\0') ) {
617  warnx("mcheck: BOINK");
618  return (1);
619  }
620  switch (m->type) {
621  case BYTE:
622  v = p->b;
623  break;
624  case SHORT:
625  case BESHORT:
626  case LESHORT:
627  v = p->h;
628  break;
629  case LONG:
630  case BELONG:
631  case LELONG:
632  case DATE:
633  case BEDATE:
634  case LEDATE:
635  v = p->l;
636  break;
637  case STRING:
638  l = 0;
639  /* What we want here is:
640  * v = strncmp(m->value.s, p->s, m->vallen);
641  * but ignoring any nulls. bcmp doesn't give -/+/0
642  * and isn't universally available anyway.
643  */
644  v = 0;
645  {
646  register u_char *a = (u_char *) m->value.s;
647  register u_char *b = (u_char *) p->s;
648  register int len = m->vallen;
649 
650  while (--len >= 0)
651  if ((v = *b++ - *a++) != '\0')
652  break;
653  }
654  break;
655  default:
656  errx(1, "mcheck: invalid type %d", m->type);
657  /* NOTREACHED */
658  }
659  v = signextend(m, v) & m->mask;
660 
661  switch (m->reln) {
662  case 'x':
663  matched = 1;
664  break;
665  case '!':
666  matched = v != l;
667  break;
668  case '=':
669  matched = v == l;
670  break;
671  case '>':
672  if (m->flag & UNSIGNED) {
673  matched = v > l;
674  }
675  else matched = (int32_t) v > (int32_t) l;
676  break;
677  case '<':
678  if (m->flag & UNSIGNED) {
679  matched = v < l;
680  }
681  else matched = (int32_t) v < (int32_t) l;
682  break;
683  case '&':
684  matched = (v & l) == l;
685  break;
686  case '^':
687  matched = (v & l) != l;
688  break;
689  default:
690  matched = 0;
691  errx(1, "mcheck: can't happen: invalid relation %d", m->reln);
692  /* NOTREACHED */
693  }
694  if (matched && Opt_debug)
695  mdump(m);
696 
697  return (matched);
698 }
699 
700 static int32_t
701 mprint(union VALUETYPE *p, struct magic *m)
702 {
703  int32_t t = 0;
704 
705  switch (m->type) {
706  case BYTE:
707  t = m->offset + sizeof(char);
708  break;
709  case SHORT:
710  case BESHORT:
711  case LESHORT:
712  t = m->offset + sizeof(short);
713  break;
714  case LONG:
715  case BELONG:
716  case LELONG:
717  t = m->offset + sizeof(int32_t);
718  break;
719  case STRING:
720  if (m->reln == '=') {
721  t = m->offset + strlen(m->value.s);
722  }
723  else {
724  if (*m->value.s == '\0') {
725  char *cp = strchr(p->s,'\n');
726  if (cp)
727  *cp = '\0';
728  }
729  t = m->offset + strlen(p->s);
730  }
731  break;
732  case DATE:
733  case BEDATE:
734  case LEDATE:
735  t = m->offset + sizeof(time_t);
736  break;
737  default:
738  errx(1, "mprint: invalid m->type (%d)", m->type);
739  }
740  strncpy(Match, m->desc, sizeof(Match));
741 
742  return (t);
743 }
744 
745 
746 /*
747  * Go through the whole list, stopping if you find a match. Process all
748  * the continuations of that match before returning.
749  *
750  * We support multi-level continuations:
751  *
752  * At any time when processing a successful top-level match, there is a
753  * current continuation level; it represents the level of the last
754  * successfully matched continuation.
755  *
756  * Continuations above that level are skipped as, if we see one, it
757  * means that the continuation that controls them - i.e, the
758  * lower-level continuation preceding them - failed to match.
759  *
760  * Continuations below that level are processed as, if we see one,
761  * it means we've finished processing or skipping higher-level
762  * continuations under the control of a successful or unsuccessful
763  * lower-level continuation, and are now seeing the next lower-level
764  * continuation and should process it. The current continuation
765  * level reverts to the level of the one we're seeing.
766  *
767  * Continuations at the current level are processed as, if we see
768  * one, there's no lower-level continuation that may have failed.
769  *
770  * If a continuation matches, we bump the current continuation level
771  * so that higher-level continuations are processed.
772  */
773 char *
774 magic_match(u_char *s, int len)
775 {
776  int i, cont_level = 0;
777  union VALUETYPE p;
778  static int32_t *tmpoff = NULL;
779  static size_t tmplen = 0;
780  int32_t oldoff = 0;
781 
782  Match[0] = '\0';
783 
784  if (tmpoff == NULL)
785  if ((tmpoff = (int32_t *) malloc(tmplen = 20)) == NULL)
786  err(1, "malloc");
787 
788  for (i = 0; i < Magiccnt; i++) {
789  /* if main entry matches, print it... */
790  if (!mget(&p, s, &Magic[i], len) || !mcheck(&p, &Magic[i])) {
791  /*
792  * main entry didn't match,
793  * flush its continuations
794  */
795  while (i < Magiccnt && Magic[i + 1].cont_level != 0)
796  i++;
797  continue;
798  }
799  tmpoff[cont_level] = mprint(&p, &Magic[i]);
800 
801  /* and any continuations that match */
802  if (++cont_level >= tmplen) {
803  tmplen += 20;
804  if (!(tmpoff = (int32_t *) realloc(tmpoff, tmplen)))
805  err(1, "magic_match: malloc");
806  }
807  while (Magic[i + 1].cont_level != 0 && ++i < Magiccnt) {
808  if (cont_level >= Magic[i].cont_level) {
809  if (cont_level > Magic[i].cont_level) {
810  /*
811  * We're at the end of the level
812  * "cont_level" continuations.
813  */
814  cont_level = Magic[i].cont_level;
815  }
816  if (Magic[i].flag & ADD) {
817  oldoff = Magic[i].offset;
818  Magic[i].offset +=
819  tmpoff[cont_level - 1];
820  }
821  if (mget(&p, s, &Magic[i], len) &&
822  mcheck(&p, &Magic[i])) {
823  /* This continuation matched. */
824  tmpoff[cont_level] =
825  mprint(&p, &Magic[i]);
826 
827  /*
828  * If we see any continuations
829  * at a higher level, process them.
830  */
831  if (++cont_level >= tmplen) {
832  tmplen += 20;
833  if (!(tmpoff = (int32_t *)
834  realloc(tmpoff, tmplen)))
835  err(1, "magic_check: "
836  "malloc");
837  }
838  }
839  if (Magic[i].flag & ADD) {
840  Magic[i].offset = oldoff;
841  }
842  }
843  }
844  return (strlen(Match) ? Match : NULL); /* all through */
845  }
846  return (NULL); /* no match at all */
847 }
magic::type
int8_t type
Definition: magic.c:68
magic::cont_level
short cont_level
Definition: magic.c:66
DATE
#define DATE
Definition: magic.c:56
mconvert
static int mconvert(union VALUETYPE *p, struct magic *m)
Definition: magic.c:526
magic
Definition: magic.c:64
UNSIGNED
#define UNSIGNED
Definition: magic.c:49
warnx
void warnx(const char *fmt,...)
Definition: err.c:89
magic::offset
int32_t offset
Definition: magic.c:69
STRING
#define STRING
Definition: magic.c:55
Match
static char Match[128]
Definition: magic.c:105
BELONG
#define BELONG
Definition: magic.c:58
Magicmax
static int Magicmax
Definition: magic.c:104
BESHORT
#define BESHORT
Definition: magic.c:57
magic::VALUETYPE::s
char s[32]
Definition: magic.c:79
LESHORT
#define LESHORT
Definition: magic.c:60
Magic
static struct magic Magic[512]
Definition: magic.c:102
strlcpy
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:43
getvalue
static int getvalue(struct magic *m, char **p)
Definition: magic.c:277
Opt_debug
int Opt_debug
Definition: dsniff.c:37
magic::VALUETYPE
Definition: magic.c:75
magic::VALUETYPE::hl
u_char hl[4]
Definition: magic.c:81
magic::vallen
char vallen
Definition: magic.c:74
magic::mask
u_int32_t mask
Definition: magic.c:83
options.h
magic::reln
u_char reln
Definition: magic.c:72
signextend
static u_int32_t signextend(struct magic *m, u_int32_t v)
Definition: magic.c:234
INDIR
#define INDIR
Definition: magic.c:48
magic.h
magic::VALUETYPE::b
u_char b
Definition: magic.c:76
l
libnet_t * l
Definition: arpspoof.c:34
magic::value
union magic::VALUETYPE value
mcheck
static int mcheck(union VALUETYPE *p, struct magic *m)
Definition: magic.c:610
magic::VALUETYPE::hs
u_char hs[2]
Definition: magic.c:80
magic_init
void magic_init(char *filename)
Definition: magic.c:502
getstr
static char * getstr(char *s, char *p, int plen, int *slen)
Definition: magic.c:147
magic_match
char * magic_match(u_char *s, int len)
Definition: magic.c:774
LONG
#define LONG
Definition: magic.c:54
eatsize
static void eatsize(char **p)
Definition: magic.c:108
err.h
magic::VALUETYPE::l
u_int32_t l
Definition: magic.c:78
buf
Definition: buf.h:14
err
void err(int eval, const char *fmt,...)
Definition: err.c:47
mget
static int mget(union VALUETYPE *p, u_char *s, struct magic *m, int nbytes)
Definition: magic.c:567
magic::desc
char desc[50]
Definition: magic.c:84
mprint
static int32_t mprint(union VALUETYPE *p, struct magic *m)
Definition: magic.c:701
errx
void errx(int eval, const char *fmt,...)
Definition: err.c:76
magic::in
struct magic::@3 in
mdump
static void mdump(struct magic *m)
Definition: magic.c:295
BEDATE
#define BEDATE
Definition: magic.c:59
LEDATE
#define LEDATE
Definition: magic.c:62
magic::flag
short flag
Definition: magic.c:65
hextoint
static int hextoint(int c)
Definition: magic.c:131
Magictypes
static char * Magictypes[12]
Definition: magic.c:87
LOWCASE
#define LOWCASE(p)
Definition: magic.c:46
BYTE
#define BYTE
Definition: magic.c:52
magic_parse
static int magic_parse(char *p)
Definition: magic.c:355
config.h
Magiccnt
static int Magiccnt
Definition: magic.c:103
magic::VALUETYPE::h
u_short h
Definition: magic.c:77
ADD
#define ADD
Definition: magic.c:50
LELONG
#define LELONG
Definition: magic.c:61
SHORT
#define SHORT
Definition: magic.c:53
SZOF
#define SZOF(a)
Definition: magic.c:292