示例#1
0
void indicator_play(struct ausrv *ausrv, int type, uint32_t vol, int dur)
{
    struct stream *stream  = stream_find(ausrv, ind_stream);
    uint32_t       timeout = dur ? dur : MAX_TONE_LENGTH;
    
    if (stream != NULL) {
        dtmf_stop(ausrv);
        indicator_stop(ausrv, PRESERVE_STREAM);
    }
    else {
        stream = stream_create(ausrv, ind_stream, NULL, 0,
                               tone_write_callback,
                               tone_destroy_callback,
                               ind_props,
                               NULL);

        if (stream == NULL) {
            LOG_ERROR("%s(): Can't create stream", __FUNCTION__);
            return;
        }
    }

    vol = (vol_scale * vol) / 100;
    
    switch (type) {
        
    case TONE_DIAL:
        switch (standard) {
        case STD_CEPT:
            tone_create(stream, type, 425, vol, 1000000, 1000000, 0,0);
            break;
        case STD_ANSI:
        case STD_ATNT:
            tone_create(stream, type, 350, (vol*7)/10, 1000000, 1000000, 0,0);
            tone_create(stream, type, 440, (vol*7)/10, 1000000, 1000000, 0,0);
            break;
        case STD_JAPAN:
            tone_create(stream, type, 400, vol, 1000000, 1000000, 0,0);
            break;
        }
        timeout = MAX_TONE_LENGTH;
        break;
        
    case TONE_BUSY:
        switch (standard) {
        case STD_CEPT:
            tone_create(stream, type, 425, vol, 1000000, 500000, 0,dur);
            break;
        case STD_ANSI:
        case STD_ATNT:
            tone_create(stream, type, 480, (vol*7)/10, 1000000, 500000, 0,dur);
            tone_create(stream, type, 620, (vol*7)/10, 1000000, 500000, 0,dur);
            break;
        case STD_JAPAN:
            tone_create(stream, type, 400, vol, 1000000, 500000, 0,dur);
            break;
        }
        break;
        
    case TONE_CONGEST:
        switch (standard) {
        case STD_CEPT:
            tone_create(stream, type, 425, vol, 400000, 200000, 0,dur);
            break;
        case STD_ANSI:
        case STD_ATNT:
            tone_create(stream, type, 480, (vol*7)/10, 500000, 250000, 0,dur);
            tone_create(stream, type, 620, (vol*7)/10, 500000, 250000, 0,dur);
            break;
        case STD_JAPAN:
            /*
             * this is non-standard, but
             * we play busy tone instead of being silent
             */
            tone_create(stream, type, 400, vol, 1000000, 500000, 0,dur);
            break;
        }
        break;
        
    case TONE_RADIO_ACK:
        switch (standard) {
        case STD_CEPT:
        case STD_ANSI:
        case STD_ATNT:
            tone_create(stream, type, 425, vol, 200000, 200000, 0,200000);
            timeout = MAX_SHORT_TONE_LENGTH;
            break;
        case STD_JAPAN:
            tone_create(stream, type, 400, vol, 3000000, 1000000, 0,0);
            /* The Japan standard tone is repeating, so I guess we need to wait 60s anyway. */
            timeout = MAX_TONE_LENGTH;
            break;
        }
        break;
        
    case TONE_RADIO_NA:
        switch (standard) {
        case STD_CEPT:
        case STD_ANSI:
        case STD_ATNT:
            tone_create(stream, type, 425, vol, 400000, 200000, 0,1200000);
            break;
        case STD_JAPAN:
            break;
        }
        timeout = MAX_SHORT_TONE_LENGTH;
        break;
        
    case TONE_ERROR:
        switch (standard) {
        case STD_CEPT:
        case STD_ANSI:
        case STD_ATNT:
            tone_create(stream, type,  900, vol, 2000000, 333333, 0,dur);
            tone_create(stream, type, 1400, vol, 2000000, 332857, 333333,dur);
            tone_create(stream, type, 1800, vol, 2000000, 300000, 666190,dur);
            break;
        case STD_JAPAN:
            /*
             * this is non-standard, but
             * we play busy tone instead of being silent
             */
            tone_create(stream, type, 400, vol, 1000000, 500000, 0,dur);
            break;
        }
        break;
        
    case TONE_WAIT:
        switch (standard) {
        case STD_CEPT:
            tone_create(stream,type, 425, vol, 800000,200000, 0,1000000);
            tone_create(stream,type, 425, vol, 800000,200000, 4000000,1000000);
            break;
        case STD_ANSI:
            tone_create(stream,type, 440, vol, 300000,300000, 0,300000);
            tone_create(stream,type, 440, vol, 10000000,100000, 10000000,0);
            tone_create(stream,type, 440, vol, 10000000,100000, 10200000,0);
            break;
        case STD_ATNT:
            tone_create(stream, type, 440, vol, 4000000, 200000, 0, 0);
            tone_create(stream, type, 440, vol, 4000000, 200000, 500000, 0);
            break;
        case STD_JAPAN:
            break;
        }
        timeout = MAX_TONE_LENGTH;
        break;
        
    case TONE_RING:
        switch (standard) {
        case STD_CEPT:
            tone_create(stream, type, 425, vol, 5000000, 1000000, 0,0);
            break;
        case STD_ANSI:
        case STD_ATNT:
            tone_create(stream, type, 440, (vol*7)/10, 6000000, 2000000, 0,0);
            tone_create(stream, type, 480, (vol*7)/10, 6000000, 2000000, 0,0);
            break;
        case STD_JAPAN:
            break;
        }
        timeout = MAX_TONE_LENGTH;
        break;
        
    default:
        LOG_ERROR("%s(): invalid type %d", __FUNCTION__, type);
        break;
    }

    stream_set_timeout(stream, timeout);
}
示例#2
0
tree_cell * nasl_recv(lex_ctxt * lexic)
{
 char * data;
 int len = get_int_local_var_by_name(lexic, "length", -1);
 int min_len = get_int_local_var_by_name(lexic, "min", -1);
 int soc = get_int_local_var_by_name(lexic, "socket", 0);
 int to  = get_int_local_var_by_name(lexic, "timeout", lexic->recv_timeout);
 fd_set rd;
 struct timeval tv;
 int new_len = 0;
 tree_cell * retc;
 int type = -1, opt_len = sizeof(type);
 int e;
 

 if(len <= 0 || soc <= 0)
	 return NULL;

 if (to <= 0) to = 5;

 tv.tv_sec = to;
 tv.tv_usec = 0; 


 data = emalloc(len);
 if ( !fd_is_stream(soc) )
 	e = getsockopt(soc, SOL_SOCKET, SO_TYPE, &type, &opt_len);
  else
	e = -1;
 
 if(e == 0 && type == SOCK_DGRAM)
 {
 /*
  * As UDP packets may be lost, we retry up to 5 times
  */
 int retries = 5;
 int i;
 
 tv.tv_sec = to / retries;
 tv.tv_usec = (to % retries) *  100000;
 
 for(i=0;i<retries;i++)
 {
  FD_ZERO(&rd);
  FD_SET(soc, &rd);

  
  if(!to || select(soc+1, &rd, NULL, NULL, &tv)>0)
  {
   int e;
   e = recv(soc, data+new_len, len-new_len, 0);
  
   if(e <= 0)
   {
    if(!new_len)
    {
     efree(&data); 
     return NULL;
    }
    else break;
   }
   else new_len+=e;
   if(new_len >= len)break;
   break; /* UDP data is never fragmented */
  }
  else 
  {
   /* 
    * The packet may have been lost en route - we resend it
    */
   char * data;
   int len;
   
   data = get_udp_data(lexic->script_infos, soc, &len);
   if(data != NULL)send(soc, data, len, 0);
   tv.tv_sec = to / retries;
   tv.tv_usec = ( to % retries) * 100000;
   }
  }
 }
 else {	
 	int old = stream_set_timeout(soc, tv.tv_sec);
 	new_len = read_stream_connection_min(soc, data, min_len, len);
	stream_set_timeout(soc, old);
      }
 if(new_len > 0)
 {
  retc = alloc_tree_cell(0, NULL);
  retc->type = CONST_DATA;
  retc->x.str_val = nasl_strndup(data, new_len);
  retc->size = new_len;
  efree(&data);
  return retc;
 }
 else {
	 efree(&data);
	 return NULL;
  }
}
示例#3
0
static int proto_tftp_process(void *proto_priv, struct packet *p, struct proto_process_stack *stack, unsigned int stack_index) {

	struct proto_process_stack *s = &stack[stack_index];
	struct proto_process_stack *s_prev = &stack[stack_index - 1];
	struct proto_process_stack *s_next = &stack[stack_index + 1];

	if (conntrack_get_unique_from_parent(stack, stack_index) != POM_OK) {
		pomlog(POMLOG_ERR "Could not get a conntrack entry");
		return PROTO_ERR;
	}

	struct proto_tftp_conntrack_priv *priv = s->ce->priv;
	if (!priv) {
		priv = malloc(sizeof(struct proto_tftp_conntrack_priv));
		if (!priv) {
			pom_oom(sizeof(struct proto_tftp_conntrack_priv));
			conntrack_unlock(s->ce);
			return POM_ERR;
		}
		memset(priv, 0, sizeof(struct proto_tftp_conntrack_priv));

		s->ce->priv = priv;
	}

	if (priv->flags & PROTO_TFTP_CONN_INVALID) {
		conntrack_unlock(s->ce);
		return PROTO_INVALID;
	}

	void *pload = s->pload;
	uint32_t plen = s->plen;


	// proto_tftp only process up to the opcode field
	// afterwards, it's up to the analyzer to parse the rest

	uint16_t opcode = ntohs(*((uint16_t*)pload));
	PTYPE_UINT16_SETVAL(s->pkt_info->fields_value[proto_tftp_field_opcode], opcode);
	pload += sizeof(uint16_t);
	plen -= sizeof(uint16_t);

	s_next->pload = pload;
	s_next->plen = plen;

	switch (opcode) {
		case tftp_rrq:
		case tftp_wrq: {

			// Find the filename
			char *filename = pload;
			char *mode = memchr(filename, 0, plen - 1);
			if (!mode) {
				priv->flags |= PROTO_TFTP_CONN_INVALID;
				conntrack_unlock(s->ce);
				debug_tftp("End of filename not found in read/write request");
				return PROTO_INVALID;
			}
			mode++;
			ssize_t filename_len = mode - filename;

			char *end = memchr(mode, 0, plen - filename_len);
			if (!end) {
				priv->flags |= PROTO_TFTP_CONN_INVALID;
				conntrack_unlock(s->ce);
				debug_tftp("End of mode not found in read/write request");
				return PROTO_INVALID;
			}
			debug_tftp("Got read/write request for filename \"%s\" with mode \"%s\"", filename, mode);

			struct conntrack_session *session = conntrack_session_get(s->ce);
			if (!session) {
				conntrack_unlock(s->ce);
				return POM_ERR;
			}

			// We don't need to do anything with the session
			conntrack_session_unlock(session);

			struct proto_expectation *expt = proto_expectation_alloc_from_conntrack(s_prev->ce, proto_tftp, NULL);

			if (!expt) {
				conntrack_unlock(s->ce);
				return PROTO_ERR;
			}

			proto_expectation_set_field(expt, -1, NULL, POM_DIR_REV);

			if (proto_expectation_add(expt, session, PROTO_TFTP_EXPT_TIMER, p->ts) != POM_OK) {
				conntrack_unlock(s->ce);
				proto_expectation_cleanup(expt);
				return PROTO_ERR;
			}

			break;
		}
		case tftp_data: {
			if (plen < 2) {
				priv->flags |= PROTO_TFTP_CONN_INVALID;
				conntrack_unlock(s->ce);
				return PROTO_INVALID;
			}
			uint16_t block_id = ntohs(*((uint16_t*)(pload)));

			int set_start_seq = 0;
			if (!priv->stream) {
				priv->stream = stream_alloc(PROTO_TFTP_STREAM_BUFF, s->ce, 0, proto_tftp_process_payload);
				if (!priv->stream) {
					conntrack_unlock(s->ce);
					return PROTO_ERR;
				}
				stream_set_timeout(priv->stream, PROTO_TFTP_PKT_TIMER);
				set_start_seq = 1;
			}

			conntrack_unlock(s->ce);
			
			if (set_start_seq)
				stream_set_start_seq(priv->stream, s->direction, PROTO_TFTP_BLK_SIZE + 2);
			int res = stream_process_packet(priv->stream, p, stack, stack_index + 1, block_id * (PROTO_TFTP_BLK_SIZE + 2), 0);

			return (res == PROTO_OK ? PROTO_STOP : res);
		}

		case tftp_ack:
			// Nothing to do
			break;

		case tftp_error:
			// An error occured, cleanup this conntrack soon
			conntrack_delayed_cleanup(s->ce, 1, p->ts);
			break;

		default:
			priv->flags |= PROTO_TFTP_CONN_INVALID;
			conntrack_unlock(s->ce);
			return PROTO_INVALID;
	}

	conntrack_delayed_cleanup(s->ce, PROTO_TFTP_PKT_TIMER, p->ts);
	conntrack_unlock(s->ce);
	return PROTO_OK;
}