/* 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); }
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); }
// 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); } }
/* 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) }