コード例 #1
0
ファイル: nsock_pcap.c プロジェクト: alex-chan/nmap
/* Remember that pcap descriptor is in nonblocking state. */
int do_actual_pcap_read(msevent *nse) {
  mspcap *mp = (mspcap *)nse->iod->pcap;
  nsock_pcap npp;
  nsock_pcap *n;
  struct pcap_pkthdr *pkt_header;
  const unsigned char *pkt_data = NULL;
  int rc;

  memset(&npp, 0, sizeof(nsock_pcap));

  if (nse->iod->nsp->tracelevel > 2)
    nsock_trace(nse->iod->nsp, "PCAP do_actual_pcap_read TEST (IOD #%li) (EID #%li)",
                nse->iod->id, nse->id);

  assert( FILESPACE_LENGTH(&(nse->iobuf)) == 0 );

  rc = pcap_next_ex(mp->pt, &pkt_header, &pkt_data);
  switch(rc) {
    case 1: /* read good packet  */
      #ifdef PCAP_RECV_TIMEVAL_VALID
      npp.ts     = pkt_header->ts;
      #else
      /* on these platforms time received from pcap is invalid. It's better to set current time */
      memcpy(&npp.ts, nsock_gettimeofday(), sizeof(struct timeval));
      #endif
      npp.len    = pkt_header->len;
      npp.caplen = pkt_header->caplen;
      npp.packet = pkt_data;

      fscat(&(nse->iobuf), (char *)&npp, sizeof(npp));
      fscat(&(nse->iobuf), (char *)pkt_data, npp.caplen);
      n = (nsock_pcap *)FILESPACE_STR(&(nse->iobuf));
      n->packet = (unsigned char *)FILESPACE_STR(&(nse->iobuf)) + sizeof(npp);

      if (nse->iod->nsp->tracelevel > 2)
        nsock_trace(nse->iod->nsp, "PCAP do_actual_pcap_read READ (IOD #%li) (EID #%li) size=%i",
                    nse->iod->id, nse->id, pkt_header->caplen);
      return(1);

    case 0: /* timeout */
      return(0);

    case -1: /* error */
      fatal("pcap_next_ex() fatal error while reading from pcap: %s\n", pcap_geterr(mp->pt));
      break;

    case -2: /* no more packets in savefile (if reading from one) */
    default:
      assert(0);
  }
  return 0;
}
コード例 #2
0
void nse_readpcap(nsock_event nsee,
	const unsigned char **l2_data, size_t *l2_len,
	const unsigned char **l3_data, size_t *l3_len,
	size_t *packet_len, struct timeval *ts) 
{
	msevent *nse = (msevent *)nsee;
	msiod  *iod = nse->iod;
	mspcap *mp = (mspcap *) iod->pcap;

	size_t l2l;
	size_t l3l;
	
	nsock_pcap *n = (nsock_pcap *) FILESPACE_STR(&(nse->iobuf));
	if(FILESPACE_LENGTH(&(nse->iobuf)) < sizeof(nsock_pcap)){
		if(l2_data) *l2_data = NULL;
		if(l2_len ) *l2_len  = 0;
		if(l3_data) *l3_data = NULL;
		if(l3_len ) *l3_len  = 0;
		if(packet_len) *packet_len = 0;
		return;
	}
	
	l2l = MIN(mp->l3_offset, n->caplen);
	l3l = MAX(0, n->caplen-mp->l3_offset);
	
	if(l2_data) *l2_data = n->packet;
	if(l2_len ) *l2_len  = l2l;
	if(l3_data) *l3_data = l3l>0? n->packet+l2l : NULL;
	if(l3_len ) *l3_len  = l3l;
	if(packet_len) *packet_len = n->len;
	if(ts) *ts = n->ts;
	return;
}
コード例 #3
0
ファイル: nsock_core.c プロジェクト: alex-chan/nmap
void handle_read_result(mspool *ms, msevent *nse, enum nse_status status) {
  unsigned int count;
  char *str;
  int rc, len;
  msiod *iod = nse->iod;

  if (status == NSE_STATUS_TIMEOUT) {
    nse->event_done = 1;
    if (FILESPACE_LENGTH(&nse->iobuf) > 0)
      nse->status = NSE_STATUS_SUCCESS;
    else
      nse->status = NSE_STATUS_TIMEOUT;
  } else if (status == NSE_STATUS_CANCELLED) {
    nse->status = status;
    nse->event_done = 1;
  } else if (status == NSE_STATUS_SUCCESS) {
    rc = do_actual_read(ms, nse);
    /* printf("DBG: Just read %d new bytes%s.\n", rc, iod->ssl? "( SSL!)" : ""); */
    if (rc > 0) {
      nse->iod->read_count += rc;
      /* We decide whether we have read enough to return */
      switch(nse->readinfo.read_type) {
        case NSOCK_READ:
          nse->status = NSE_STATUS_SUCCESS;
          nse->event_done = 1;
          break;
        case NSOCK_READBYTES:
          if (FILESPACE_LENGTH(&nse->iobuf) >= nse->readinfo.num) {
            nse->status = NSE_STATUS_SUCCESS;
            nse->event_done = 1;
          }
          /* else we are not done */
          break;
        case NSOCK_READLINES:
          /* Lets count the number of lines we have ... */
          count = 0;
          len = FILESPACE_LENGTH(&nse->iobuf) -1;
          str = FILESPACE_STR(&nse->iobuf);
          for (count=0; len >= 0; len--) {
            if (str[len] == '\n') {
              count++;
              if ((int)count >= nse->readinfo.num)
                break;
            }
          }
          if ((int) count >= nse->readinfo.num) {
            nse->event_done = 1;
            nse->status = NSE_STATUS_SUCCESS;
          }
          /* Else we are not done */
          break;
        default:
          assert(0);
          break; /* unreached */
      }
    }
  } else {
    assert(0); /* Currently we only know about TIMEOUT, CANCELLED, and SUCCESS callbacks */
  }

  /* If there are no more reads for this IOD, we are done reading on the socket
   * so we can take it off the descriptor list ... */
  if (nse->event_done && iod->sd >= 0) {
    int ev = EV_NONE;

#if HAVE_OPENSSL
    if (nse->iod->ssl != NULL)
      ev |= socket_count_dec_ssl_desire(nse);
    else
#endif
      ev |= socket_count_read_dec(nse->iod);
    update_events(nse->iod, ms, EV_NONE, ev);
  }
}
コード例 #4
0
ファイル: nsock_core.c プロジェクト: alex-chan/nmap
void handle_write_result(mspool *ms, msevent *nse, enum nse_status status) {
  int bytesleft;
  char *str;
  int res;
  int err;
  msiod *iod = nse->iod;

  if (status == NSE_STATUS_TIMEOUT || status == NSE_STATUS_CANCELLED) {
    nse->event_done = 1;
    nse->status = status;
  } else if (status == NSE_STATUS_SUCCESS) {
    str = FILESPACE_STR(&nse->iobuf) + nse->writeinfo.written_so_far;
    bytesleft = FILESPACE_LENGTH(&nse->iobuf) - nse->writeinfo.written_so_far;
    if (nse->writeinfo.written_so_far > 0)
      assert(bytesleft > 0);
#if HAVE_OPENSSL
    if (iod->ssl)
      res = SSL_write(iod->ssl, str, bytesleft);
    else
#endif
      if (nse->writeinfo.dest.ss_family == AF_UNSPEC)
        res = send(nse->iod->sd, str, bytesleft, 0);
      else
        res = sendto(nse->iod->sd, str, bytesleft, 0, (struct sockaddr *)&nse->writeinfo.dest, (int)nse->writeinfo.destlen);
    if (res == bytesleft) {
      nse->event_done = 1;
      nse->status = NSE_STATUS_SUCCESS;
    } else if (res >= 0) {
      nse->writeinfo.written_so_far += res;
    } else {
      assert(res == -1);
      if (iod->ssl) {
#if HAVE_OPENSSL
        err = SSL_get_error(iod->ssl, res);
        if (err == SSL_ERROR_WANT_READ) {
          int evclr;

          evclr = socket_count_dec_ssl_desire(nse);
          socket_count_read_inc(iod);
          update_events(iod, ms, EV_READ, evclr);
          nse->sslinfo.ssl_desire = err;
        } else if (err == SSL_ERROR_WANT_WRITE) {
          int evclr;

          evclr = socket_count_dec_ssl_desire(nse);
          socket_count_write_inc(iod);
          update_events(iod, ms, EV_WRITE, evclr);
          nse->sslinfo.ssl_desire = err;
        } else {
          /* Unexpected error */
          nse->event_done = 1;
          nse->status = NSE_STATUS_ERROR;
          nse->errnum = EIO;
        }
#endif
      } else {
        err = socket_errno();
        if (err != EINTR && err != EAGAIN
#ifndef WIN32
            && err != EBUSY
#endif
            ) {
          nse->event_done = 1;
          nse->status = NSE_STATUS_ERROR;
          nse->errnum = err;
        }
      }
    }

    if (res >= 0)
      nse->iod->write_count += res;
  }

  if (nse->event_done && nse->iod->sd != -1) {
    int ev = EV_NONE;

#if HAVE_OPENSSL
    if (nse->iod->ssl != NULL)
      ev |= socket_count_dec_ssl_desire(nse);
    else
#endif
      ev |= socket_count_write_dec(nse->iod);
    update_events(nse->iod, ms, EV_NONE, ev);
  }
  return;
}