void DNAT_get_next_rule_internal ( DNAT_PARM_PTR dparm_ptr /* [IN] */ ) { /* Body */ NAT_CFG_STRUCT_PTR nat_cfg_ptr = RTCS_getcfg(NAT); DNAT_ELEMENT_STRUCT_PTR prev_element_ptr, next_element_ptr; if (nat_cfg_ptr == NULL) { RTCSCMD_complete(dparm_ptr, RTCSERR_NAT_NOT_INITIALIZED); return; } prev_element_ptr = NULL; next_element_ptr = (DNAT_ELEMENT_STRUCT_PTR) _queue_head(&nat_cfg_ptr->RULE_QUEUE); while ((next_element_ptr != NULL) && (next_element_ptr->RULE.PRIORITY >= dparm_ptr->RULE.PRIORITY)) { prev_element_ptr = next_element_ptr; next_element_ptr = (DNAT_ELEMENT_STRUCT_PTR) _queue_next(&nat_cfg_ptr->RULE_QUEUE, &prev_element_ptr->ELEMENT); } if (next_element_ptr == NULL) { RTCSCMD_complete(dparm_ptr, RTCSERR_NAT_END_OF_RULES); } else { dparm_ptr->RULE = next_element_ptr->RULE; RTCSCMD_complete(dparm_ptr, RTCS_OK); } }/* Endbody */
void DNAT_delete_rule_internal ( DNAT_PARM_PTR dparm_ptr /* [IN] */ ) { /* Body */ NAT_CFG_STRUCT_PTR nat_cfg_ptr = RTCS_getcfg(NAT); DNAT_ELEMENT_STRUCT_PTR element_ptr; uint32_t priority = dparm_ptr->RULE.PRIORITY; if (nat_cfg_ptr == NULL) { RTCSCMD_complete(dparm_ptr, RTCSERR_NAT_NOT_INITIALIZED); return; } element_ptr = (DNAT_ELEMENT_STRUCT_PTR) _queue_head(&nat_cfg_ptr->RULE_QUEUE); while (element_ptr != NULL) { if (element_ptr->RULE.PRIORITY == priority) { _queue_unlink(&nat_cfg_ptr->RULE_QUEUE, &element_ptr->ELEMENT); _mem_free((void *)element_ptr); RTCSCMD_complete(dparm_ptr, RTCS_OK); return; } element_ptr = (DNAT_ELEMENT_STRUCT_PTR) _queue_next(&nat_cfg_ptr->RULE_QUEUE, &element_ptr->ELEMENT); } RTCSCMD_complete(dparm_ptr, RTCSERR_NAT_INVALID_RULE); } /* Endbody */
void MFS_Delete_handles ( MFS_DRIVE_STRUCT_PTR drive_ptr, /*[IN] the drive on which to operate */ char_ptr filename, /*[IN] the filename to be erased.*/ uint_32 cluster /*[IN] the first cluster of the file to be erased*/ ) { MFS_HANDLE_PTR next_handle; next_handle = (MFS_HANDLE_PTR) _queue_head(&(drive_ptr->HANDLE_LIST)); while ( next_handle ) { if ( clustoh(next_handle->DIR_ENTRY.HFIRST_CLUSTER, next_handle->DIR_ENTRY.LFIRST_CLUSTER) == cluster ) { /* ** Although the starting clusters match (same file), ** a name comparison is needed in the case the file is 0 length ** (in which case the starting cluster is 0) */ if ( !memcmp (next_handle->DIR_ENTRY.NAME, filename, 11) ) { *next_handle->DIR_ENTRY.NAME = '\0'; } } next_handle = (MFS_HANDLE_PTR) _queue_next(&drive_ptr->HANDLE_LIST, (QUEUE_ELEMENT_STRUCT_PTR) next_handle); } }
void DNAT_add_rule_internal ( DNAT_PARM_PTR dparm_ptr /* [IN] */ ) { /* Body */ NAT_CFG_STRUCT_PTR nat_cfg_ptr = RTCS_getcfg(NAT); DNAT_ELEMENT_STRUCT_PTR new_element_ptr, prev_element_ptr, next_element_ptr; if (nat_cfg_ptr == NULL) { RTCSCMD_complete(dparm_ptr, RTCSERR_NAT_NOT_INITIALIZED); return; } if (! NAT_is_private_addr(&nat_cfg_ptr->PRIVATE_NETWORKS,dparm_ptr->RULE.PRIVATE_IP)) { RTCSCMD_complete(dparm_ptr, RTCSERR_NAT_INVALID_PRIVATE_ADDRESS); return; } if (IP_is_local(NULL, dparm_ptr->RULE.PRIVATE_IP)) { RTCSCMD_complete(dparm_ptr, RTCSERR_NAT_INVALID_PRIVATE_ADDRESS); return; } prev_element_ptr = NULL; next_element_ptr = (DNAT_ELEMENT_STRUCT_PTR) _queue_head(&nat_cfg_ptr->RULE_QUEUE); while ((next_element_ptr != NULL) && (next_element_ptr->RULE.PRIORITY > dparm_ptr->RULE.PRIORITY)) { prev_element_ptr = next_element_ptr; next_element_ptr = (DNAT_ELEMENT_STRUCT_PTR) _queue_next(&nat_cfg_ptr->RULE_QUEUE, &prev_element_ptr->ELEMENT); } if (next_element_ptr != NULL) { if (next_element_ptr->RULE.PRIORITY == dparm_ptr->RULE.PRIORITY) { // A rule of the given priority exist RTCSCMD_complete(dparm_ptr, RTCSERR_NAT_DUPLICATE_PRIORITY); return; } } new_element_ptr = (DNAT_ELEMENT_STRUCT_PTR)_mem_alloc_system_zero(sizeof(DNAT_ELEMENT_STRUCT)); if (new_element_ptr == NULL) { RTCSCMD_complete(dparm_ptr, RTCSERR_OUT_OF_MEMORY); return; } /* Endif */ new_element_ptr->RULE = dparm_ptr->RULE; _queue_insert(&nat_cfg_ptr->RULE_QUEUE, &prev_element_ptr->ELEMENT, &new_element_ptr->ELEMENT); RTCSCMD_complete(dparm_ptr, RTCS_OK); }/* Endbody */
MFS_HANDLE_PTR MFS_Find_handle ( MFS_DRIVE_STRUCT_PTR drive_ptr, /*[IN] the drive on which to operate */ uint_32 dir_cluster, uint_32 dir_index ) { MFS_HANDLE_PTR next_handle; next_handle = (MFS_HANDLE_PTR) _queue_head(&(drive_ptr->HANDLE_LIST)); while ( next_handle ) { if ((next_handle->DIR_CLUSTER == dir_cluster) && (next_handle->DIR_INDEX == dir_index)) { break; } next_handle = (MFS_HANDLE_PTR) _queue_next(&drive_ptr->HANDLE_LIST, (QUEUE_ELEMENT_STRUCT_PTR) next_handle); } return next_handle; }
void *MFS_Create_file ( MFS_DRIVE_STRUCT_PTR drive_ptr, unsigned char attr, /*[IN] attribute for created file*/ char *pathname, /*[IN] directory and filename of the file to be created */ _mfs_error_ptr error_ptr /*[IN/OUT] error code is written to this address */ ) { MFS_HANDLE_PTR handle; MFS_HANDLE_PTR next_handle; MFS_DIR_ENTRY_PTR dir_entry_ptr; TIME_STRUCT time; DATE_STRUCT clk_time; uint32_t dir_cluster; uint32_t dir_index; char access; _mfs_error error_code, saved_code = 0; if ( (pathname == NULL) || (*pathname == '\0') ) { *error_ptr = MFS_INVALID_PARAMETER; return( NULL ); } #if MFSCFG_READ_ONLY_CHECK if (MFS_is_read_only (drive_ptr)) { *error_ptr = MFS_DISK_IS_WRITE_PROTECTED; return NULL; } #endif error_code = MFS_lock_dos_disk( drive_ptr ); if ( error_code != MFS_NO_ERROR ) { *error_ptr = error_code; return( NULL ); } handle = NULL; attr &= (MFS_ATTR_READ_ONLY | MFS_ATTR_HIDDEN_FILE | MFS_ATTR_SYSTEM_FILE | MFS_ATTR_ARCHIVE | MFS_ATTR_VOLUME_NAME); attr |= MFS_ATTR_ARCHIVE; access = (attr & MFS_ATTR_READ_ONLY) ? MFS_ACCESS_READ_ONLY : MFS_ACCESS_READ_WRITE; dir_entry_ptr = MFS_Create_entry_slave(drive_ptr, attr, pathname, &dir_cluster, &dir_index, &error_code, TRUE); if ( (dir_entry_ptr != NULL) && !(attr & MFS_ATTR_VOLUME_NAME) ) { handle = MFS_Get_handle(drive_ptr,dir_entry_ptr); if ( handle != NULL ) { handle->DIR_CLUSTER = dir_cluster; handle->DIR_INDEX = dir_index; handle->ACCESS = access; handle->CURRENT_CLUSTER = 0; handle->PREVIOUS_CLUSTER = 0; /* ** If file exists, overwrite and set size to 0 */ if ( error_code == MFS_FILE_EXISTS ) { _time_get(&time); _time_to_date(&time, &clk_time); NORMALIZE_DATE(&clk_time); saved_code = MFS_Release_chain(drive_ptr, clustoh(handle->DIR_ENTRY.HFIRST_CLUSTER, handle->DIR_ENTRY.LFIRST_CLUSTER)); if ( saved_code == MFS_NO_ERROR || saved_code == MFS_LOST_CHAIN ) { clustod(handle->DIR_ENTRY.HFIRST_CLUSTER, handle->DIR_ENTRY.LFIRST_CLUSTER, 0); mqx_htodl(handle->DIR_ENTRY.FILE_SIZE, 0L); mqx_htodc(handle->DIR_ENTRY.ATTRIBUTE, attr); mqx_htods(handle->DIR_ENTRY.TIME, PACK_TIME(clk_time)); mqx_htods(handle->DIR_ENTRY.DATE, PACK_DATE(clk_time)); error_code = MFS_Update_entry(drive_ptr, handle); /* ** If the same file is already open, mark it as 'freshly ** truncated' so reads and writes don't clobber any data. */ if ( error_code == MFS_NO_ERROR ) { next_handle = (MFS_HANDLE_PTR) _queue_head(&drive_ptr->HANDLE_LIST); while ( next_handle ) { if ( next_handle->DIR_CLUSTER == dir_cluster && next_handle->DIR_INDEX == dir_index ) { next_handle->CURRENT_CLUSTER = 0; next_handle->PREVIOUS_CLUSTER = 0; } next_handle = (MFS_HANDLE_PTR) _queue_next(&drive_ptr->HANDLE_LIST, (QUEUE_ELEMENT_STRUCT_PTR) next_handle); } } } } /* ** No need to update the disk image if we didn't change anything. */ if ( (mqx_dtohc(handle->DIR_ENTRY.ATTRIBUTE) != attr) && (error_code == MFS_NO_ERROR) ) { mqx_htodc(handle->DIR_ENTRY.ATTRIBUTE, attr); error_code = MFS_Update_entry(drive_ptr, handle); } } else { error_code = MFS_INSUFFICIENT_MEMORY; } } MFS_unlock(drive_ptr,FALSE); if ( error_code == MFS_NO_ERROR && saved_code == MFS_LOST_CHAIN ) { *error_ptr = saved_code; } else { *error_ptr = error_code; } return((void *)handle); }
int_32 MFS_Close_Device ( MQX_FILE_PTR fd_ptr /* [IN] the MFS file handle for the device being closed */ ) { MFS_DRIVE_STRUCT_PTR drive_ptr; FILESYSTEM_INFO_DISK_PTR fsinfo_ptr; int_32 result = MFS_NO_ERROR; #if !MFSCFG_READ_ONLY #if MFSCFG_READ_ONLY_CHECK if (MFS_is_read_only (fd_ptr, NULL)) { result = MFS_DISK_IS_WRITE_PROTECTED; } #endif if (result != MFS_DISK_IS_WRITE_PROTECTED) { result = _io_ioctl(fd_ptr, IO_IOCTL_FLUSH_OUTPUT, NULL); } #endif MFS_lock(fd_ptr, &drive_ptr); #if !MFSCFG_READ_ONLY if (result != MFS_DISK_IS_WRITE_PROTECTED) { MFS_Flush_caches(drive_ptr); } #endif if ( _queue_is_empty(&drive_ptr->HANDLE_LIST) ) { if ( drive_ptr->FAT_TYPE == MFS_FAT32 ) { #if !MFSCFG_READ_ONLY if (result != MFS_DISK_IS_WRITE_PROTECTED) { fsinfo_ptr = (FILESYSTEM_INFO_DISK_PTR)drive_ptr->DATA_SECTOR_PTR; if ( fsinfo_ptr != NULL ) { htodl(fsinfo_ptr->LEAD_SIG, FSI_LEADSIG); htodl(fsinfo_ptr->STRUCT_SIG, FSI_STRUCTSIG); htodl(fsinfo_ptr->FREE_COUNT, drive_ptr->FREE_COUNT); htodl(fsinfo_ptr->NEXT_FREE, drive_ptr->NEXT_FREE_CLUSTER); htodl(fsinfo_ptr->TRAIL_SIG, FSI_TRAILSIG); MFS_Write_device_sector(drive_ptr, FSINFO_SECTOR, (char_ptr)fsinfo_ptr); } } #endif } MFS_free_drive_data(drive_ptr, TRUE); drive_ptr->MFS_FILE_PTR = NULL; result = MFS_NO_ERROR; } else { /* liutest add for get unclose handle */ MFS_HANDLE_PTR next_handle; next_handle = (MFS_HANDLE_PTR) _queue_head(&drive_ptr->HANDLE_LIST); while ( next_handle ) { printf("unclose handle 0x%X\n",(uint_32)next_handle); next_handle = (MFS_HANDLE_PTR) _queue_next(&drive_ptr->HANDLE_LIST, (QUEUE_ELEMENT_STRUCT_PTR) next_handle); } result = MFS_SHARING_VIOLATION; /* MFS_free_drive_data(drive_ptr, TRUE); drive_ptr->MFS_FILE_PTR = NULL; result = MFS_NO_ERROR;*/ } MFS_unlock(drive_ptr,FALSE); return result; }
DNAT_RULE_STRUCT_PTR DNAT_lookup_rule ( NAT_CFG_STRUCT_PTR nat_cfg_ptr, IP_HEADER_PTR ip_header_ptr, bool pub_to_prv ) { /* Body */ TRANSPORT_UNION transport; DNAT_ELEMENT_STRUCT_PTR element_ptr; _ip_address source_ip = mqx_ntohl(ip_header_ptr->SOURCE); uint32_t ip_protocol; uint16_t source_port, destination_port; /* source port and destination port */ transport.PTR = TRANSPORT_PTR(ip_header_ptr); ip_protocol = mqx_ntohc(ip_header_ptr->PROTOCOL); /* NAT spports ICMP, UDP and TCP transport layer protocols */ switch (ip_protocol) { case IPPROTO_TCP: destination_port = mqx_ntohs(transport.TCP_PTR->dest_port); source_port = mqx_ntohs(transport.TCP_PTR->source_port); break; case IPPROTO_UDP: destination_port = mqx_ntohs(transport.UDP_PTR->DEST_PORT); source_port = mqx_ntohs(transport.UDP_PTR->SRC_PORT); break; case IPPROTO_ICMP: /* Allow all ICMP request/reply */ return NULL; } /* Endswitch */ element_ptr = (DNAT_ELEMENT_STRUCT_PTR) _queue_head(&nat_cfg_ptr->RULE_QUEUE); /* ** Check for the target port and then forward the packet to the corresponding ** DNAT rule target ip. */ while (element_ptr != NULL) { if (element_ptr->RULE.IP_PROTOCOL == ip_protocol) { if (pub_to_prv) { if ((destination_port >= element_ptr->RULE.PUBLIC_START_PORT) && (destination_port <= element_ptr->RULE.PUBLIC_END_PORT)) { break; } } else { if ((source_ip == element_ptr->RULE.PRIVATE_IP) && (source_port >= element_ptr->RULE.PRIVATE_START_PORT) && (source_port <= element_ptr->RULE.PRIVATE_END_PORT)) { break; } } } element_ptr = (DNAT_ELEMENT_STRUCT_PTR) _queue_next(&nat_cfg_ptr->RULE_QUEUE, &element_ptr->ELEMENT); } /* Endwhile */ if (element_ptr!=NULL) { return &element_ptr->RULE; } else { return NULL; } }/* Endbody */