static int process_mkdir_cmd(client_t *client, netiso_mkdir_cmd *cmd) { netiso_mkdir_result result; char *dirpath; uint16_t dp_len; int ret; dp_len = BE16(cmd->dp_len); dirpath = (char *)malloc(dp_len+1); if (!dirpath) { DPRINTF("CRITICAL: memory allocation error\n"); return -1; } dirpath[dp_len] = 0; ret = recv_all(client->s, (void *)dirpath, dp_len); if (ret != dp_len) { DPRINTF("recv failed, getting dirname for mkdir: %d %d\n", ret, get_network_error()); free(dirpath); return -1; } dirpath = translate_path(dirpath, 1, 1, NULL); if (!dirpath) { DPRINTF("Path cannot be translated. Connection with this client will be aborted.\n"); return -1; } DPRINTF("mkdir %s\n", dirpath); #ifdef WIN32 result.mkdir_result = BE32(mkdir(dirpath)); #else result.mkdir_result = BE32(mkdir(dirpath, 0777)); #endif free(dirpath); ret = send(client->s, (char *)&result, sizeof(result), 0); if (ret != sizeof(result)) { DPRINTF("open dir, send result error: %d %d\n", ret, get_network_error()); return -1; } return 0; }
static int process_get_dir_size_cmd(client_t *client, netiso_get_dir_size_cmd *cmd) { netiso_get_dir_size_result result; char *dirpath; uint16_t dp_len; int ret; dp_len = BE16(cmd->dp_len); dirpath = (char *)malloc(dp_len+1); if (!dirpath) { DPRINTF("CRITICAL: memory allocation error\n"); return -1; } dirpath[dp_len] = 0; ret = recv_all(client->s, (char *)dirpath, dp_len); if (ret != dp_len) { DPRINTF("recv failed, getting dirname for get_dir_size: %d %d\n", ret, get_network_error()); free(dirpath); return -1; } dirpath = translate_path(dirpath, 1, 1, NULL); if (!dirpath) { DPRINTF("Path cannot be translated. Connection with this client will be aborted.\n"); return -1; } DPRINTF("get_dir_size %s\n", dirpath); result.dir_size = BE64(calculate_directory_size(dirpath)); free(dirpath); ret = send(client->s, (char *)&result, sizeof(result), 0); if (ret != sizeof(result)) { DPRINTF("get_dir_size, send result error: %d %d\n", ret, get_network_error()); return -1; } return 0; }
static int process_delete_file_cmd(client_t *client, netiso_delete_file_cmd *cmd) { netiso_delete_file_result result; char *filepath; uint16_t fp_len; int ret; fp_len = BE16(cmd->fp_len); filepath = (char *)malloc(fp_len+1); if (!filepath) { DPRINTF("CRITICAL: memory allocation error\n"); return -1; } filepath[fp_len] = 0; ret = recv_all(client->s, (void *)filepath, fp_len); if (ret != fp_len) { DPRINTF("recv failed, getting filename for delete file: %d %d\n", ret, get_network_error()); free(filepath); return -1; } filepath = translate_path(filepath, 1, 1, NULL); if (!filepath) { DPRINTF("Path cannot be translated. Connection with this client will be aborted.\n"); return -1; } DPRINTF("delete %s\n", filepath); result.delete_result = BE32(unlink(filepath)); free(filepath); ret = send(client->s, (char *)&result, sizeof(result), 0); if (ret != sizeof(result)) { DPRINTF("delete, send result error: %d %d\n", ret, get_network_error()); return -1; } return 0; }
static int initialize_socket(uint16_t port) { int s; struct sockaddr_in addr; #ifdef WIN32 WSADATA wsaData; WSAStartup(MAKEWORD(2,2), &wsaData); #endif s = socket(AF_INET, SOCK_STREAM, 0); if (s < 0) { DPRINTF("Socket creation error: %d\n", get_network_error()); return s; } int flag = 1; if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char *)&flag, sizeof(flag)) < 0) { DPRINTF("Error in setsockopt(REUSEADDR): %d\n", get_network_error()); closesocket(s); return -1; } addr.sin_family = AF_INET; addr.sin_port = htons(port); addr.sin_addr.s_addr = INADDR_ANY; if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { DPRINTF("Error in bind: %d\n", get_network_error()); return -1; } if (listen(s, 1) < 0) { DPRINTF("Error in listen: %d\n", get_network_error()); return -1; } return s; }
static int process_write_file_cmd(client_t *client, netiso_write_file_cmd *cmd) { uint32_t remaining; int32_t bytes_written; netiso_write_file_result result; remaining = BE32(cmd->num_bytes); if (!client->wo_file) { bytes_written = -1; goto send_result; } if (remaining > BUFFER_SIZE) { return -1; } //DPRINTF("Remaining: %d\n", remaining); if (remaining > 0) { int ret = recv_all(client->s, (void *)client->buf, remaining); if (ret != remaining) { DPRINTF("recv failed on write file: %d %d\n", ret, get_network_error()); return -1; } } bytes_written = client->wo_file->write(client->buf, remaining); if (bytes_written < 0) { bytes_written = -1; } send_result: result.bytes_written = (int32_t)BE32(bytes_written); if (send(client->s, (char *)&result, sizeof(result), 0) != 4) { DPRINTF("send failed on send result (read file)\n"); return -1; } return 0; }
static int process_read_dir_entry_cmd(client_t *client, netiso_read_dir_entry_cmd *cmd, int version) { netiso_read_dir_entry_result result_v1; netiso_read_dir_entry_result_v2 result_v2; file_stat_t st; struct dirent *entry; char *path; if (version == 1) { memset(&result_v1, 0, sizeof(result_v1)); } else { memset(&result_v2, 0, sizeof(result_v2)); } if (!client->dir || !client->dirpath) { if (version == 1) { result_v1.file_size = BE64(-1); } else { result_v2.file_size = BE64(-1); } goto send_result; } while ((entry = readdir(client->dir))) { if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0 && strlen(entry->d_name) <= 65535) break; } if (!entry) { closedir(client->dir); free(client->dirpath); client->dir = NULL; client->dirpath = NULL; if (version == 1) { result_v1.file_size = BE64(-1); } else { result_v2.file_size = BE64(-1); } goto send_result; } path = (char *)malloc(strlen(client->dirpath)+strlen(entry->d_name)+2); sprintf(path, "%s/%s", client->dirpath, entry->d_name); if (stat_file(path, &st) < 0) { closedir(client->dir); free(client->dirpath); client->dir = NULL; client->dirpath = NULL; if (version == 1) { result_v1.file_size = BE64(-1); } else { result_v2.file_size = BE64(-1); } DPRINTF("Stat failed on read dir entry: %s\n", path); free(path); goto send_result; } free(path); if ((st.mode & S_IFDIR) == S_IFDIR) { if (version == 1) { result_v1.file_size = BE64(0); result_v1.is_directory = 1; } else { result_v2.file_size = BE64(0); result_v2.is_directory = 1; } } else { if (version == 1) { result_v1.file_size = BE64(st.file_size); result_v1.is_directory = 0; } else { result_v2.file_size = BE64(st.file_size); result_v2.is_directory = 0; } } if (version == 1) { result_v1.fn_len = BE16(strlen(entry->d_name)); } else { result_v2.fn_len = BE16(strlen(entry->d_name)); result_v2.atime = BE64(st.atime); result_v2.ctime = BE64(st.ctime); result_v2.mtime = BE64(st.mtime); } send_result: if (version == 1) { if (send(client->s, (char *)&result_v1, sizeof(result_v1), 0) != sizeof(result_v1)) { DPRINTF("send error on read dir entry (%d)\n", get_network_error()); return -1; } } else { if (send(client->s, (char *)&result_v2, sizeof(result_v2), 0) != sizeof(result_v2)) { DPRINTF("send error on read dir entry (%d)\n", get_network_error()); return -1; } } if ((version == 1 && result_v1.file_size != BE64(-1)) || (version == 2 && result_v2.file_size != BE64(-1))) { if (send(client->s, (char *)entry->d_name, strlen(entry->d_name), 0) != strlen(entry->d_name)) { DPRINTF("send file name error on read dir entry (%d)\n", get_network_error()); return -1; } } return 0; }
static int process_open_dir_cmd(client_t *client, netiso_open_dir_cmd *cmd) { netiso_open_dir_result result; char *dirpath; uint16_t dp_len; int ret; dp_len = BE16(cmd->dp_len); //DPRINTF("fp_len = %d\n", fp_len); dirpath = (char *)malloc(dp_len+1); if (!dirpath) { DPRINTF("CRITICAL: memory allocation error\n"); return -1; } dirpath[dp_len] = 0; ret = recv_all(client->s, (void *)dirpath, dp_len); if (ret != dp_len) { DPRINTF("recv failed, getting dirname for open dir: %d %d\n", ret, get_network_error()); free(dirpath); return -1; } dirpath = translate_path(dirpath, 1, 1, NULL); if (!dirpath) { DPRINTF("Path cannot be translated. Connection with this client will be aborted.\n"); return -1; } DPRINTF("open dir %s\n", dirpath); if (client->dir) { closedir(client->dir); client->dir = NULL; } if (client->dirpath) { free(client->dirpath); } client->dirpath = NULL; client->dir = opendir(dirpath); if (!client->dir) { DPRINTF("open dir error on \"%s\"\n", dirpath); result.open_result = BE32(-1); } else { client->dirpath = dirpath; result.open_result = BE32(0); } if (!client->dirpath) free(dirpath); ret = send(client->s, (char *)&result, sizeof(result), 0); if (ret != sizeof(result)) { DPRINTF("open dir, send result error: %d %d\n", ret, get_network_error()); return -1; } return 0; }
static int process_create_cmd(client_t *client, netiso_create_cmd *cmd) { netiso_create_result result; char *filepath; uint16_t fp_len; int ret; fp_len = BE16(cmd->fp_len); //DPRINTF("fp_len = %d\n", fp_len); filepath = (char *)malloc(fp_len+1); if (!filepath) { DPRINTF("CRITICAL: memory allocation error\n"); return -1; } filepath[fp_len] = 0; ret = recv_all(client->s, (void *)filepath, fp_len); if (ret != fp_len) { DPRINTF("recv failed, getting filename for create: %d %d\n", ret, get_network_error()); free(filepath); return -1; } filepath = translate_path(filepath, 1, 1, NULL); if (!filepath) { DPRINTF("Path cannot be translated. Connection with this client will be aborted.\n"); return -1; } DPRINTF("create %s\n", filepath); if (client->wo_file) { delete client->wo_file; } client->wo_file = new File(); if (client->wo_file->open(filepath, O_WRONLY|O_CREAT|O_TRUNC) < 0) { DPRINTF("create error on \"%s\"\n", filepath); result.create_result = BE32(-1); delete client->wo_file; client->wo_file = NULL; } else { result.create_result = BE32(0); } free(filepath); ret = send(client->s, (char *)&result, sizeof(result), 0); if (ret != sizeof(result)) { DPRINTF("create, send result error: %d %d\n", ret, get_network_error()); return -1; } return 0; }
static int process_open_cmd(client_t *client, netiso_open_cmd *cmd) { file_stat_t st; netiso_open_result result; char *filepath; uint16_t fp_len; int ret, viso; int error = 0; fp_len = BE16(cmd->fp_len); //DPRINTF("fp_len = %d\n", fp_len); filepath = (char *)malloc(fp_len+1); if (!filepath) { DPRINTF("CRITICAL: memory allocation error\n"); return -1; } filepath[fp_len] = 0; ret = recv_all(client->s, (void *)filepath, fp_len); if (ret != fp_len) { DPRINTF("recv failed, getting filename for open: %d %d\n", ret, get_network_error()); free(filepath); return -1; } filepath = translate_path(filepath, 1, 1, &viso); if (!filepath) { DPRINTF("Path cannot be translated. Connection with this client will be aboreted.\n"); return -1; } DPRINTF("open %s\n", filepath); if (client->ro_file) { delete client->ro_file; } if (viso == VISO_NONE) { client->ro_file = new File(); } else { client->ro_file = new VIsoFile((viso == VISO_PS3)); } if (client->ro_file->open(filepath, O_RDONLY) < 0) { DPRINTF("open error on \"%s\" (viso=%d)\n", filepath, viso); error = 1; delete client->ro_file; client->ro_file = NULL; } else { if (client->ro_file->fstat(&st) < 0) { DPRINTF("Error in fstat\n"); error = 1; } else { result.file_size = BE64(st.file_size); result.mtime = BE64(st.mtime); } } #ifdef WIN32 DPRINTF("File size: %I64x\n", st.file_size); #else DPRINTF("File size: %llx\n", (long long unsigned int)st.file_size); #endif if (error) { result.file_size = BE64(-1); result.mtime = BE64(0); } free(filepath); ret = send(client->s, (char *)&result, sizeof(result), 0); if (ret != sizeof(result)) { DPRINTF("open, send result error: %d %d\n", ret, get_network_error()); return -1; } return 0; }
//------------------------------------------------------------------------- idarpc_stream_t *init_client_irs(const char *hostname, int port_number) { if ( hostname[0] == '\0' ) { warning("AUTOHIDE NONE\n" "Please specify the hostname in Debugger, Process options"); return NULL; } if ( !init_irs_layer() ) { warning("AUTOHIDE NONE\n" "Could not initialize sockets: %s", winerr(get_network_error())); return NULL; } struct addrinfo ai, *res, *e; char port[33]; // try to enumerate all possible addresses memset(&ai,0, sizeof(ai)); ai.ai_flags = AI_CANONNAME; ai.ai_family = PF_UNSPEC; ai.ai_socktype = SOCK_STREAM; qsnprintf(port, sizeof(port), "%d", port_number); bool ok = false; const char *errstr = NULL; SOCKET sock = INVALID_SOCKET; int code = getaddrinfo(hostname, port, &ai, &res); if ( code != 0 ) { // failed to resolve the name errstr = gai_strerror(code); } else { for ( e = res; !ok && e != NULL; e = e->ai_next ) { char uaddr[INET6_ADDRSTRLEN+1]; char uport[33]; if ( getnameinfo(e->ai_addr, e->ai_addrlen, uaddr, sizeof(uaddr), uport, sizeof(uport), NI_NUMERICHOST | NI_NUMERICSERV) != 0 ) { NETERR: errstr = winerr(get_network_error()); continue; } sock = socket(e->ai_family, e->ai_socktype, e->ai_protocol); if ( sock == INVALID_SOCKET ) goto NETERR; setup_irs((idarpc_stream_t*)sock); if ( connect(sock, e->ai_addr, e->ai_addrlen) == SOCKET_ERROR ) { errstr = winerr(get_network_error()); closesocket(sock); continue; } ok = true; } freeaddrinfo(res); } if ( !ok ) { msg("Could not connect to %s: %s\n", hostname, errstr); return NULL; } return (idarpc_stream_t*)sock; }
static int process_stat_cmd(client_t *client, netiso_stat_cmd *cmd) { netiso_stat_result result; file_stat_t st; char *filepath; uint16_t fp_len; int ret; fp_len = BE16(cmd->fp_len); //DPRINTF("fp_len = %d\n", fp_len); filepath = (char *)malloc(fp_len+1); if (!filepath) { DPRINTF("CRITICAL: memory allocation error\n"); return -1; } filepath[fp_len] = 0; ret = recv_all(client->s, (char *)filepath, fp_len); if (ret != fp_len) { DPRINTF("recv failed, getting filename for stat: %d %d\n", ret, get_network_error()); free(filepath); return -1; } filepath = translate_path(filepath, 1, 1, NULL); if (!filepath) { DPRINTF("Path cannot be translated. Connection with this client will be aborted.\n"); return -1; } DPRINTF("stat %s\n", filepath); if (stat_file(filepath, &st) < 0) { DPRINTF("stat error on \"%s\"\n", filepath); result.file_size = BE64(-1); } else { if ((st.mode & S_IFDIR) == S_IFDIR) { result.file_size = BE64(0); result.is_directory = 1; } else { result.file_size = BE64(st.file_size); result.is_directory = 0; } result.mtime = BE64(st.mtime); result.ctime = BE64(st.ctime); result.atime = BE64(st.atime); } free(filepath); ret = send(client->s, (char *)&result, sizeof(result), 0); if (ret != sizeof(result)) { DPRINTF("stat, send result error: %d %d\n", ret, get_network_error()); return -1; } return 0; }
static int process_read_dir_entry_cmd(client_t *client, netiso_read_dir_entry_cmd *cmd, int version) { char *path; file_stat_t st; struct dirent *entry; size_t d_name_len = 0; netiso_read_dir_entry_result result_v1; netiso_read_dir_entry_result_v2 result_v2; if(version == 1) { memset(&result_v1, 0, sizeof(result_v1)); } else { memset(&result_v2, 0, sizeof(result_v2)); } if(!client->dir || !client->dirpath) { if(version == 1) { result_v1.file_size = BE64(-1); } else { result_v2.file_size = BE64(-1); } goto send_result_read_dir; } while ((entry = readdir(client->dir))) { if(IS_PARENT_DIR(entry->d_name)) continue; d_name_len = strlen(entry->d_name); if(IS_RANGE(d_name_len, 1, 65535)) break; } if(!entry) { closedir(client->dir); if(client->dirpath) free(client->dirpath); client->dir = NULL; client->dirpath = NULL; if(version == 1) { result_v1.file_size = BE64(-1); } else { result_v2.file_size = BE64(-1); } goto send_result_read_dir; } path = (char *)malloc(strlen(client->dirpath) + d_name_len + 2); if(!path) { DPRINTF("CRITICAL: memory allocation error\n"); goto send_result_read_dir; } sprintf(path, "%s/%s", client->dirpath, entry->d_name); DPRINTF("Read dir entry: %s\n", path); if(stat_file(path, &st) < 0) { closedir(client->dir); if(client->dirpath) free(client->dirpath); client->dir = NULL; client->dirpath = NULL; if(version == 1) { result_v1.file_size = BE64(-1); } else { result_v2.file_size = BE64(-1); } DPRINTF("Stat failed on read dir entry: %s\n", path); goto send_result_read_dir; } if((st.mode & S_IFDIR) == S_IFDIR) { if(version == 1) { result_v1.file_size = BE64(0); result_v1.is_directory = 1; } else { result_v2.file_size = BE64(0); result_v2.is_directory = 1; } } else { if(version == 1) { result_v1.file_size = BE64(st.file_size); result_v1.is_directory = 0; } else { result_v2.file_size = BE64(st.file_size); result_v2.is_directory = 0; } } if(version == 1) { result_v1.fn_len = BE16(d_name_len); } else { result_v2.fn_len = BE16(d_name_len); result_v2.atime = BE64(st.atime); result_v2.ctime = BE64(st.ctime); result_v2.mtime = BE64(st.mtime); } send_result_read_dir: if(path) free(path); if(version == 1) { if(send(client->s, (char *)&result_v1, sizeof(result_v1), 0) != sizeof(result_v1)) { DPRINTF("send error on read dir entry (%d)\n", get_network_error()); return -1; } } else { if(send(client->s, (char *)&result_v2, sizeof(result_v2), 0) != sizeof(result_v2)) { DPRINTF("send error on read dir entry (%d)\n", get_network_error()); return -1; } } if((version == 1 && result_v1.file_size != BE64(-1)) || (version == 2 && result_v2.file_size != BE64(-1))) { if(send(client->s, (char *)entry->d_name, d_name_len, 0) != d_name_len) { DPRINTF("send file name error on read dir entry (%d)\n", get_network_error()); return -1; } } return 0; }
static int process_open_cmd(client_t *client, netiso_open_cmd *cmd) { file_stat_t st; netiso_open_result result; char *filepath; uint16_t fp_len; int ret, viso = VISO_NONE; result.file_size = BE64(-1); result.mtime = BE64(0); fp_len = BE16(cmd->fp_len); //DPRINTF("fp_len = %d\n", fp_len); filepath = (char *)malloc(fp_len+1); if(!filepath) { DPRINTF("CRITICAL: memory allocation error\n"); return -1; } if(client->ro_file) { delete client->ro_file; } ret = recv_all(client->s, (void *)filepath, fp_len); filepath[fp_len] = 0; if(!strcmp(filepath, "/CLOSEFILE")) { free(filepath); return 0; } if(ret != fp_len) { DPRINTF("recv failed, getting filename for open: %d %d\n", ret, get_network_error()); free(filepath); return -1; } filepath = translate_path(filepath, 1, &viso); if(!filepath) { DPRINTF("Path cannot be translated. Connection with this client will be aborted.\n"); return -1; } if(viso == VISO_NONE) { client->ro_file = new File(); } else { printf("building virtual iso...\n"); client->ro_file = new VIsoFile((viso == VISO_PS3)); } client->CD_SECTOR_SIZE = 2352; if(client->ro_file->open(filepath, O_RDONLY) < 0) { printf("open error on \"%s\" (viso=%d)\n", filepath + root_len, viso); delete client->ro_file; client->ro_file = NULL; } else { if(client->ro_file->fstat(&st) < 0) { DPRINTF("Error in fstat\n"); } else { result.file_size = BE64(st.file_size); result.mtime = BE64(st.mtime); if(viso != VISO_NONE || BE64(st.file_size) > 0x400000UL) printf("open %s\n", filepath + root_len); // detect cd sector size (2MB - 848MB) if(IS_RANGE(st.file_size, 0x200000UL, 0x35000000UL)) { char buffer[0x10] = ""; client->CD_SECTOR_SIZE = 0; client->ro_file->seek(0x8020UL, SEEK_SET); client->ro_file->read(buffer, 0xC); if(memcmp(buffer, "PLAYSTATION ", 0xC) == 0) client->CD_SECTOR_SIZE = 2048; else { client->ro_file->seek(0x9220UL, SEEK_SET); client->ro_file->read(buffer, 0xC); if(memcmp(buffer, "PLAYSTATION ", 0xC) == 0) client->CD_SECTOR_SIZE = 2336; else { client->ro_file->seek(0x9320UL, SEEK_SET); client->ro_file->read(buffer, 0xC); if(memcmp(buffer, "PLAYSTATION ", 0xC) == 0) client->CD_SECTOR_SIZE = 2352; else { client->ro_file->seek(0x9920UL, SEEK_SET); client->ro_file->read(buffer, 0xC); if(memcmp(buffer, "PLAYSTATION ", 0xC) == 0) client->CD_SECTOR_SIZE = 2448; }}} if(client->CD_SECTOR_SIZE > 0) printf("CD sector size: %i\n", client->CD_SECTOR_SIZE); else client->CD_SECTOR_SIZE = 2352; } } } #ifdef WIN32 DPRINTF("File size: %I64x\n", st.file_size); #else DPRINTF("File size: %llx\n", (long long unsigned int)st.file_size); #endif free(filepath); ret = send(client->s, (char *)&result, sizeof(result), 0); if(ret != sizeof(result)) { DPRINTF("open, send result error: %d %d\n", ret, get_network_error()); return -1; } return 0; }
int main(int argc, char *argv[]) { int s; uint32_t whitelist_start = 0; uint32_t whitelist_end = 0; uint16_t port = NETISO_PORT; printf("ps3netsrv build 20161211 (mod by aldostools)\n"); #ifndef WIN32 if(sizeof(off_t) < 8) { DPRINTF("off_t too small!\n"); return -1; } #endif file_stat_t fs; if(argc < 2 && ((stat_file("./PS3ISO", &fs) >= 0) || (stat_file("./PSXISO", &fs) >= 0) || (stat_file("./GAMES", &fs) >= 0) || (stat_file("./GAMEZ", &fs) >= 0) || (stat_file("./DVDISO", &fs) >= 0) || (stat_file("./BDISO", &fs) >= 0))) {argv[1] = (char *)malloc(2); sprintf(argv[1], "."); argc = 2;} if(argc < 2) { #ifdef MERGE_DRIVES printf( "\nUsage: %s [rootdirectory] [port] [whitelist] [ignore drive letters]\n\n" "Default port: %d\n" "Whitelist: x.x.x.x, where x is 0-255 or *\n" "(e.g 192.168.1.* to allow only connections from 192.168.1.0-192.168.1.255)\n", argv[0], NETISO_PORT); #else printf( "\nUsage: %s [rootdirectory] [port] [whitelist]\n\n" "Default port: %d\n" "Whitelist: x.x.x.x, where x is 0-255 or *\n" "(e.g 192.168.1.* to allow only connections from 192.168.1.0-192.168.1.255)\n", argv[0], NETISO_PORT); #endif return -1; } if(strlen(argv[1]) >= sizeof(root_directory)) { printf("Directory name too long!\n"); return -1; } strcpy(root_directory, argv[1]); for (int i = strlen(root_directory) - 1; i >= 0; i--) { if(root_directory[i] == '/' || root_directory[i] == '\\') root_directory[i] = 0; else break; } printf("Path: %s\n\n", root_directory); root_len = strlen(root_directory); if(root_len == 0) { printf("/ can't be specified as root directory!\n"); return -1; } if(argc > 2) { uint32_t u; if(sscanf(argv[2], "%u", &u) != 1) { printf("Wrong port specified.\n"); return -1; } #ifdef WIN32 uint32_t min = 1; #else uint32_t min = 1024; #endif if(u < min || u > 65535) { printf("Port must be in %d-65535 range.\n", min); return -1; } port = u; } if(argc > 3) { char *p = argv[3]; for (int i = 3; i >= 0; i--) { uint32_t u; int wildcard = 0; if(sscanf(p, "%u", &u) != 1) { if(i == 0) { if(strcmp(p, "*") != 0) { printf("Wrong whitelist format.\n"); return -1; } } else { if(p[0] != '*' || p[1] != '.') { printf("Wrong whitelist format.\n"); return -1; } } wildcard = 1; } else { if(u > 0xFF) { printf("Wrong whitelist format.\n"); return -1; } } if(wildcard) { whitelist_end |= (0xFF<<(i*8)); } else { whitelist_start |= (u<<(i*8)); whitelist_end |= (u<<(i*8)); } if(i != 0) { p = strchr(p, '.'); if(!p) { printf("Wrong whitelist format.\n"); return -1; } p++; } } DPRINTF("Whitelist: %08X-%08X\n", whitelist_start, whitelist_end); } #ifdef MERGE_DRIVES if(argc > 4) { ignore_drives = argv[4]; } else if(whitelist_end == 0x0A000008) { ignore_drives = (char*)"E"; // ignore E:\ by default only if whitelist is 10.0.0.8 } // convert to upper case if(ignore_drives) { ignore_drives_len = strlen(ignore_drives); for(uint8_t d = 0; d < ignore_drives_len; d++) if((ignore_drives[d] >= 'a') && (ignore_drives[d] <= 'z')) ignore_drives[d] -= ('a'-'A'); } #endif s = initialize_socket(port); if(s < 0) { printf("Error in initialization.\n"); return -1; } memset(clients, 0, sizeof(clients)); printf("Waiting for client...\n"); for (;;) { struct sockaddr_in addr; unsigned int size; int cs; int i; size = sizeof(addr); cs = accept(s, (struct sockaddr *)&addr, (socklen_t *)&size); if(cs < 0) { printf("Network error: %d\n", get_network_error()); break; } // Check for same client for (i = 0; i < MAX_CLIENTS; i++) { if(clients[i].connected && clients[i].ip_addr.s_addr == addr.sin_addr.s_addr) break; } if(i != MAX_CLIENTS) { // Shutdown socket and wait for thread to complete shutdown(clients[i].s, SHUT_RDWR); closesocket(clients[i].s); join_thread(clients[i].thread); printf("Reconnection from %s\n", inet_ntoa(addr.sin_addr)); } else { if(whitelist_start != 0) { uint32_t ip = BE32(addr.sin_addr.s_addr); if(ip < whitelist_start || ip > whitelist_end) { printf("Rejected connection from %s (not in whitelist)\n", inet_ntoa(addr.sin_addr)); closesocket(cs); continue; } } for (i = 0; i < MAX_CLIENTS; i++) { if(!clients[i].connected) break; } if(i == MAX_CLIENTS) { printf("Too many connections! (rejected client: %s)\n", inet_ntoa(addr.sin_addr)); closesocket(cs); continue; } printf("Connection from %s\n", inet_ntoa(addr.sin_addr)); } if(initialize_client(&clients[i]) != 0) { printf("System seems low in resources.\n"); break; } clients[i].s = cs; clients[i].ip_addr = addr.sin_addr; create_start_thread(&clients[i].thread, client_thread, &clients[i]); } #ifdef WIN32 #ifdef MERGE_DRIVES if(ignore_drives) { free(ignore_drives); } #endif WSACleanup(); #endif return 0; }
//------------------------------------------------------------------------- int irs_error(idarpc_stream_t *) { return get_network_error(); }
int main(int argc, char *argv[]) { int s; uint32_t whitelist_start = 0; uint32_t whitelist_end = 0; uint16_t port = NETISO_PORT; #ifndef WIN32 if (sizeof(off_t) < 8) { DPRINTF("off_t too small!\n"); return -1; } #endif if (argc < 2) { printf("Usage: %s rootdirectory [port] [whitelist]\nDefault port: %d\nWhitelist: x.x.x.x, where x is 0-255 or * (e.g 192.168.1.* to allow only connections from 192.168.1.0-192.168.1.255)\n", argv[0], NETISO_PORT); return -1; } if (strlen(argv[1]) >= sizeof(root_directory)) { printf("Directory name too long!\n"); return -1; } strcpy(root_directory, argv[1]); for (int i = strlen(root_directory)-1; i>= 0; i--) { if (root_directory[i] == '/' || root_directory[i] == '\\') root_directory[i] = 0; else break; } if (strlen(root_directory) == 0) { printf("/ can't be specified as root directory!\n"); return -1; } if (argc > 2) { uint32_t u; if (sscanf(argv[2], "%u", &u) != 1) { printf("Wrong port specified.\n"); return -1; } #ifdef WIN32 uint32_t min = 1; #else uint32_t min = 1024; #endif if (u < min || u > 65535) { printf("Port must be in %d-65535 range.\n", min); return -1; } port = u; } if (argc > 3) { char *p = argv[3]; for (int i = 3; i >= 0; i--) { uint32_t u; int wildcard = 0; if (sscanf(p, "%u", &u) != 1) { if (i == 0) { if (strcmp(p, "*") != 0) { printf("Wrong whitelist format.\n"); return -1; } } else { if (p[0] != '*' || p[1] != '.') { printf("Wrong whitelist format.\n"); return -1; } } wildcard = 1; } else { if (u > 0xFF) { printf("Wrong whitelist format.\n"); return -1; } } if (wildcard) { whitelist_end |= (0xFF<<(i*8)); } else { whitelist_start |= (u<<(i*8)); whitelist_end |= (u<<(i*8)); } if (i != 0) { p = strchr(p, '.'); if (!p) { printf("Wrong whitelist format.\n"); return -1; } p++; } } DPRINTF("Whitelist: %08X-%08X\n", whitelist_start, whitelist_end); } s = initialize_socket(port); if (s < 0) { printf("Error in initialization.\n"); return -1; } memset(clients, 0, sizeof(clients)); printf("Waiting for client...\n"); for (;;) { struct sockaddr_in addr; unsigned int size; int cs; int i; size = sizeof(addr); cs = accept(s, (struct sockaddr *)&addr, (socklen_t *)&size); if (cs < 0) { DPRINTF("Accept error: %d\n", get_network_error()); printf("Network error.\n"); break; } // Check for same client for (i = 0; i < MAX_CLIENTS; i++) { if (clients[i].connected && clients[i].ip_addr.s_addr == addr.sin_addr.s_addr) break; } if (i != MAX_CLIENTS) { // Shutdown socket and wait for thread to complete shutdown(clients[i].s, SHUT_RDWR); closesocket(clients[i].s); join_thread(clients[i].thread); printf("Reconnection from %s\n", inet_ntoa(addr.sin_addr)); } else { if (whitelist_start != 0) { uint32_t ip = BE32(addr.sin_addr.s_addr); if (ip < whitelist_start || ip > whitelist_end) { printf("Rejected connection from %s (not in whitelist)\n", inet_ntoa(addr.sin_addr)); closesocket(cs); continue; } } for (i = 0; i < MAX_CLIENTS; i++) { if (!clients[i].connected) break; } if (i == MAX_CLIENTS) { printf("Too many connections! (rejected client: %s)\n", inet_ntoa(addr.sin_addr)); closesocket(cs); continue; } printf("Connection from %s\n", inet_ntoa(addr.sin_addr)); } if (initialize_client(&clients[i]) != 0) { printf("System seems low in resources.\n"); break; } clients[i].s = cs; clients[i].ip_addr = addr.sin_addr; create_start_thread(&clients[i].thread, client_thread, &clients[i]); } #ifdef WIN32 WSACleanup(); #endif return 0; }
static void neterr(const char *module) { int code = get_network_error(); error("%s: %s", module, winerr(code)); }