示例#1
0
文件: tftpcmd.c 项目: sbmart/uftpd
/* Parse TFTP payload in RRQ to get filename and optional blksize & timeout */
static int parse_RRQ(ctrl_t *ctrl, char *buf, size_t len)
{
	size_t opt_len = strlen(buf) + 1;

	/* First opt is always filename */
	ctrl->file = strdup(buf);

	do {
		/* Prepare to read options */
		buf += opt_len;
		len -= opt_len;
		opt_len = strlen(buf) + 1;

		if (!strncasecmp(buf, "blksize", 7)) {
			size_t sz = 0;

			buf += opt_len;
			len -= opt_len;
			opt_len = strlen(buf) + 1;

			sscanf(buf, "%zd", &sz);
			if (sz < MIN_SEGSIZE)
				continue; /* Ignore if too small for us. */

			if (alloc_buf(ctrl, sz)) {
				ERR(errno, "Failed reallocating TFTP buffer memory");
				return send_ERROR(ctrl, ENOMEM);
			}

			setbit(&ctrl->tftp_options, 1);
		}
	} while (len);

	return send_OACK(ctrl);
}
示例#2
0
文件: tftpcmd.c 项目: sbmart/uftpd
static int handle_RRQ(ctrl_t *ctrl)
{
	char *path = compose_path(ctrl, ctrl->file);

	ctrl->fp = fopen(path, "r");
	if (!ctrl->fp) {
		ERR(errno, "Failed opening %s", path);
		return send_ERROR(ctrl, ENOTFOUND);
	}

	return !send_DATA(ctrl, 0);
}
示例#3
0
// Processar agente
void proc_agent_snmp(){
	
	unsigned char asn_type; //ASN.1
	unsigned int length; //size
	
	 //tamnho
	unsigned char size_varbind, size_dataRx;
	//unsigned char size_OID;
	unsigned char i, j, k, numberOfRequests;
	unsigned char *ptr_data, *aux_ptr, *ptr_msg;
	
	if( !SnIRQ_wiznet( s, SOCK_IRQ_RECV ) )
		return;
	
	size_dataRx = getSn_RXsize_wiznet( s );
	if( size_dataRx==0 )
		return;
	if( size_dataRx < 8){
		recvData_wiznet( s, RX_ptr, size_dataRx);
		return;
	}
	/* tratar a trama */
	
	recvData_wiznet( s, RX_ptr, 8);
	
	ptr_msg = RX_ptr;
	IP_dest = *ptr_msg++;
	IP_dest <<= 8;
	IP_dest |= *ptr_msg++;
	IP_dest <<= 8;
	IP_dest |= *ptr_msg++;
	IP_dest <<= 8;
	IP_dest |= *ptr_msg++;

	PORT_dest = *ptr_msg++;
	PORT_dest <<= 8;
	PORT_dest |= *ptr_msg++;

	SIZE_SNMP = *ptr_msg++;
	SIZE_SNMP <<= 8;
	SIZE_SNMP |= *ptr_msg++;
	
	if( SIZE_SNMP>SNMP_MAX_LEN ){
		send_ERROR( SNMP_ERR_TOOBIG, 0 );
		while(1); //forca watchdog
	}
	if( SIZE_SNMP >= size_dataRx ){
		recvData_wiznet( s, RX_ptr, size_dataRx);
		return;
	}
	if( SIZE_SNMP )
		recvData_wiznet( s, RX_ptr, SIZE_SNMP);
	else
		return;
	
	//++inc_;

	//if(inc_==37)
		//RX_ptr += 0; 
	
	ptr_msg = RX_ptr;
	
	LENGTH_Build_ptr[0] = ptr_msg; //SEQ da msg
	ptr_data = parseHeader(ptr_msg, &asn_type, &length);
	if( ptr_data == 0x00){
		send_ERROR( length, 0 );   ////////////////////////////////
		return;
	}
	size_msg = length; //tamanho msgSNMP
		
	//Procurar versao	
	ptr_data = parseHeader(ptr_data, &asn_type, &length);
	if( ptr_data == 0x00){
		send_ERROR( length, 0 );   ////////////////////////////////
		return;
	}
	if( *ptr_data!= SNMP_VERSION_1)
		return;
	++ptr_data;
		
	//Procurar community
	ptr_data = parseHeader(ptr_data, &asn_type, &length);
	if( ptr_data == 0x00){
		send_ERROR( length, 0 );   ////////////////////////////////
		return;
	}
	if( length != COMMUNITY_SIZE )
		return;
	for(i=0; i<length; ++i)
		if( *(ptr_data+i) != community[i] )
			return;
	
	ptr_data += length;
	
	/* PDU */
	LENGTH_Build_ptr[1] = ptr_data;
	//Procurar GetRequest
	ptr_data = parseHeader(ptr_data, &asn_type, &length);
	if( ptr_data == 0x00){
		send_ERROR( length, 0 );
		return;
	}
	

	if( asn_type == (MSG_GET_REQUEST+ASN_CONTEXT+ASN_FORMAT) ){ //GetRequest
		
		//Procurar RID
		ptr_data = parseHeader(ptr_data, &asn_type, &length);
		if( ptr_data == 0x00 ){
			send_ERROR( length, 0 );
			return;
		}
		ptr_data += length;
		
		//Procurar ERR
		ptr_data = parseHeader(ptr_data, &asn_type, &length);
		if( ptr_data == 0x00){
			send_ERROR( length, 0 );
			return;
		}
		ptr_data += length;
		
		//Procurar ERROR INDEX
		ptr_data = parseHeader(ptr_data, &asn_type, &length);
		if( ptr_data == 0x00){
			send_ERROR( length, 0 );   
			return;
		}
		ptr_data += length;
		LENGTH_Build_ptr[2] = ptr_data; //SEQ VARBIND_LIST
		
		//Procurar VARBIND LIST
		ptr_data = parseHeader(ptr_data, &asn_type, &length);
		if( ptr_data == 0x00){
			send_ERROR( length, 0 );
			return;
		}
		LENGTH_Build_ptr[3] = ptr_data; //SEQ VARBIND
		
		//Procurar VARBIND
		ptr_data = parseHeader(ptr_data, &asn_type, &length);
		if( ptr_data == 0x00){
			send_ERROR( length, 0 );
			return;
		}
		size_varbind = length;
		
		//Procurar OIDs
		i=0; j=0; numberOfRequests=0;
		while( i<size_varbind ){
			aux_ptr = ptr_data;
			ptr_data = parseHeader(ptr_data, &asn_type, &length);
			if( asn_type == ASN_OBJECT_ID+ASN_UNIVERSAL ){
				if( length != (NumberNodes+1+1+1) ){
					send_ERROR( SNMP_ERR_NOSUCHNAME, j );
					return;
				}			
				if( ++numberOfRequests>OID_MAX_REQ ){
					send_ERROR( SNMP_ERR_GENERR, 0 );
					return;
				}
				for(k=0; k<length; ++k)
					oid[j].id[k] = *(ptr_data+k);
				++j;
			}
			ptr_data += length + 2; // Value=0x00 Len=0
			i += ptr_data - aux_ptr;		
		}
		
		i = searchOID_MIB(numberOfRequests);
		if( i ){
			send_ERROR( SNMP_ERR_NOSUCHNAME, i-1 );
			return;
		}
		
		sendResponse(numberOfRequests);
	}
}
示例#4
0
/* Enviar msg resposta:	Num de respostas a produzir
 * 					 Index
 ****************************************
 */ 
void sendResponse( unsigned char ans ){
	
	unsigned char *ptr, *ptr_aux;
	unsigned char i, j, size, size_VARBIND_LIST, value_taken;
	unsigned char value[OID_MAX_REQ][SYSTEM_ID_SIZE+2];
	unsigned int length, length_aux, size_tmp;
	
	ptr = LENGTH_Build_ptr[2]+1;//LEN_VARBIND_LIST
	size = value_taken = 0;
	size_VARBIND_LIST = *ptr;
	//size_VARBIND = *(LENGTH_Build_ptr[3]+1);
	
	for(i=0; i<ans; ++i){
		switch( oid[i].id[8] ){
			case 1: //Produto
				switch( oid[i].id[9] ){ //variavel
					case 1: // Nome
						value[i][0] = ASN_OCTET_STR+ASN_UNIVERSAL;
						value[i][1] = SYSTEM_ID_SIZE;
						for(j=0; j<SYSTEM_ID_SIZE; ++j)
							value[i][2+j] = systemID[j];
						size += 2 + j;
						break;
				}
				break;
			case 2: //Controlo
				switch( oid[i].id[9] ){ //variavel
					case MIB_ISEL_IPL_CONTROLE_U: //U
						value[i][0] = ASN_OCTET_STR+ASN_UNIVERSAL;
						size_tmp = float_toChar( &value[i][2], u, 0);
						value[i][1] = size_tmp; //XXX.X
						size += 2 + size_tmp;	
						break;		
					case MIB_ISEL_IPL_CONTROLE_I:
						value[i][0] = ASN_OCTET_STR+ASN_UNIVERSAL;
						size_tmp = float_toChar( &value[i][2], irms, 2);
						value[i][1] = size_tmp; //XX.X
						size += 2 + size_tmp;
						break;		
					case MIB_ISEL_IPL_CONTROLE_E:
						value[i][0] = ASN_OCTET_STR+ASN_UNIVERSAL;
						size_tmp = float_toChar( &value[i][2], e, 1);
						value[i][1] = size_tmp; //XXX.X
						size += 2 + size_tmp;
						break;		
					case MIB_ISEL_IPL_CONTROLE_T:
						value[i][0] = ASN_OCTET_STR+ASN_UNIVERSAL;
						size_tmp = char_toString(&value[i][2], temp);
						value[i][1] = size_tmp; //XX.X
						size += 2 + size_tmp;
						break;		
					case MIB_ISEL_IPL_CONTROLE_H:
						value[i][0] = ASN_OCTET_STR+ASN_UNIVERSAL;
						size_tmp = char_toString(&value[i][2], humi);
						value[i][1] = size_tmp; //XXX.X
						size += 2 + size_tmp;
						break;		
				}
				break;
		}
	value_taken += 2;
	}//end_for
	
	size_msg = size_msg - value_taken + size;
	//size_msg += size;
	if( size_msg <= SNMP_MAX_LEN){
		ptr = LENGTH_Build_ptr[0];
		buildLength( ptr+1, size_msg );
		
		ptr = LENGTH_Build_ptr[1];
		*ptr = MSG_GET_RESPONSE+ASN_CONTEXT+ASN_FORMAT; //GetResponse
		buildLength( ptr+1, length_value(ptr+1)-value_taken+size );
		
		ptr = LENGTH_Build_ptr[2];
		buildLength( ptr+1, length_value(ptr+1)-value_taken+size );
	
		ptr = LENGTH_Build_ptr[3];
		buildLength( ptr+1, length_value(ptr+1)-value_taken+size );
		
		ptr = LENGTH_Build_ptr[3];
		ptr = parseHeader(ptr, &size_VARBIND_LIST, &length_aux);//OID
		
		for(i=0; i<length_aux; ){
			ptr = parseHeader(ptr, &size_VARBIND_LIST, &length);
			ptr_aux = ptr + length;
			for(j=0; j<value[i][1]+2; ++j)
				*ptr_aux++ = value[i][j];
			
			i += ptr_aux-ptr+j;
			ptr = ptr_aux + j; 
		}
	}
	else
		send_ERROR( SNMP_ERR_TOOBIG, 0 );
	
	
	length = parseHeader(RX_ptr, &size_VARBIND_LIST, &length) - RX_ptr +  size_msg;	
	sendtoUDP_socket(s, RX_ptr, length, IP_dest, PORT_dest); // Enviar data (UDP/IP RAW)

}