Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

OSFingerprint Class Reference

#include <OSFinger.h>

Collaboration diagram for OSFingerprint:

Collaboration graph
[legend]
List of all members.

Public Member Functions

 OSFingerprint (FingerprintMode mode)
 ~OSFingerprint ()
bool Error () const
int FindMatch (struct os_type *retval, uint16 tot, uint8 DF_flag, uint8 TTL, uint16 WSS, uint8 ocnt, uint8 *op, uint16 MSS, uint8 win_scale, uint32 tstamp, uint32 quirks, uint8 ECN) const
bool CacheMatch (uint32 addr, int id)
int Get_OS_From_SYN (struct os_type *retval, uint16 tot, uint8 DF_flag, uint8 TTL, uint16 WSS, uint8 ocnt, uint8 *op, uint16 MSS, uint8 win_scale, uint32 tstamp, uint32 quirks, uint8 ecn) const
void load_config (char *file)

Protected Member Functions

void collide (uint32 id)
void Error (const char *msg)
void Error (const char *msg, int n)
void Error (const char *msg, const char *s)

Private Member Functions

 PDict (int) os_matches

Private Attributes

bool err
unsigned int mode
uint32 sigcnt
uint32 gencnt
uint8 problems
fp_entry sig [MAXSIGS]
fp_entrybh [OSHSIZE]

Constructor & Destructor Documentation

OSFingerprint::OSFingerprint FingerprintMode  mode  ) 
 

Definition at line 28 of file OSFinger.cc.

References bh, copy_string(), err, Error(), gencnt, internal_val(), load_config(), MAXSIGS, OSHSIZE, problems, RST_FINGERPRINT_MODE, sig, sigcnt, SYN_ACK_FINGERPRINT_MODE, and SYN_FINGERPRINT_MODE.

00029   {
00030   err = 0;
00031 
00032   sigcnt=gencnt=0;
00033   problems=0;
00034   char* fname;
00035 
00036   memset(sig, 0, sizeof(struct fp_entry)*MAXSIGS);
00037   memset(bh, 0, sizeof(struct fp_entry*)*OSHSIZE);
00038 
00039   if (mode == SYN_FINGERPRINT_MODE)
00040     {
00041     fname = copy_string(internal_val("passive_fingerprint_file")->AsString()->CheckString());
00042     load_config(fname);
00043     }
00044   else if (mode == SYN_ACK_FINGERPRINT_MODE)
00045     {//not yet supported
00046     load_config("p0fsynack.sig");
00047     }
00048   else if (mode == RST_FINGERPRINT_MODE)
00049     {//not yet supported
00050     load_config("p0frst.sig");
00051     }
00052   else
00053     {
00054     Error("OS fingerprinting: unknown mode!");
00055     }
00056 }

OSFingerprint::~OSFingerprint  )  [inline]
 

Definition at line 86 of file OSFinger.h.

00086 {}


Member Function Documentation

bool OSFingerprint::CacheMatch uint32  addr,
int  id
 

Definition at line 58 of file OSFinger.cc.

References addr, id, and uint32.

Referenced by NetSessions::CompareWithPreviousOSMatch().

00059   {
00060   HashKey key = HashKey(&addr, 1);
00061   int* pid = new int;
00062   *pid=id;
00063   int* prev = os_matches.Insert(&key, pid);
00064   bool ret = (prev ? *prev != id : 1);
00065   if (prev)
00066     delete prev;
00067   return ret;
00068   }

void OSFingerprint::collide uint32  id  )  [protected]
 

Definition at line 72 of file OSFinger.cc.

References fp_entry::df, fmt(), id, MOD_CONST, MOD_MSS, MOD_MTU, fp_entry::optcnt, PACKET_BIG, problems, fp_entry::quirks, sig, fp_entry::size, uint32, warn(), and fp_entry::zero_stamp.

Referenced by load_config().

00073   {
00074   uint32 i,j;
00075   uint32 cur;
00076 
00077   if (sig[id].ttl % 32 && sig[id].ttl != 255 && sig[id].ttl % 30)
00078     {
00079     problems=1;
00080     warn(fmt("OS fingerprinting: [!] Unusual TTL (%d) for signature '%s %s' (line %d).",
00081           sig[id].ttl,sig[id].os,sig[id].desc,sig[id].line));
00082     }
00083 
00084   for (i=0;i<id;i++)
00085     {
00086     if (!strcmp(sig[i].os,sig[id].os) &&
00087         !strcmp(sig[i].desc,sig[id].desc)) {
00088       problems=1;
00089       warn(fmt("OS fingerprinting: [!] Duplicate signature name: '%s %s' (line %d and %d).",
00090             sig[i].os,sig[i].desc,sig[i].line,sig[id].line));
00091     }
00092 
00093     /* If TTLs are sufficiently away from each other, the risk of
00094        a collision is lower. */
00095     if (abs((int)sig[id].ttl - (int)sig[i].ttl) > 25) continue;
00096 
00097     if (sig[id].df ^ sig[i].df) continue;
00098     if (sig[id].zero_stamp ^ sig[i].zero_stamp) continue;
00099 
00100     /* Zero means >= PACKET_BIG */
00101     if (sig[id].size) { if (sig[id].size ^ sig[i].size) continue; }
00102       else if (sig[i].size < PACKET_BIG) continue;
00103 
00104     if (sig[id].optcnt ^ sig[i].optcnt) continue;
00105     if (sig[id].quirks ^ sig[i].quirks) continue;
00106 
00107     switch (sig[id].wsize_mod) {
00108 
00109       case 0: /* Current: const */
00110 
00111         cur=sig[id].wsize;
00112 
00113 do_const:
00114 
00115         switch (sig[i].wsize_mod) {
00116 
00117           case 0: /* Previous is also const */
00118 
00119             /* A problem if values match */
00120             if (cur ^ sig[i].wsize) continue;
00121             break;
00122 
00123           case MOD_CONST: /* Current: const, prev: modulo (or *) */
00124 
00125             /* A problem if current value is a multiple of that modulo */
00126             if (cur % sig[i].wsize) continue;
00127             break;
00128 
00129           case MOD_MSS: /* Current: const, prev: mod MSS */
00130 
00131             if (sig[i].mss_mod || sig[i].wsize *
00132                (sig[i].mss ? sig[i].mss : 1460 ) != (int) cur)
00133               continue;
00134 
00135             break;
00136 
00137           case MOD_MTU: /* Current: const, prev: mod MTU */
00138 
00139             if (sig[i].mss_mod || sig[i].wsize * (
00140                 (sig[i].mss ? sig[i].mss : 1460 )+40) != (int) cur)
00141               continue;
00142 
00143             break;
00144 
00145         }
00146 
00147         break;
00148 
00149       case 1: /* Current signature is modulo something */
00150 
00151         /* A problem only if this modulo is a multiple of the
00152            previous modulo */
00153 
00154         if (sig[i].wsize_mod != MOD_CONST) continue;
00155         if (sig[id].wsize % sig[i].wsize) continue;
00156 
00157         break;
00158 
00159       case MOD_MSS: /* Current is modulo MSS */
00160 
00161         /* There's likely a problem only if the previous one is close
00162            to '*'; we do not check known MTUs, because this particular
00163            signature can be made with some uncommon MTUs in mind. The
00164            problem would also appear if current signature has a fixed
00165            MSS. */
00166 
00167         if (sig[i].wsize_mod != MOD_CONST || sig[i].wsize >= 8) {
00168           if (!sig[id].mss_mod) {
00169             cur = (sig[id].mss ? sig[id].mss : 1460 ) * sig[id].wsize;
00170             goto do_const;
00171           }
00172           continue;
00173         }
00174 
00175         break;
00176 
00177       case MOD_MTU: /* Current is modulo MTU */
00178 
00179         if (sig[i].wsize_mod != MOD_CONST || sig[i].wsize <= 8) {
00180           if (!sig[id].mss_mod) {
00181             cur = ( (sig[id].mss ? sig[id].mss : 1460 ) +40) * sig[id].wsize;
00182             goto do_const;
00183           }
00184           continue;
00185         }
00186 
00187         break;
00188 
00189     }
00190 
00191     /* Same for wsc */
00192     switch (sig[id].wsc_mod) {
00193 
00194       case 0: /* Current: const */
00195 
00196         cur=sig[id].wsc;
00197 
00198         switch (sig[i].wsc_mod) {
00199 
00200           case 0: /* Previous is also const */
00201 
00202             /* A problem if values match */
00203             if (cur ^ sig[i].wsc) continue;
00204             break;
00205 
00206           case 1: /* Current: const, prev: modulo (or *) */
00207 
00208             /* A problem if current value is a multiple of that modulo */
00209             if (cur % sig[i].wsc) continue;
00210             break;
00211 
00212         }
00213 
00214         break;
00215 
00216       case MOD_CONST: /* Current signature is modulo something */
00217 
00218         /* A problem only if this modulo is a multiple of the
00219            previous modulo */
00220 
00221         if (!sig[i].wsc_mod) continue;
00222         if (sig[id].wsc % sig[i].wsc) continue;
00223 
00224         break;
00225 
00226      }
00227 
00228     /* Same for mss */
00229     switch (sig[id].mss_mod) {
00230 
00231       case 0: /* Current: const */
00232 
00233         cur=sig[id].mss;
00234 
00235         switch (sig[i].mss_mod) {
00236 
00237           case 0: /* Previous is also const */
00238 
00239             /* A problem if values match */
00240             if (cur ^ sig[i].mss) continue;
00241             break;
00242 
00243           case 1: /* Current: const, prev: modulo (or *) */
00244 
00245             /* A problem if current value is a multiple of that modulo */
00246             if (cur % sig[i].mss) continue;
00247             break;
00248 
00249         }
00250 
00251         break;
00252 
00253       case MOD_CONST: /* Current signature is modulo something */
00254 
00255         /* A problem only if this modulo is a multiple of the
00256            previous modulo */
00257 
00258         if (!sig[i].mss_mod) continue;
00259         if ((sig[id].mss ? sig[id].mss : 1460 ) %
00260             (sig[i].mss ? sig[i].mss : 1460 )) continue;
00261 
00262         break;
00263 
00264      }
00265 
00266      /* Now check option sequence */
00267 
00268     for (j=0;j<sig[id].optcnt;j++)
00269       if (sig[id].opt[j] ^ sig[i].opt[j]) goto reloop;
00270 
00271     problems=1;
00272     warn(fmt("OS fingerprinting: [!] Signature '%s %s' (line %d)\n"
00273           "    is already covered by '%s %s' (line %d).",
00274           sig[id].os,sig[id].desc,sig[id].line,sig[i].os,sig[i].desc,
00275           sig[i].line));
00276 
00277 reloop:
00278     ;
00279     }
00280   }

void OSFingerprint::Error const char *  msg,
const char *  s
[inline, protected]
 

Definition at line 118 of file OSFinger.h.

References err, and error().

00119                 {
00120                 error(msg, s);
00121                 err = true;
00122                 }

void OSFingerprint::Error const char *  msg,
int  n
[inline, protected]
 

Definition at line 112 of file OSFinger.h.

References err, and error().

00113                 {
00114                 error(msg, n);
00115                 err = true;
00116                 }

void OSFingerprint::Error const char *  msg  )  [inline, protected]
 

Definition at line 106 of file OSFinger.h.

References err, and error().

00107                 {
00108                 error(msg);
00109                 err = true;
00110                 }

bool OSFingerprint::Error  )  const [inline]
 

Definition at line 88 of file OSFinger.h.

References err.

Referenced by load_config(), NetSessions::NetSessions(), and OSFingerprint().

00088 { return err; }

int OSFingerprint::FindMatch struct os_type retval,
uint16  tot,
uint8  DF_flag,
uint8  TTL,
uint16  WSS,
uint8  ocnt,
uint8 op,
uint16  MSS,
uint8  win_scale,
uint32  tstamp,
uint32  quirks,
uint8  ECN
const
 

Definition at line 513 of file OSFinger.cc.

References bh, os_type::desc, os_type::dist, GADGETECN, GADGETFIREWALL, GADGETNAT, GADGETNAT2, os_type::gadgets, GADGETUPTIME, id, os_type::match, MATCHFUZZY, MATCHGENERIC, MAXDIST, MOD_CONST, MOD_MSS, MOD_MTU, mode, os_type::os, p, PACKET_BIG, RST_FINGERPRINT_MODE, SIGHASH, uint16, uint32, uint8, and os_type::uptime.

Referenced by NetSessions::Get_OS_From_SYN().

00517   {
00518   uint32 j; //used for counter in loops
00519   struct fp_entry* p;
00520   uint8  orig_df  = df;
00521 
00522   struct fp_entry* fuzzy = 0;
00523   uint8 fuzzy_now = 0;
00524   int id = 0; //return value: 0 indicates no match.
00525 
00526   retval->os="UNKNOWN";
00527   retval->desc=NULL;
00528   retval->gadgets=0;
00529   retval->match=0;
00530   retval->uptime=0;
00531 
00532 re_lookup:
00533 
00534   p = bh[SIGHASH(tot,ocnt,quirks,df)];
00535 
00536   while (p)
00537     {
00538     /* Cheap and specific checks first... */
00539     /* psize set to zero means >= PACKET_BIG */
00540     if (p->size) { if (tot ^ p->size) { p = p->next; continue; } }
00541       else if (tot < PACKET_BIG) { p = p->next; continue; }
00542 
00543     if (ocnt ^ p->optcnt) { p = p->next; continue; }
00544 
00545     if (p->zero_stamp ^ (!tstamp)) { p = p->next; continue; }
00546     if (p->df ^ df) { p = p->next; continue; }
00547     if (p->quirks ^ quirks) { p = p->next; continue; }
00548 
00549     /* Check MSS and WSCALE... */
00550     if (!p->mss_mod) {
00551       if (mss ^ p->mss) { p = p->next; continue; }
00552     } else if (mss % p->mss) { p = p->next; continue; }
00553 
00554     if (!p->wsc_mod) {
00555       if (wsc ^ p->wsc) { p = p->next; continue; }
00556     } else if (wsc % p->wsc) { p = p->next; continue; }
00557 
00558     /* Then proceed with the most complex WSS check... */
00559     switch (p->wsize_mod)
00560       {
00561       case 0:
00562         if (wss ^ p->wsize) { p = p->next; continue; }
00563         break;
00564       case MOD_CONST:
00565         if (wss % p->wsize) { p = p->next; continue; }
00566         break;
00567       case MOD_MSS:
00568         if (mss && !(wss % mss))
00569           {
00570           if ((wss / mss) ^ p->wsize) { p = p->next; continue; }
00571           }
00572         else if (!(wss % 1460))
00573           {
00574           if ((wss / 1460) ^ p->wsize) { p = p->next; continue; }
00575           }
00576         else { p = p->next; continue; }
00577         break;
00578       case MOD_MTU:
00579         if (mss && !(wss % (mss+40)))
00580           {
00581           if ((wss / (mss+40)) ^ p->wsize) { p = p->next; continue; }
00582           }
00583         else if (!(wss % 1500))
00584           {
00585           if ((wss / 1500) ^ p->wsize) { p = p->next; continue; }
00586           }
00587         else { p = p->next; continue; }
00588         break;
00589       }
00590 
00591     /* Numbers agree. Let's check options */
00592     for (j=0;j<ocnt;j++)
00593       if (p->opt[j] ^ op[j]) goto continue_search;
00594 
00595     /* Check TTLs last because we might want to go fuzzy. */
00596     if (p->ttl < ttl)
00597       {
00598       if ( mode != RST_FINGERPRINT_MODE )fuzzy = p;
00599       p = p->next;
00600       continue;
00601       }
00602 
00603     /* Naah... can't happen ;-) */
00604     if (!p->no_detail)
00605       if (p->ttl - ttl > MAXDIST)
00606         {
00607         if (mode != RST_FINGERPRINT_MODE ) fuzzy = p;
00608         p = p->next;
00609         continue;
00610         }
00611 
00612 continue_fuzzy:
00613 
00614     /* Match! */
00615     id = p->line;
00616     if (mss & wss)
00617       {
00618       if (p->wsize_mod == MOD_MSS)
00619         {
00620         if ((wss % mss) && !(wss % 1460)) retval->gadgets|=GADGETNAT;
00621         }
00622       else if (p->wsize_mod == MOD_MTU)
00623         {
00624         if ((wss % (mss+40)) && !(wss % 1500)) retval->gadgets|=GADGETNAT2;
00625         }
00626       }
00627 
00628     retval->os=p->os;
00629     retval->desc=p->desc;
00630     retval->dist=p->ttl-ttl;
00631 
00632     if (ecn) retval->gadgets|=GADGETECN;
00633     if (orig_df ^ df) retval->gadgets|=GADGETFIREWALL;
00634 
00635     if (p->generic) retval->match=MATCHGENERIC;
00636     if (fuzzy_now) retval->match=MATCHFUZZY;
00637 
00638     if (!p->no_detail && tstamp)
00639       {
00640       retval->uptime=tstamp/360000;
00641       retval->gadgets|=GADGETUPTIME;
00642       }
00643 
00644     return id;
00645 
00646 continue_search:
00647 
00648     p = p->next;
00649 
00650     }
00651 
00652   if (!df) { df = 1; goto re_lookup; } //not found with df=0 do df=1
00653 
00654   if (fuzzy)
00655     {
00656     df = orig_df;
00657     fuzzy_now = 1;
00658     p = fuzzy;
00659     fuzzy = 0;
00660     goto continue_fuzzy;
00661     }
00662 
00663   if (mss & wss)
00664     {
00665     if ((wss % mss) && !(wss % 1460)) retval->gadgets|=GADGETNAT;
00666     else if ((wss % (mss+40)) && !(wss % 1500)) retval->gadgets|=GADGETNAT2;
00667     }
00668 
00669   if (ecn) retval->gadgets|=GADGETECN;
00670 
00671   if (tstamp)
00672     {
00673     retval->uptime=tstamp/360000;
00674     retval->gadgets|=GADGETUPTIME;
00675     }
00676 
00677   return id;
00678   }

int OSFingerprint::Get_OS_From_SYN struct os_type retval,
uint16  tot,
uint8  DF_flag,
uint8  TTL,
uint16  WSS,
uint8  ocnt,
uint8 op,
uint16  MSS,
uint8  win_scale,
uint32  tstamp,
uint32  quirks,
uint8  ecn
const
 

void OSFingerprint::load_config char *  file  ) 
 

Definition at line 283 of file OSFinger.cc.

References bh, collide(), Error(), file, gencnt, MAXLINE, MAXOPT, MAXSIGS, MOD_CONST, MOD_MSS, MOD_MTU, mode, p, QUIRK_ACK, QUIRK_BROKEN, QUIRK_DATA, QUIRK_FLAGS, QUIRK_IPOPT, QUIRK_PAST, QUIRK_RSTACK, QUIRK_SEQ0, QUIRK_SEQEQ, QUIRK_T2, QUIRK_URG, QUIRK_X2, QUIRK_ZEROID, RST_FINGERPRINT_MODE, search_for_file(), sig, sigcnt, SIGHASH, sscanf(), TCPOPT_EOL, TCPOPT_MAXSEG, TCPOPT_NOP, TCPOPT_SACK_PERMITTED, TCPOPT_TIMESTAMP, TCPOPT_WINDOW, tolower(), toupper(), uint32, and uint8.

Referenced by OSFingerprint().

00284   {
00285   uint32 ln=0;
00286   char buf[MAXLINE];
00287   char* p;
00288   FILE* c = search_for_file( file, "osf", 0);
00289 
00290   if (!c)
00291     {
00292     Error("Can't open OS passive fingerprinting signature file", file);
00293     return;
00294     }
00295   sigcnt=0; //every time we read config we reset it to 0;
00296   while ((p=fgets(buf,sizeof(buf),c)))
00297     {
00298     uint32 l;
00299 
00300     char obuf[MAXLINE],genre[MAXLINE],desc[MAXLINE],quirks[MAXLINE];
00301     char w[MAXLINE],sb[MAXLINE];
00302     char* gptr = genre;
00303     uint32 t,d,s;
00304     struct fp_entry* e;
00305 
00306     ln++;
00307 
00308     /* Remove leading and trailing blanks */
00309     while (isspace(*p)) p++;
00310     l=strlen(p);
00311     while (l && isspace(*(p+l-1))) *(p+(l--)-1)=0;
00312         
00313     /* Skip empty lines and comments */
00314     if (!l) continue;
00315     if (*p == '#') continue;
00316 
00317     if (sscanf(p,"%[0-9%*()ST]:%d:%d:%[0-9()*]:%[^:]:%[^ :]:%[^:]:%[^:]",
00318                   w,         &t,&d,sb,     obuf, quirks,genre,desc) != 8)
00319       Error("OS fingerprinting: Syntax error in p0f signature config line %d.\n",(uint32)ln);
00320 
00321     gptr = genre;
00322 
00323     if (*sb != '*') s = atoi(sb); else s = 0;
00324 
00325 reparse_ptr:
00326 
00327     switch (*gptr)
00328       {
00329       case '-': sig[sigcnt].userland = 1; gptr++; goto reparse_ptr;
00330       case '*': sig[sigcnt].no_detail = 1; gptr++; goto reparse_ptr;
00331       case '@': sig[sigcnt].generic = 1; gptr++; gencnt++; goto reparse_ptr;
00332       case 0: Error("OS fingerprinting: Empty OS genre in line",(uint32)ln);
00333       }
00334 
00335     sig[sigcnt].os     = strdup(gptr);
00336     sig[sigcnt].desc   = strdup(desc);
00337     sig[sigcnt].ttl    = t;
00338     sig[sigcnt].size   = s;
00339     sig[sigcnt].df     = d;
00340  
00341     if (w[0] == '*')
00342       {
00343       sig[sigcnt].wsize = 1;
00344       sig[sigcnt].wsize_mod = MOD_CONST;
00345       }
00346     else if (tolower(w[0]) == 's')
00347       {
00348       sig[sigcnt].wsize_mod = MOD_MSS;
00349       if (!isdigit(*(w+1)))
00350         Error("OS fingerprinting: Bad Snn value in WSS in line",(uint32)ln);
00351       sig[sigcnt].wsize = atoi(w+1);
00352       }
00353     else if (tolower(w[0]) == 't')
00354       {
00355       sig[sigcnt].wsize_mod = MOD_MTU;
00356       if (!isdigit(*(w+1)))
00357         Error("OS fingerprinting: Bad Tnn value in WSS in line",(uint32)ln);
00358       sig[sigcnt].wsize = atoi(w+1);
00359       }
00360     else if (w[0] == '%')
00361       {
00362       if (!(sig[sigcnt].wsize = atoi(w+1)))
00363         Error("OS fingerprinting: Null modulo for window size in config line",(uint32)ln);
00364       sig[sigcnt].wsize_mod = MOD_CONST;
00365       }
00366     else
00367       sig[sigcnt].wsize = atoi(w);
00368 
00369     /* Now let's parse options */
00370 
00371     p=obuf;
00372 
00373     sig[sigcnt].zero_stamp = 1;
00374 
00375     if (*p=='.') p++;
00376 
00377     while (*p)
00378       {
00379       uint8 optcnt = sig[sigcnt].optcnt;
00380       switch (tolower(*p))
00381         {
00382         case 'n': sig[sigcnt].opt[optcnt] = TCPOPT_NOP;
00383                   break;
00384 
00385         case 'e': sig[sigcnt].opt[optcnt] = TCPOPT_EOL;
00386                   if (*(p+1))
00387                     Error("OS fingerprinting: EOL not the last option, line",(uint32)ln);
00388                   break;
00389 
00390         case 's': sig[sigcnt].opt[optcnt] = TCPOPT_SACK_PERMITTED;
00391                   break;
00392 
00393         case 't': sig[sigcnt].opt[optcnt] = TCPOPT_TIMESTAMP;
00394                   if (*(p+1)!='0')
00395                     {
00396                     sig[sigcnt].zero_stamp=0;
00397                     if (isdigit(*(p+1)))
00398                       Error("OS fingerprinting: Bogus Tstamp specification in line",(uint32)ln);
00399                     }
00400                   break;
00401 
00402         case 'w': sig[sigcnt].opt[optcnt] = TCPOPT_WINDOW;
00403                   if (p[1] == '*')
00404                     {
00405                     sig[sigcnt].wsc = 1;
00406                     sig[sigcnt].wsc_mod = MOD_CONST;
00407                     }
00408                   else if (p[1] == '%')
00409                     {
00410                     if (!(sig[sigcnt].wsc = atoi(p+2)))
00411                       Error("OS fingerprinting: Null modulo for wscale in config line",(uint32)ln);
00412                     sig[sigcnt].wsc_mod = MOD_CONST;
00413                     }
00414                   else if (!isdigit(*(p+1)))
00415                     Error("OS fingerprinting: Incorrect W value in line",(uint32)ln);
00416                   else sig[sigcnt].wsc = atoi(p+1);
00417                   break;
00418 
00419         case 'm': sig[sigcnt].opt[optcnt] = TCPOPT_MAXSEG;
00420                   if (p[1] == '*')
00421                     {
00422                     sig[sigcnt].mss = 1;
00423                     sig[sigcnt].mss_mod = MOD_CONST;
00424                     }
00425                   else if (p[1] == '%')
00426                     {
00427                     if (!(sig[sigcnt].mss = atoi(p+2)))
00428                       Error("OS fingerprinting: Null modulo for MSS in config line",(uint32)ln);
00429                     sig[sigcnt].mss_mod = MOD_CONST;
00430                     }
00431                   else if (!isdigit(*(p+1)))
00432                     Error("OS fingerprinting: Incorrect M value in line",(uint32)ln);
00433                   else sig[sigcnt].mss = atoi(p+1);
00434                   break;
00435 
00436         /* Yuck! */
00437         case '?': if (!isdigit(*(p+1)))
00438                     Error("OS fingerprinting: Bogus ?nn value in line",(uint32)ln);
00439                   else sig[sigcnt].opt[optcnt] = atoi(p+1);
00440                   break;
00441 
00442         default: Error("OS fingerprinting: Unknown TCP option in config line",(uint32)ln);
00443         }
00444 
00445       if (++sig[sigcnt].optcnt >= MAXOPT)
00446         Error("OS fingerprinting: Too many TCP options specified in config line",(uint32)ln);
00447 
00448       /* Skip separators */
00449       do { p++; } while (*p && !isalpha(*p) && *p != '?');
00450 
00451     }
00452  
00453     sig[sigcnt].line = ln;
00454 
00455     p = quirks;
00456 
00457     while (*p)
00458       switch (toupper(*(p++)))
00459         {
00460         case 'E':
00461           Error("OS fingerprinting: Quirk 'E' is obsolete. Remove it, append E to the options. Line",(uint32)ln);
00462 
00463         case 'K':
00464           if ( mode != RST_FINGERPRINT_MODE )
00465             Error("OS fingerprinting: Quirk 'K' is valid only in RST+ (-R) mode (wrong config file?). Line",(uint32)ln);
00466           sig[sigcnt].quirks |= QUIRK_RSTACK;
00467           break;
00468 
00469         case 'Q': sig[sigcnt].quirks |= QUIRK_SEQEQ; break;
00470         case '0': sig[sigcnt].quirks |= QUIRK_SEQ0; break;
00471         case 'P': sig[sigcnt].quirks |= QUIRK_PAST; break;
00472         case 'Z': sig[sigcnt].quirks |= QUIRK_ZEROID; break;
00473         case 'I': sig[sigcnt].quirks |= QUIRK_IPOPT; break;
00474         case 'U': sig[sigcnt].quirks |= QUIRK_URG; break;
00475         case 'X': sig[sigcnt].quirks |= QUIRK_X2; break;
00476         case 'A': sig[sigcnt].quirks |= QUIRK_ACK; break;
00477         case 'T': sig[sigcnt].quirks |= QUIRK_T2; break;
00478         case 'F': sig[sigcnt].quirks |= QUIRK_FLAGS; break;
00479         case 'D': sig[sigcnt].quirks |= QUIRK_DATA; break;
00480         case '!': sig[sigcnt].quirks |= QUIRK_BROKEN; break;
00481         case '.': break;
00482         default: Error("OS fingerprinting: Bad quirk in line",(uint32)ln);
00483         }
00484 
00485     e = bh[SIGHASH(s,sig[sigcnt].optcnt,sig[sigcnt].quirks,d)];
00486 
00487     if (!e)
00488       {
00489       bh[SIGHASH(s,sig[sigcnt].optcnt,sig[sigcnt].quirks,d)] = &sig[sigcnt];
00490       }
00491     else
00492       {
00493       while (e->next) e = e->next;
00494       e->next = &sig[sigcnt];
00495       }
00496 
00497     collide(sigcnt);
00498     if (++sigcnt >= MAXSIGS)
00499       Error("OS fingerprinting: Maximum signature count exceeded.\n");
00500 
00501     }
00502 
00503   fclose(c);
00504 
00505   if (!sigcnt)
00506     Error("OS fingerprinting: no signatures loaded from config file.");
00507 
00508   }

OSFingerprint::PDict int   )  [private]
 


Member Data Documentation

struct fp_entry* OSFingerprint::bh[OSHSIZE] [private]
 

Definition at line 133 of file OSFinger.h.

Referenced by FindMatch(), load_config(), and OSFingerprint().

bool OSFingerprint::err [private]
 

Definition at line 125 of file OSFinger.h.

Referenced by Error(), and OSFingerprint().

uint32 OSFingerprint::gencnt [private]
 

Definition at line 127 of file OSFinger.h.

Referenced by load_config(), and OSFingerprint().

unsigned int OSFingerprint::mode [private]
 

Definition at line 126 of file OSFinger.h.

Referenced by FindMatch(), and load_config().

uint8 OSFingerprint::problems [private]
 

Definition at line 128 of file OSFinger.h.

Referenced by collide(), and OSFingerprint().

struct fp_entry OSFingerprint::sig[MAXSIGS] [private]
 

Definition at line 129 of file OSFinger.h.

Referenced by collide(), load_config(), and OSFingerprint().

uint32 OSFingerprint::sigcnt [private]
 

Definition at line 127 of file OSFinger.h.

Referenced by load_config(), and OSFingerprint().


The documentation for this class was generated from the following files:
Generated on Wed Sep 14 03:11:35 2005 for bro_docs by doxygen 1.3.5