Beispiel #1
0
static void config_parse_sys(u8* val) {

  if (cur_sys) {
    cur_sys = NULL;
    cur_sys_cnt = 0;
  }

  while (*val) {

    u8* nxt;
    u8  is_cl = 0, orig;
    u32 i;

    while (isblank(*val) || *val == ',') val++;

    if (*val == '@') { is_cl = 1; val++; }

    nxt = val;

    while (isalnum(*nxt) || (*nxt && strchr(NAME_CHARS, *nxt))) nxt++;

    if (nxt == val || (*nxt && *nxt != ','))
      FATAL("Malformed sys entry in line %u.", line_no);

    orig = *nxt;
    *nxt = 0;

    if (is_cl) {

      for (i = 0; i < class_cnt; i++)
        if (!strcasecmp((char*)val, (char*)fp_os_classes[i])) break;

      if (i == class_cnt)
        FATAL("Unknown class '%s' in line %u.", val, line_no);

      i |= SYS_CLASS_FLAG;

    } else {

      for (i = 0; i < name_cnt; i++)
        if (!strcasecmp((char*)val, (char*)fp_os_names[i])) break;

      if (i == name_cnt) {
        fp_os_names = DFL_ck_realloc(fp_os_names, (name_cnt + 1) * sizeof(u8*));
        fp_os_names[name_cnt++] = DFL_ck_memdup_str(val, nxt - val);
      }

    }

    cur_sys = DFL_ck_realloc(cur_sys, (cur_sys_cnt + 1) * 4);
    cur_sys[cur_sys_cnt++] = i;

    *nxt = orig;
    val = nxt;

  }

}
Beispiel #2
0
u32 lookup_name_id(u8* name, u8 len) {

  u32 i;

  for (i = 0; i < name_cnt; i++)
    if (!strncasecmp((char*)name, (char*)fp_os_names[i], len)
        && !fp_os_names[i][len]) break;

  if (i == name_cnt) {

    sig_name = name_cnt;

    fp_os_names = DFL_ck_realloc(fp_os_names, (name_cnt + 1) * sizeof(u8*));
    fp_os_names[name_cnt++] = DFL_ck_memdup_str(name, len);

  }

  return i;

}
Beispiel #3
0
static void config_parse_classes(u8* val) {

  while (*val) {

    u8* nxt;

    while (isblank(*val) || *val == ',') val++;

    nxt = val;

    while (isalnum(*nxt)) nxt++;

    if (nxt == val || (*nxt && *nxt != ','))
      FATAL("Malformed class entry in line %u.", line_no);

    fp_os_classes = DFL_ck_realloc(fp_os_classes, (class_cnt + 1) * sizeof(u8*));

    fp_os_classes[class_cnt++] = DFL_ck_memdup_str(val, nxt - val);

    val = nxt;

  }

}
Beispiel #4
0
void tcp_register_sig(u8 to_srv, u8 generic, s32 sig_class, u32 sig_name,
                      u8* sig_flavor, u32 label_id, u32* sys, u32 sys_cnt,
                      u8* val, u32 line_no) {

  s8  ver, win_type, pay_class;
  u8  opt_layout[MAX_TCP_OPT];
  u8  opt_cnt = 0, bad_ttl = 0;

  s32 ittl, olen, mss, win, scale, opt_eol_pad = 0;
  u32 quirks = 0, bucket, opt_hash;

  u8* nxt;

  struct tcp_sig* tsig;
  struct tcp_sig_record* trec;

  /* IP version */

  switch (*val) {
    case '4': ver = IP_VER4; break;
    case '6': ver = IP_VER6; break;
    case '*': ver = -1; break;
    default: FATAL("Unrecognized IP version in line %u.", line_no);
  }

  if (val[1] != ':') FATAL("Malformed signature in line %u.", line_no);

  val += 2;

  /* Initial TTL (possibly ttl+dist or ttl-) */

  nxt = val;
  while (isdigit(*nxt)) nxt++;

  if (*nxt != ':' && *nxt != '+' && *nxt != '-')
    FATAL("Malformed signature in line %u.", line_no);

  ittl = atol((char*)val);
  if (ittl < 1 || ittl > 255) FATAL("Bogus initial TTL in line %u.", line_no);
  val = nxt + 1;

  if (*nxt == '-' && nxt[1] == ':') {

    bad_ttl = 1;
    val += 2;

  } else if (*nxt == '+') {

    s32 ittl_add;

    nxt++;
    while (isdigit(*nxt)) nxt++;
    if (*nxt != ':') FATAL("Malformed signature in line %u.", line_no);

    ittl_add = atol((char*)val);

    if (ittl_add < 0 || ittl + ittl_add > 255)
      FATAL("Bogus initial TTL in line %u.", line_no);

    ittl += ittl_add;
    val = nxt + 1;

  }

  /* Length of IP options */

  nxt = val;
  while (isdigit(*nxt)) nxt++;
  if (*nxt != ':') FATAL("Malformed signature in line %u.", line_no);

  olen = atol((char*)val);
  if (olen < 0 || olen > 255)
    FATAL("Bogus IP option length in line %u.", line_no);

  val = nxt + 1;

  /* MSS */

  if (*val == '*' && val[1] == ':') {

    mss = -1;
    val += 2;

  } else {

    nxt = val;
    while (isdigit(*nxt)) nxt++;
    if (*nxt != ':') FATAL("Malformed signature in line %u.", line_no);

    mss = atol((char*)val);
    if (mss < 0 || mss > 65535) FATAL("Bogus MSS in line %u.", line_no);
    val = nxt + 1;

  }

  /* window size, followed by comma */

  if (*val == '*' && val[1] == ',') {

    win_type = WIN_TYPE_ANY;
    win = 0;
    val += 2;

  } else if (*val == '%') {

    win_type = WIN_TYPE_MOD;

    val++;

    nxt = val;
    while (isdigit(*nxt)) nxt++;
    if (*nxt != ',') FATAL("Malformed signature in line %u.", line_no);

    win = atol((char*)val);
    if (win < 2 || win > 65535) FATAL("Bogus '%%' value in line %u.", line_no);
    val = nxt + 1;

  } else if (!strncmp((char*)val, "mss*", 4) ||
             !strncmp((char*)val, "mtu*", 4)) {

    win_type = (val[1] == 's') ? WIN_TYPE_MSS : WIN_TYPE_MTU;

    val += 4;

    nxt = val;
    while (isdigit(*nxt)) nxt++;
    if (*nxt != ',') FATAL("Malformed signature in line %u.", line_no);

    win = atol((char*)val);
    if (win < 1 || win > 1000)
      FATAL("Bogus MSS/MTU multiplier in line %u.", line_no);

    val = nxt + 1;

  } else {

    win_type = WIN_TYPE_NORMAL;

    nxt = val;
    while (isdigit(*nxt)) nxt++;
    if (*nxt != ',') FATAL("Malformed signature in line %u.", line_no);

    win = atol((char*)val);
    if (win < 0 || win > 65535) FATAL("Bogus window size in line %u.", line_no);
    val = nxt + 1;

  }

  /* Window scale */

  if (*val == '*' && val[1] == ':') {

    scale = -1;
    val += 2;

  } else {

    nxt = val;
    while (isdigit(*nxt)) nxt++;
    if (*nxt != ':') FATAL("Malformed signature in line %u.", line_no);

    scale = atol((char*)val);
    if (scale < 0 || scale > 255)
      FATAL("Bogus window scale in line %u.", line_no);

    val = nxt + 1;

  }

  /* Option layout */

  memset(opt_layout, 0, sizeof(opt_layout));  

  while (*val != ':') {

    if (opt_cnt >= MAX_TCP_OPT)
      FATAL("Too many TCP options in line %u.", line_no);

    if (!strncmp((char*)val, "eol", 3)) {

      opt_layout[opt_cnt++] = TCPOPT_EOL;
      val += 3;

      if (*val != '+')
        FATAL("Malformed EOL option in line %u.", line_no);

      val++;
      nxt = val;
      while (isdigit(*nxt)) nxt++;

      if (!*nxt) FATAL("Truncated options in line %u.", line_no);

      if (*nxt != ':')
        FATAL("EOL must be the last option in line %u.", line_no);

      opt_eol_pad = atol((char*)val);

      if (opt_eol_pad < 0 || opt_eol_pad > 255)
        FATAL("Bogus EOL padding in line %u.", line_no);

      val = nxt;

    } else if (!strncmp((char*)val, "nop", 3)) {

      opt_layout[opt_cnt++] = TCPOPT_NOP;
      val += 3;

    } else if (!strncmp((char*)val, "mss", 3)) {

      opt_layout[opt_cnt++] = TCPOPT_MAXSEG;
      val += 3;

    } else if (!strncmp((char*)val, "ws", 2)) {

      opt_layout[opt_cnt++] = TCPOPT_WSCALE;
      val += 2;

    } else if (!strncmp((char*)val, "sok", 3)) {

      opt_layout[opt_cnt++] = TCPOPT_SACKOK;
      val += 3;

    } else if (!strncmp((char*)val, "sack", 4)) {

      opt_layout[opt_cnt++] = TCPOPT_SACK;
      val += 4;

    } else if (!strncmp((char*)val, "ts", 2)) {

      opt_layout[opt_cnt++] = TCPOPT_TSTAMP;
      val += 2;

    } else if (*val == '?') {

      s32 optno;

      val++;
      nxt = val;
      while (isdigit(*nxt)) nxt++;

      if (*nxt != ':' && *nxt != ',')
        FATAL("Malformed '?' option in line %u.", line_no);

      optno = atol((char*)val);

      if (optno < 0 || optno > 255)
          FATAL("Bogus '?' option in line %u.", line_no);

      opt_layout[opt_cnt++] = optno;

      val = nxt;

    } else {

      FATAL("Unrecognized TCP option in line %u.", line_no);

    }

    if (*val == ':') break;

    if (*val != ',')
      FATAL("Malformed TCP options in line %u.", line_no);

    val++;

  }

  val++;

  opt_hash = hash32(opt_layout, opt_cnt, hash_seed);

  /* Quirks */

  while (*val != ':') {

    if (!strncmp((char*)val, "df", 2)) {

      if (ver == IP_VER6)
        FATAL("'df' is not valid for IPv6 in line %d.", line_no);

      quirks |= QUIRK_DF;
      val += 2;

    } else if (!strncmp((char*)val, "id+", 3)) {

      if (ver == IP_VER6)
        FATAL("'id+' is not valid for IPv6 in line %d.", line_no);

      quirks |= QUIRK_NZ_ID;
      val += 3;

    } else if (!strncmp((char*)val, "id-", 3)) {

      if (ver == IP_VER6)
        FATAL("'id-' is not valid for IPv6 in line %d.", line_no);

      quirks |= QUIRK_ZERO_ID;
      val += 3;

    } else if (!strncmp((char*)val, "ecn", 3)) {

      quirks |= QUIRK_ECN;
      val += 3;

    } else if (!strncmp((char*)val, "0+", 2)) {

      if (ver == IP_VER6)
        FATAL("'0+' is not valid for IPv6 in line %d.", line_no);

      quirks |= QUIRK_NZ_MBZ;
      val += 2;

    } else if (!strncmp((char*)val, "flow", 4)) {

      if (ver == IP_VER4)
        FATAL("'flow' is not valid for IPv4 in line %d.", line_no);

      quirks |= QUIRK_FLOW;
      val += 4;

    } else if (!strncmp((char*)val, "seq-", 4)) {

      quirks |= QUIRK_ZERO_SEQ;
      val += 4;

    } else if (!strncmp((char*)val, "ack+", 4)) {

      quirks |= QUIRK_NZ_ACK;
      val += 4;

    } else if (!strncmp((char*)val, "ack-", 4)) {

      quirks |= QUIRK_ZERO_ACK;
      val += 4;

    } else if (!strncmp((char*)val, "uptr+", 5)) {

      quirks |= QUIRK_NZ_URG;
      val += 5;

    } else if (!strncmp((char*)val, "urgf+", 5)) {

      quirks |= QUIRK_URG;
      val += 5;

    } else if (!strncmp((char*)val, "pushf+", 6)) {

      quirks |= QUIRK_PUSH;
      val += 6;

    } else if (!strncmp((char*)val, "ts1-", 4)) {

      quirks |= QUIRK_OPT_ZERO_TS1;
      val += 4;

    } else if (!strncmp((char*)val, "ts2+", 4)) {

      quirks |= QUIRK_OPT_NZ_TS2;
      val += 4;

    } else if (!strncmp((char*)val, "opt+", 4)) {

      quirks |= QUIRK_OPT_EOL_NZ;
      val += 4;

    } else if (!strncmp((char*)val, "exws", 4)) {

      quirks |= QUIRK_OPT_EXWS;
      val += 4;

    } else if (!strncmp((char*)val, "bad", 3)) {

      quirks |= QUIRK_OPT_BAD;
      val += 3;

    } else {

      FATAL("Unrecognized quirk in line %u.", line_no);

    }

    if (*val == ':') break;

    if (*val != ',')
      FATAL("Malformed quirks in line %u.", line_no);

    val++;

  }

  val++;

  /* Payload class */

  if (!strcmp((char*)val, "*")) pay_class = -1;
  else if (!strcmp((char*)val, "0")) pay_class = 0;
  else if (!strcmp((char*)val, "+")) pay_class = 1;
  else FATAL("Malformed payload class in line %u.", line_no);

  /* Phew, okay, we're done. Now, create tcp_sig... */

  tsig = DFL_ck_alloc(sizeof(struct tcp_sig));

  tsig->opt_hash    = opt_hash;
  tsig->opt_eol_pad = opt_eol_pad;

  tsig->quirks      = quirks;

  tsig->ip_opt_len  = olen;
  tsig->ip_ver      = ver;
  tsig->ttl         = ittl;

  tsig->mss         = mss;
  tsig->win         = win;
  tsig->win_type    = win_type;
  tsig->wscale      = scale;
  tsig->pay_class   = pay_class;

  /* No need to set ts1, recv_ms, match, fuzzy, dist */

  tcp_find_match(to_srv, tsig, 1, 0);

  if (tsig->matched)
    FATAL("Signature in line %u is already covered by line %u.",
          line_no, tsig->matched->line_no);

  /* Everything checks out, so let's register it. */

  bucket = opt_hash % SIG_BUCKETS;

  sigs[to_srv][bucket] = DFL_ck_realloc(sigs[to_srv][bucket],
    (sig_cnt[to_srv][bucket] + 1) * sizeof(struct tcp_sig_record));

  trec = sigs[to_srv][bucket] + sig_cnt[to_srv][bucket];

  sig_cnt[to_srv][bucket]++;

  trec->generic  = generic;
  trec->class_id = sig_class;
  trec->name_id  = sig_name;
  trec->flavor   = sig_flavor;
  trec->label_id = label_id;
  trec->sys      = sys;
  trec->sys_cnt  = sys_cnt;
  trec->line_no  = line_no;
  trec->sig      = tsig;
  trec->bad_ttl  = bad_ttl;

  /* All done, phew. */

}