コード例 #1
0
ファイル: dns.c プロジェクト: epok76/lanmap2
static size_t strip_c0(const char *s, size_t len)
{
  size_t c0 = memcspn(s, len, "\xc0\x00", 2);
  if (c0)
    c0--;
  return c0;
}
コード例 #2
0
ファイル: tivoconn.c プロジェクト: aNeutrino/lanmap2
/**
 * parse a single line of the TivoConnect protocol into a 'kkv' structure
 * "foo=bar\x0a"
 * "AAABCCCDDDD"
 */
static ptrdiff_t do_parse_kv(char *buf, size_t len, kkv *k)
{
  const char *orig = buf; /* save original address */
  size_t l = memcspn(buf, len, "=\x0a", 2);
  k->keystr.start = buf;
  k->keystr.len = l;
  strlower(k->keystr.start, k->keystr.len);
  k->key = str2key(&k->keystr);
  buf += l, len -= l;
  l = memspn(buf, len, "=", 1);
  buf += l, len -= l;
  k->val.start = buf;
  l = memcspn(buf, len, "\x0a", 1);
  k->val.len = l;
  buf += l, len -= l;
  l = memspn(buf, len, "\x0a", 1);
  buf += l, len -= l;
  return buf - orig;
}
コード例 #3
0
ファイル: rasadv.c プロジェクト: aNeutrino/lanmap2
/**
 * consume a single token of the pattern "[^;]*;", write it's start and 
 * length in 'p' and return the total number of bytes consumed
 */
static size_t do_parse_token(char *buf, size_t len, ptrlen *p)
{
  size_t bytes;
  p->start = buf;
  bytes = memcspn(buf, len, "=\x0a\x00", 3);
  p->len = bytes;
  if (bytes < len)
    bytes++;
  return bytes;
}
コード例 #4
0
ファイル: http.c プロジェクト: aNeutrino/lanmap2
// FIXME: "GET /common/jquery.autocomplete.js HTTP/1.1\x0d\x0a" -> HTTP req meth=HTT uri=/1.1 304 Not Modified
static ptrdiff_t do_parse_req(char *buf, size_t len, http_req *r)
{
  const char *orig = buf;
  size_t l = memcspn(buf, len, " \r\n", 3);
  if (l > 0) {
    /* method */
    r->meth.start = buf;
    r->meth.len = l;
    buf += l, len -= l;
    /* skip whitespace */
    l = memspn(buf, len, " ", 1);
    buf += l, len -= l;
    /* uri */
    l = memcspn(buf, len, " \r\n", 3);
    r->uri.start = buf;
    r->uri.len = l;
    buf += l, len -= l;
    /* skip whitespace */
    l = memspn(buf, len, " ", 1);
    buf += l, len -= l;
    /* version */
    l = memcspn(buf, len, "\r\n", 2);
    r->ver.start = buf;
    r->ver.len = l;
    printf("HTTP meth=<%.*s> uri=<%.*s> ver=<%.*s> (%u)\n",
      (int)r->meth.len, r->meth.start,
      (int)r->uri.len, r->uri.start,
      (int)r->ver.len, r->ver.start, r->ver.len);
    buf += l, len -= l;
    /* skip newline */
    /* NOTE: we must skip only a single set of "\r\n" */
    if (len >= 2 && '\r' == buf[0] && '\n' == buf[1])
      buf += 2, len -= 2;
  }
#if 1
  /* debug */
  printf("%s ver=<%.*s> buf=<%.*s>\n",
    __func__, (int)r->ver.len, r->ver.start, 20, buf);
  printf("%s -> %u\n", __func__, (unsigned)(buf-orig));
#endif
  return buf - orig;
}
コード例 #5
0
ファイル: http.c プロジェクト: aNeutrino/lanmap2
/**
 * 'buf' points at first char in headers, parse them into 'head' and
 * return bytes consumed
 * @note this function is used by other protocols, such as SSDP
 */
size_t http_parse_headers(char *buf, size_t len, http_headers *head)
{
  struct head_kv *kv = head->h;
  const char *orig = buf,
             *end = buf + len;
  size_t skip = 2;
  head->cnt = 0;
  /* FIXME: make sure we don't go further than 'len' */
#if 0
  printf("%s len=%u buf=%.*s\n",
    __func__, (unsigned)len, (unsigned)len, buf);
#endif
  while (
    buf < end
    && 2 == skip
    && head->cnt < sizeof head->h / sizeof head->h[0]
  ) {
    /* "<A><: ><B><\r\n>" */
    ptrlen_list *pl = &kv->val;
    ptrlen *v = pl->p;
    pl->cnt = 0;
    kv->key.start = buf;
    kv->key.len = memcspn(buf, len, ": \r\n", 4);
    buf += kv->key.len;
    len -= kv->key.len;
    skip = memspn(buf, len, ": ", 2);
    buf += skip;
    len -= skip;
    v->start = buf;
    v->len = memcspn(buf, len, "\r\n", 2);
    pl->cnt++;
    buf += v->len;
    len -= v->len;
    skip = memspn(buf, len, "\r\n", 2);
    buf += skip;
    len -= skip;
    head->cnt++;
    v++;
    kv++;
  }
  return (size_t)(buf - orig);
}
コード例 #6
0
ファイル: gnutella.c プロジェクト: aNeutrino/lanmap2
/**
 * test 'buf' for the beginnings of HTTP-based GNUTELLA protocol content
 */
static int test_header(const char *buf, size_t len, const parse_status *st)
{
  char c[32]; /* temp sscanf buffers */
  unsigned i;
  return len >= 32                          /* minimum possible valid length */
      && 'G' == buf[0]                      /* cheap initial test */
      && memcspn(buf, len, "\r\n", 2) < len /* contains a newline somewhere */
      && (                                  /* validate header line */
        3 == sscanf(buf, "GNUTELLA %31[^ /]/%u.%u\r\n", c, &i, &i) ||
        4 == sscanf(buf, "GNUTELLA/%u.%u %u %31[^\r\n]\r\n", &i, &i, &i, c)
      );
}
コード例 #7
0
ファイル: browse.c プロジェクト: aNeutrino/lanmap2
static int test_smb(const char *buf, size_t len, const parse_status *st)
{
  const smb_hdr *h = (smb_hdr *)st->frame[st->frames-1].off;
  const smb_trans_req *r;
  size_t namelen;
  assert(PROT_SMB == st->frame[st->frames-1].id);
  if (st->frame[st->frames-1].len < sizeof *h)
    return 0;
  if (SMB_Cmd_TransReq != h->cmd)
    return 0;
  r = (smb_trans_req *)((char *)h + sizeof *h);
  namelen = memcspn((char *)r->name, len - sizeof *h + sizeof *r - 1, "\x00", 1);
  return (16 == namelen && 0 == memcmp(r->name, "\\MAILSLOT\\BROWSE", namelen));
}
コード例 #8
0
ファイル: browse.c プロジェクト: aNeutrino/lanmap2
static size_t parse_domwg(const browse *b, char *buf, size_t len, const parse_status *st)
{
  const struct dom_wg *d = (struct dom_wg *)buf;
  size_t bytes,
         namelen;
  if (len < sizeof *d)
    return 0;
  namelen = memcspn((char *)d->master_name, len - sizeof *d, "\x00", 1);
  bytes = sizeof *d + namelen;
  printf("%s %s (bytes=%u):", __FILE__, __func__, (unsigned)bytes);
  dump_chars((char *)d, bytes, stdout);
  fputc('\n', stdout);
  return bytes;
}
コード例 #9
0
ファイル: browse.c プロジェクト: aNeutrino/lanmap2
/**
 * parse host comment at the end;
 * NOTE: this *should* go until the end of the packet; however some instances
 * (i.e. BROWSER over LLC) pad the message with NUL bytes.
 */
static size_t parse_host(const browse *b, char *buf, size_t len, const parse_status *st)
{
  const struct browse_hostann *h = (struct browse_hostann *)buf;
  size_t bytes,
         commentlen;
  if (len < sizeof *h)
    return 0;
  commentlen = memcspn((char *)h->host_comment, len - sizeof *h, "\x00", 1);
  bytes = sizeof *h + commentlen;
  if (bytes > len)
    bytes = len;
  printf("%s %s (bytes=%u):", __FILE__, __func__, (unsigned)bytes);
  dump_chars((char *)h, bytes, stdout);
  fputc('\n', stdout);
  return bytes;
}
コード例 #10
0
ファイル: dns.c プロジェクト: epok76/lanmap2
size_t dns_calc_len_qd(const char *buf, size_t len)
{
  const char *name = (const char *)buf;
  size_t l = memcspn(name, len, "\x00", 1),
         bytes = l;
  if (l < len) {
    const dns_query *q = (dns_query *)(buf + l + 1);
    bytes += 1 + sizeof *q;
  }
#if 0
  assert(bytes <= len);
#endif
  if (bytes > len)
    bytes = len;
  return bytes;
}
コード例 #11
0
ファイル: test_hash.c プロジェクト: hitchiker42/my-code
void remove_from_htable(struct hashtable *ht, char *words, size_t sz){
  uint8_t *ptr = (uint8_t*)words;
  uint32_t word_len;
  long i = 0;
  while(i < sz){
    word_len = memcspn(ptr, sz-i, (uint8_t*)" \n\t", 3);
    //hashtable_add(ht, ptr, word_len, (void*)i);
    hashtable_remove(ht, ptr, word_len);
    i += word_len;
    ptr += word_len;
    while(isspace(*ptr)){
      ptr++;
      i++;
    }
  }
  return;
}
コード例 #12
0
ファイル: browse.c プロジェクト: aNeutrino/lanmap2
static size_t parse_elect(const browse *b, char *buf, size_t len, const parse_status *st)
{
  struct electreq *e = (struct electreq *)buf;
  size_t bytes,
         namelen;
  if (len < sizeof *e)
    return 0;
  namelen = memcspn((char *)e->name, len - sizeof *e, "\x00", 1);
  bytes = sizeof *e + namelen;
  printf("%s %s (bytes=%u):", __FILE__, __func__, (unsigned)bytes);
  dump_chars((char *)e, bytes, stdout);
  fputc('\n', stdout);
  /* fix endianness */
  e->uptime = ltohl(e->uptime);
  assert(bytes == len);
  return bytes;
}
コード例 #13
0
ファイル: smb.c プロジェクト: epok76/lanmap2
/**
 * calculate the length, in bytes, of the next layer after the header
 */
static size_t do_calc_len(const char *buf, size_t len, const smb_hdr *h)
{
  size_t bytes = 0;
  switch ((enum SMB_Cmd)h->cmd) {
  case SMB_Cmd_TransReq:
  { /* TODO: break out into own function */
    smb_trans_req *r = (smb_trans_req *)buf;
    if (sizeof *r > len)
      return len;
    /* calculate length of name */
    bytes = memcspn((char *)r->name, len - sizeof *r - 1, "\x00", 1);
    bytes += sizeof *r; /* includes trailing \0 */
  }
    break;
  default:
    break;
  }
  return bytes;
}
コード例 #14
0
ファイル: dns.c プロジェクト: epok76/lanmap2
static size_t dump_qd(const char *buf, size_t len, FILE *out)
{
  char namebuf[1024];
  const char *name = (const char *)buf;
  size_t namel = memcspn(name, len, "\x00", 1);
  int bytes = 0;
  const dns_query *q = (dns_query *)(buf + namel + 1);
  (void)dump_chars_buf(namebuf, sizeof namebuf, buf, namel);
#if 0
  printf("len=%u name[namel=%u]=%s name[10]=", (unsigned)len, (unsigned)namel, namebuf);
  dump_chars(name, 10, stdout);
  fputc('\n', stdout);
#endif
  bytes = fprintf(out, " qd name=%s type=%hu(%s) class=%hu(%s)\n", 
    namebuf,
    ntohs(q->type), type2str(ntohs(q->type)),
    ntohs(q->class_), class2str(ntohs(q->class_)));
  return bytes;
}
コード例 #15
0
ファイル: http.c プロジェクト: aNeutrino/lanmap2
/**
 * @return number of octets used by this protocol, or zero upon error
 */
size_t http_parse(char *buf, size_t len, parse_frame *f, const parse_status *st, http *h)
{
  size_t      olen = len;
  const char *start = buf,
             *end = buf + len;

  if (test_resphead(buf, len, st)) {
    http_resp *r = &h->data.resp;
    h->type = HTTP_Type_RESP;
    /* TODO: break out to separate function a la do_parse_req() */
    /* something like "HTTP/1.1 301 Moved Permanently" */
    r->ver.start = buf;
    r->ver.len = memcspn(r->ver.start, len, " ", 1);
    r->code.start = r->ver.start + r->ver.len + strspn(r->ver.start + r->ver.len, " ");
    r->code.len = strcspn(r->code.start, " ");
    r->desc.start = r->code.start + r->code.len + strspn(r->code.start + r->code.len, " ");
    r->desc.len = strcspn(r->desc.start, "\r\n");
    buf = r->desc.start + r->desc.len + strspn(r->desc.start + r->desc.len, "\r\n");
    buf += http_parse_headers(buf, len - (buf - start), &r->headers);
    r->contents.start = buf;
    r->contents.len = len-(buf-start);
  } else if (do_test_http_header(buf, len)) {
    /* something like "GET / HTTP/1.1" */
    size_t consumed;
    h->type = HTTP_Type_REQ;
    consumed = do_parse_req(buf, len, &h->data.req);
    if (consumed != 0) {
      buf += consumed, len -= consumed;
      consumed = http_parse_headers(buf, len, &h->data.req.headers);
      buf += consumed, len -= consumed;
      h->data.req.contents.start = buf;
      h->data.req.contents.len = len;
      do_req_rep(&h->data.req, st);
    }
  } else {
    h->type = HTTP_Type_DATA;
    buf += len;
  }
  f->pass = h;
  printf("%s -> %u\n", __func__, (unsigned)(buf-start));
  return olen;
}
コード例 #16
0
ファイル: smb.c プロジェクト: epok76/lanmap2
/**
 * SMB header has been parsed, parse rest of msg
 * @return number of bytes consumed
 */
static size_t do_parse(char *buf, size_t len, const smb_hdr *h)
{
  size_t bytes = 0;
  printf("do_parse len=%u buf=", (unsigned)len);
  dump_chars(buf, len, stdout);
  fputc('\n', stdout);
  switch ((enum SMB_Cmd)h->cmd) {
  case SMB_Cmd_TransReq:
  { /* TODO: break out into own function */
    size_t namelen;
    smb_trans_req *r = (smb_trans_req *)buf;
    if (sizeof *r > len)
      return 0;
    /* convert endianness */
    r->totalparam       = ltohs(r->totalparam);
    r->totaldata        = ltohs(r->totaldata);
    r->maxparam         = ltohs(r->maxparam);
    r->maxdata          = ltohs(r->maxdata);
    r->param            = ltohs(r->param);
    r->paramoffset      = ltohs(r->paramoffset);
    r->data             = ltohs(r->data);
    r->dataoffset       = ltohs(r->dataoffset);
    r->mailslot.opcode  = ltohs(r->mailslot.opcode);
    r->mailslot.priority= ltohs(r->mailslot.priority);
    r->mailslot.class_  = ltohs(r->mailslot.class_);
    r->mailslot.bytes   = ltohs(r->mailslot.bytes);
    /* calculate length of name */
    namelen = memcspn((char *)r->name, len - sizeof *r - 1, "\x00", 1);
    bytes = namelen + sizeof *r; /* includes trailing \0 */
  }
    break;
  default:
    break;
  }
  return bytes;
}
コード例 #17
0
int cURLCamera::Capture( Image &image ) {
  bool frameComplete = false;

  /* MODE_STREAM specific variables */
  bool SubHeadersParsingComplete = false;
  unsigned int frame_content_length = 0;
  std::string frame_content_type;
  bool need_more_data = false;
  int nRet;

  /* Grab the mutex to ensure exclusive access to the shared data */
  lock();

  while ( !frameComplete ) {

    /* If the work thread did a reset, reset our local variables */
    if ( bReset ) {
      SubHeadersParsingComplete = false;
      frame_content_length = 0;
      frame_content_type.clear();
      need_more_data = false;
      bReset = false;
    }

    if ( mode == MODE_UNSET ) {
      /* Don't have a mode yet. Sleep while waiting for data */
      nRet = pthread_cond_wait(&data_available_cond,&shareddata_mutex);
      if ( nRet != 0 ) {
        Error("Failed waiting for available data condition variable: %s",strerror(nRet));
        return -20;
      }
    }

    if ( mode == MODE_STREAM ) {

      /* Subheader parsing */
      while( !SubHeadersParsingComplete && !need_more_data ) {

        size_t crlf_start, crlf_end, crlf_size;
        std::string subheader;

        /* Check if the buffer contains something */
        if ( databuffer.empty() ) {
          /* Empty buffer, wait for data */
          need_more_data = true;
          break;
        }
     
        /* Find crlf start */
        crlf_start = memcspn(databuffer,"\r\n",databuffer.size());
        if ( crlf_start == databuffer.size() ) {
          /* Not found, wait for more data */
          need_more_data = true;
          break;
        }

        /* See if we have enough data for determining crlf length */
        if ( databuffer.size() < crlf_start+5 ) {
          /* Need more data */
          need_more_data = true;
          break;
        }

        /* Find crlf end and calculate crlf size */
        crlf_end = memspn(((const char*)databuffer.head())+crlf_start,"\r\n",5);
        crlf_size = (crlf_start + crlf_end) - crlf_start;

        /* Is this the end of a previous stream? (This is just before the boundary) */
        if ( crlf_start == 0 ) {
          databuffer.consume(crlf_size);
          continue;        
        }

        /* Check for invalid CRLF size */
        if ( crlf_size > 4 ) {
          Error("Invalid CRLF length");
        }

        /* Check if the crlf is \n\n or \r\n\r\n (marks end of headers, this is the last header) */
        if( (crlf_size == 2 && memcmp(((const char*)databuffer.head())+crlf_start,"\n\n",2) == 0) || (crlf_size == 4 && memcmp(((const char*)databuffer.head())+crlf_start,"\r\n\r\n",4) == 0) ) {
          /* This is the last header */
          SubHeadersParsingComplete = true;
        }

        /* Copy the subheader, excluding the crlf */
        subheader.assign(databuffer, crlf_start);

        /* Advance the buffer past this one */
        databuffer.consume(crlf_start+crlf_size);

        Debug(7,"Got subheader: %s",subheader.c_str());

        /* Find where the data in this header starts */
        size_t subheader_data_start = subheader.rfind(' ');
        if ( subheader_data_start == std::string::npos ) {
          subheader_data_start = subheader.find(':');
        }

        /* Extract the data into a string */
        std::string subheader_data = subheader.substr(subheader_data_start+1, std::string::npos);

        Debug(8,"Got subheader data: %s",subheader_data.c_str());

        /* Check the header */
        if(strncasecmp(subheader.c_str(),content_length_match,content_length_match_len) == 0) {  
          /* Found the content-length header */
          frame_content_length = atoi(subheader_data.c_str());
          Debug(6,"Got content-length subheader: %d",frame_content_length);
        } else if(strncasecmp(subheader.c_str(),content_type_match,content_type_match_len) == 0) { 
          /* Found the content-type header */
          frame_content_type = subheader_data;
          Debug(6,"Got content-type subheader: %s",frame_content_type.c_str());
        }

      }

      /* Attempt to extract the frame */
      if(!need_more_data) {
        if(!SubHeadersParsingComplete) {
          /* We haven't parsed all headers yet */
          need_more_data = true;
        } else if ( ! frame_content_length ) {
          /* Invalid frame */
          Error("Invalid frame: invalid content length");
        } else if ( frame_content_type != "image/jpeg" ) {
          /* Unsupported frame type */
          Error("Unsupported frame: %s",frame_content_type.c_str());
        } else if(frame_content_length > databuffer.size()) {
          /* Incomplete frame, wait for more data */
          need_more_data = true;
        } else {
          /* All good. decode the image */
          image.DecodeJpeg(databuffer.extract(frame_content_length), frame_content_length, colours, subpixelorder);
          frameComplete = true;
        }
      }

      /* Attempt to get more data */
      if(need_more_data) {
        nRet = pthread_cond_wait(&data_available_cond,&shareddata_mutex);
        if(nRet != 0) {
          Error("Failed waiting for available data condition variable: %s",strerror(nRet));
          return -18;
        }
        need_more_data = false;
      }

    } else if(mode == MODE_SINGLE) { 
      /* Check if we have anything */
      if (!single_offsets.empty()) {
        if( (single_offsets.front() > 0) && (databuffer.size() >= single_offsets.front()) ) {
          /* Extract frame */
          image.DecodeJpeg(databuffer.extract(single_offsets.front()), single_offsets.front(), colours, subpixelorder);
          single_offsets.pop_front();
          frameComplete = true;
        } else {
          /* This shouldn't happen */
          Error("Internal error. Attempting recovery");
          databuffer.consume(single_offsets.front());
          single_offsets.pop_front();
        }
      } else {
        /* Don't have a frame yet, wait for the request complete condition variable */
        nRet = pthread_cond_wait(&request_complete_cond,&shareddata_mutex);
        if(nRet != 0) {
          Error("Failed waiting for request complete condition variable: %s",strerror(nRet));
          return -19;
        }
      }
    } else {
      /* Failed to match content-type */
      Fatal("Unable to match Content-Type. Check URL, username and password");
    } /* mode */

  } /* frameComplete loop */

  /* Release the mutex */
  unlock();

  if(!frameComplete)
    return -1;

  return 1;
}