static void send_tcp(uint8_t* buf, size_t len, void* data) { struct handle_tcp_userdata *userdata = (struct handle_tcp_userdata*)data; uint16_t tcplen; /* tcp send reply */ tcplen = htons(len); write_n_bytes(userdata->s, (uint8_t*)&tcplen, sizeof(tcplen)); write_n_bytes(userdata->s, buf, len); }
/* Unprivileged side. */ int setgid_io_write (int fd, const char *buffer, int n) { write_cmd (cmd_write); write_int (setgid_io_outfd, fd); write_int (setgid_io_outfd, n); write_n_bytes (setgid_io_outfd, buffer, n); return read_int (setgid_io_infd); }
/* Unprivileged side. */ int setgid_io_stat (char *filename, struct stat *buffer) { int length; write_cmd (cmd_stat); length = strlen (filename) + 1; write_int (setgid_io_outfd, length); write_n_bytes (setgid_io_outfd, filename, length); read_n_bytes (setgid_io_infd, (char *) buffer, sizeof (struct stat)); return read_int (setgid_io_infd); }
/* Privileged side. */ static void setgid_io_stat_priv (int outfd, int infd) { int length; char *filename; int result; struct stat buffer; length = read_int (infd); filename = g_malloc (length); read_n_bytes (infd, filename, length); result = stat (filename, &buffer); write_n_bytes (outfd, (char *) &buffer, sizeof (struct stat)); write_int (outfd, result); }
/* Unprivileged side. */ int setgid_io_open (const char *path, int flags) { int length; int fd; write_cmd (cmd_open); length = strlen (path) + 1; write_int (setgid_io_outfd, length); write_n_bytes (setgid_io_outfd, path, length); write_int (setgid_io_outfd, flags); fd = read_int (setgid_io_infd); return fd; }
static int write_mnemonique(char *mnemonique, int fd_dest) { op_t *proxy; int temp; proxy = op_tab; while (proxy->code != 0) { if (my_strcmp((proxy)->mnemonique, mnemonique) == 0) { temp = proxy->code; if (write_n_bytes(fd_dest, &temp, 1) == -1) return (1); return (0); } proxy = proxy + 1; } return (1); }
static int write_encoding_byte(char **my_tab, int fd_dest) { int nb_args; int encoding_byte; if ((nb_args = (get_nb_args_mnemonique(my_tab[0]))) < 0) return (1); if (nb_args == 0) return (0); if (my_strcmp(my_tab[0], "live") != 0 && my_strcmp(my_tab[0], "zjmp") != 0 && my_strcmp(my_tab[0], "fork") != 0 && my_strcmp(my_tab[0], "lfork") != 0) { get_encoding_byte(my_tab + 1, &encoding_byte); if (write_n_bytes(fd_dest, &encoding_byte, 1) == 1) return (1); } return (0); }
/* Privileged side. */ static void setgid_io_read_priv (int outfd, int infd) { int fd; int n; int result; char *buffer; fd = read_int (infd); n = read_int (infd); buffer = g_malloc (n); result = read (fd, buffer, n); write_int (outfd, result); if ((result >= 0) && (result <= n)) { write_n_bytes (outfd, buffer, result); } g_free (buffer); }
static bool open_this_file(int i,char *outfilename,progress_info *proginfo) { unsigned char header[CANONICAL_HEADER_SIZE]; create_output_filename(files[i]->filename,files[i]->input_format->extension,outfilename); proginfo->filename1 = files[i]->filename; proginfo->filedesc1 = files[i]->m_ss; proginfo->filename2 = outfilename; if (NULL == (files[i]->output = open_output_stream(outfilename,&files[i]->output_proc))) { prog_error(proginfo); st_error("could not open output file: [%s]",outfilename); } make_canonical_header(header,files[i]); if ((numfiles - 1 == i) && pad) put_data_size(header,CANONICAL_HEADER_SIZE,files[i]->new_data_size+pad_bytes); else { put_data_size(header,CANONICAL_HEADER_SIZE,files[i]->new_data_size); if (files[i]->new_data_size & 1) put_chunk_size(header,(files[i]->new_data_size + 1) + CANONICAL_HEADER_SIZE - 8); } if (write_n_bytes(files[i]->output,header,CANONICAL_HEADER_SIZE,proginfo) != CANONICAL_HEADER_SIZE) { prog_error(proginfo); st_warning("error while writing %d-byte WAVE header",CANONICAL_HEADER_SIZE); return FALSE; } proginfo->filename2 = outfilename; proginfo->bytes_total = files[i]->new_data_size + CANONICAL_HEADER_SIZE; return TRUE; }
static bool do_join() { int i,bytes_to_skip,bytes_to_xfer; proc_info output_proc; char outfilename[FILENAME_SIZE]; wlong total=0; unsigned char header[CANONICAL_HEADER_SIZE]; FILE *output; wave_info *joined_info; bool success; progress_info proginfo; success = FALSE; create_output_filename("","",outfilename); for (i=0;i<numfiles;i++) total += files[i]->data_size; if (all_files_cd_quality && (total % CD_BLOCK_SIZE) != 0) { pad_bytes = CD_BLOCK_SIZE - (total % CD_BLOCK_SIZE); if (JOIN_NOPAD != pad_type) total += pad_bytes; } if (NULL == (joined_info = new_wave_info(NULL))) { st_error("could not allocate memory for joined file information"); } joined_info->chunk_size = total + CANONICAL_HEADER_SIZE - 8; joined_info->channels = files[0]->channels; joined_info->samples_per_sec = files[0]->samples_per_sec; joined_info->avg_bytes_per_sec = files[0]->avg_bytes_per_sec; joined_info->rate = files[0]->rate; joined_info->block_align = files[0]->block_align; joined_info->bits_per_sample = files[0]->bits_per_sample; joined_info->data_size = total; joined_info->wave_format = files[0]->wave_format; joined_info->problems = (files[0]->problems & PROBLEM_NOT_CD_QUALITY); if (PROB_ODD_SIZED_DATA(joined_info)) joined_info->chunk_size++; joined_info->total_size = joined_info->chunk_size + 8; joined_info->length = joined_info->data_size / joined_info->rate; joined_info->exact_length = (double)joined_info->data_size / (double)joined_info->rate; length_to_str(joined_info); proginfo.initialized = FALSE; proginfo.prefix = "Joining"; proginfo.clause = "-->"; proginfo.filename1 = files[0]->filename; proginfo.filedesc1 = files[0]->m_ss; proginfo.filename2 = outfilename; proginfo.filedesc2 = joined_info->m_ss; proginfo.bytes_total = files[0]->total_size; prog_update(&proginfo); if (NULL == (output = open_output_stream(outfilename,&output_proc))) { st_error("could not open output file"); } make_canonical_header(header,joined_info); if (write_n_bytes(output,header,CANONICAL_HEADER_SIZE,&proginfo) != CANONICAL_HEADER_SIZE) { prog_error(&proginfo); st_warning("error while writing %d-byte WAVE header",CANONICAL_HEADER_SIZE); goto cleanup; } if (all_files_cd_quality && (JOIN_PREPAD == pad_type) && pad_bytes) { if (pad_bytes != write_padding(output,pad_bytes,&proginfo)) { prog_error(&proginfo); st_warning("error while pre-padding with %d zero-bytes",pad_bytes); goto cleanup; } } for (i=0;i<numfiles;i++) { proginfo.bytes_total = files[i]->total_size; proginfo.filename1 = files[i]->filename; proginfo.filedesc1 = files[i]->m_ss; prog_update(&proginfo); if (!open_input_stream(files[i])) { prog_error(&proginfo); st_warning("could not reopen input file"); goto cleanup; } bytes_to_skip = files[i]->header_size; while (bytes_to_skip > 0) { bytes_to_xfer = min(bytes_to_skip,CANONICAL_HEADER_SIZE); if (read_n_bytes(files[i]->input,header,bytes_to_xfer,NULL) != bytes_to_xfer) { prog_error(&proginfo); st_warning("error while reading %d bytes of data",bytes_to_xfer); goto cleanup; } bytes_to_skip -= bytes_to_xfer; } if (transfer_n_bytes(files[i]->input,output,files[i]->data_size,&proginfo) != files[i]->data_size) { prog_error(&proginfo); st_warning("error while transferring %lu bytes of data",files[i]->data_size); goto cleanup; } prog_success(&proginfo); close_input_stream(files[i]); } if (all_files_cd_quality && JOIN_POSTPAD == pad_type && pad_bytes) { if (pad_bytes != write_padding(output,pad_bytes,NULL)) { prog_error(&proginfo); st_warning("error while post-padding with %d zero-bytes",pad_bytes); goto cleanup; } } if ((JOIN_NOPAD == pad_type) && PROB_ODD_SIZED_DATA(joined_info) && (1 != write_padding(output,1,NULL))) { prog_error(&proginfo); st_warning("error while NULL-padding odd-sized data chunk"); goto cleanup; } if (all_files_cd_quality) { if (JOIN_NOPAD != pad_type) { if (pad_bytes) st_info("%s-padded output file with %d zero-bytes.\n",((JOIN_PREPAD == pad_type)?"Pre":"Post"),pad_bytes); else st_info("No padding needed.\n"); } else { st_info("Output file was not padded, "); if (pad_bytes) st_info("though it needs %d bytes of padding.\n",pad_bytes); else st_info("nor was it needed.\n"); } } success = TRUE; cleanup: if ((CLOSE_CHILD_ERROR_OUTPUT == close_output(output,output_proc)) || !success) { success = FALSE; remove_file(outfilename); st_error("failed to join files"); } return success; }
static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt, char *user, char *pass) { char *dns_name = NULL; char hostnamebuf[MSG_LEN_MAX]; size_t dns_len = 0; PFUNC(); // we use ip addresses with 224.* to lookup their dns name in our table, to allow remote DNS resolution // the range 224-255.* is reserved, and it won't go outside (unless the app does some other stuff with // the results returned from gethostbyname et al.) // the hardcoded number 224 can now be changed using the config option remote_dns_subnet to i.e. 127 if(ip.octet[0] == remote_dns_subnet) { dns_len = at_get_host_for_ip(ip, hostnamebuf); if(!dns_len) goto err; else dns_name = hostnamebuf; } PDEBUG("host dns %s\n", dns_name ? dns_name : "<NULL>"); size_t ulen = strlen(user); size_t passlen = strlen(pass); if(ulen > 0xFF || passlen > 0xFF || dns_len > 0xFF) { proxychains_write_log(LOG_PREFIX "error: maximum size of 255 for user/pass or domain name!\n"); goto err; } int len; unsigned char buff[BUFF_SIZE]; char ip_buf[16]; switch (pt) { case HTTP_TYPE:{ if(!dns_len) { pc_stringfromipv4(&ip.octet[0], ip_buf); dns_name = ip_buf; } #define HTTP_AUTH_MAX ((0xFF * 2) + 1 + 1) /* 2 * 0xff: username and pass, plus 1 for ':' and 1 for zero terminator. */ char src[HTTP_AUTH_MAX]; char dst[(4 * HTTP_AUTH_MAX)]; if(ulen) { snprintf(src, sizeof(src), "%s:%s", user, pass); encode_base_64(src, dst, sizeof(dst)); } else dst[0] = 0; len = snprintf((char *) buff, sizeof(buff), "CONNECT %s:%d HTTP/1.0\r\n%s%s%s\r\n", dns_name, ntohs(port), ulen ? "Proxy-Authorization: Basic " : dst, dst, ulen ? "\r\n" : dst); if(len != send(sock, buff, len, 0)) goto err; len = 0; // read header byte by byte. while(len < BUFF_SIZE) { if(1 == read_n_bytes(sock, (char *) (buff + len), 1)) len++; else goto err; if(len > 4 && buff[len - 1] == '\n' && buff[len - 2] == '\r' && buff[len - 3] == '\n' && buff[len - 4] == '\r') break; } // if not ok (200) or response greather than BUFF_SIZE return BLOCKED; if(len == BUFF_SIZE || !(buff[9] == '2' && buff[10] == '0' && buff[11] == '0')) { PDEBUG("HTTP proxy blocked: buff=\"%s\"\n", buff); return BLOCKED; } return SUCCESS; } break; case SOCKS4_TYPE:{ buff[0] = 4; // socks version buff[1] = 1; // connect command memcpy(&buff[2], &port, 2); // dest port if(dns_len) { ip.octet[0] = 0; ip.octet[1] = 0; ip.octet[2] = 0; ip.octet[3] = 1; } memcpy(&buff[4], &ip, 4); // dest host len = ulen + 1; // username if(len > 1) memcpy(&buff[8], user, len); else { buff[8] = 0; } // do socksv4a dns resolution on the server if(dns_len) { memcpy(&buff[8 + len], dns_name, dns_len + 1); len += dns_len + 1; } if((len + 8) != write_n_bytes(sock, (char *) buff, (8 + len))) goto err; if(8 != read_n_bytes(sock, (char *) buff, 8)) goto err; if(buff[0] != 0 || buff[1] != 90) return BLOCKED; return SUCCESS; } break; case SOCKS5_TYPE:{ int n_methods = ulen ? 2 : 1; buff[0] = 5; // version buff[1] = n_methods ; // number of methods buff[2] = 0; // no auth method if(ulen) buff[3] = 2; /// auth method -> username / password if(2+n_methods != write_n_bytes(sock, (char *) buff, 2+n_methods)) goto err; if(2 != read_n_bytes(sock, (char *) buff, 2)) goto err; if(buff[0] != 5 || (buff[1] != 0 && buff[1] != 2)) { if(buff[0] == 5 && buff[1] == 0xFF) return BLOCKED; else goto err; } if(buff[1] == 2) { // authentication char in[2]; char out[515]; char *cur = out; size_t c; *cur++ = 1; // version c = ulen & 0xFF; *cur++ = c; memcpy(cur, user, c); cur += c; c = passlen & 0xFF; *cur++ = c; memcpy(cur, pass, c); cur += c; if((cur - out) != write_n_bytes(sock, out, cur - out)) goto err; if(2 != read_n_bytes(sock, in, 2)) goto err; if(in[0] != 1 || in[1] != 0) { if(in[0] != 1) goto err; else return BLOCKED; } } int buff_iter = 0; buff[buff_iter++] = 5; // version buff[buff_iter++] = 1; // connect buff[buff_iter++] = 0; // reserved if(!dns_len) { buff[buff_iter++] = 1; // ip v4 memcpy(buff + buff_iter, &ip, 4); // dest host buff_iter += 4; } else { buff[buff_iter++] = 3; //dns buff[buff_iter++] = dns_len & 0xFF; memcpy(buff + buff_iter, dns_name, dns_len); buff_iter += dns_len; } memcpy(buff + buff_iter, &port, 2); // dest port buff_iter += 2; if(buff_iter != write_n_bytes(sock, (char *) buff, buff_iter)) goto err; if(4 != read_n_bytes(sock, (char *) buff, 4)) goto err; if(buff[0] != 5 || buff[1] != 0) goto err; switch (buff[3]) { case 1: len = 4; break; case 4: len = 16; break; case 3: len = 0; if(1 != read_n_bytes(sock, (char *) &len, 1)) goto err; break; default: goto err; } if(len + 2 != read_n_bytes(sock, (char *) buff, len + 2)) goto err; return SUCCESS; } break; } err: return SOCKET_ERROR; }
static bool split_file(wave_info *info) { unsigned char header[CANONICAL_HEADER_SIZE]; char outfilename[FILENAME_SIZE],filenum[FILENAME_SIZE]; int current; wint discard,bytes; bool success; wlong leadin_bytes, leadout_bytes, bytes_to_xfer; progress_info proginfo; // uwe double start_time, end_time, last_end_time; success = FALSE; proginfo.initialized = FALSE; proginfo.prefix = "Splitting"; proginfo.clause = "-->"; proginfo.filename1 = info->filename; proginfo.filedesc1 = info->m_ss; proginfo.filename2 = NULL; proginfo.filedesc2 = NULL; proginfo.bytes_total = 0; if (!open_input_stream(info)) { prog_error(&proginfo); st_error("could not reopen input file: [%s]",info->filename); } discard = info->header_size; while (discard > 0) { bytes = min(discard,CANONICAL_HEADER_SIZE); if (read_n_bytes(info->input,header,bytes,NULL) != bytes) { prog_error(&proginfo); st_error("error while discarding %d-byte WAVE header",info->header_size); } discard -= bytes; } leadin_bytes = (leadin) ? smrt_parse((unsigned char *)leadin,info) : 0; leadout_bytes = (leadout) ? smrt_parse((unsigned char *)leadout,info) : 0; adjust_for_leadinout(leadin_bytes,leadout_bytes); // uwe transcription st_output("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"); st_output("<Trans version=\"2\">\n\n"); start_time = end_time = last_end_time = 0; for (current=0;current<numfiles;current++) { if (SPLIT_INPUT_CUE == input_type && cueinfo.format) { create_output_filename(cueinfo.filenames[current],"",outfilename); } else { st_snprintf(filenum,8,num_format,current+offset); create_output_filename(filenum,"",outfilename); } files[current]->chunk_size = files[current]->data_size + CANONICAL_HEADER_SIZE - 8; files[current]->channels = info->channels; files[current]->samples_per_sec = info->samples_per_sec; files[current]->avg_bytes_per_sec = info->avg_bytes_per_sec; files[current]->block_align = info->block_align; files[current]->bits_per_sample = info->bits_per_sample; files[current]->wave_format = info->wave_format; files[current]->rate = info->rate; files[current]->length = files[current]->data_size / (wlong)info->rate; files[current]->exact_length = (double)files[current]->data_size / (double)info->rate; files[current]->total_size = files[current]->chunk_size + 8; length_to_str(files[current]); proginfo.filedesc2 = files[current]->m_ss; proginfo.bytes_total = files[current]->total_size; if (extract_track[current]) { proginfo.prefix = "Splitting"; proginfo.filename2 = outfilename; // uwe transcription start_time += last_end_time; end_time += files[current]->data_size / (wlong)info->rate; last_end_time = end_time; printf("<Turn startTime=\"%.2f\"", start_time); // %.2f st_output(" endTime=\"%.2f\"", end_time); st_output(" splitFilename=\"%s\"", outfilename); st_output(" speaker=\"spk1\">\n"); st_output("<Sync time=\"%.2f\"/>\n", start_time); st_output("***Include transcript words here***\n"); st_output("</Turn>\n"); if (NULL == (files[current]->output = open_output_stream(outfilename,&files[current]->output_proc))) { prog_error(&proginfo); st_error("could not open output file"); } } else { proginfo.prefix = "Skipping "; proginfo.filename2 = NULLDEVICE; if (NULL == (files[current]->output = open_output(NULLDEVICE))) { prog_error(&proginfo); st_error("while skipping track %d: could not open output file: [%s]",current+1,NULLDEVICE); } files[current]->output_proc.pid = NO_CHILD_PID; } if (PROB_ODD_SIZED_DATA(files[current])) files[current]->chunk_size++; make_canonical_header(header,files[current]); // uwe disable //prog_update(&proginfo); if (write_n_bytes(files[current]->output,header,CANONICAL_HEADER_SIZE,&proginfo) != CANONICAL_HEADER_SIZE) { prog_error(&proginfo); st_warning("error while writing %d-byte WAVE header",CANONICAL_HEADER_SIZE); goto cleanup; } /* if this is not the first file, finish up writing previous file, and simultaneously start writing to current file */ if (0 != current) { /* write overlapping lead-in/lead-out data to both previous and current files */ if (transfer_n_bytes2(info->input,files[current]->output,files[current-1]->output,leadin_bytes+leadout_bytes,&proginfo) != leadin_bytes+leadout_bytes) { prog_error(&proginfo); st_warning("error while transferring %ld bytes of lead-in/lead-out",leadin_bytes+leadout_bytes); goto cleanup; } /* pad and close previous file */ if (PROB_ODD_SIZED_DATA(files[current-1]) && (1 != write_padding(files[current-1]->output,1,&proginfo))) { prog_error(&proginfo); st_warning("error while NULL-padding odd-sized data chunk"); goto cleanup; } close_output(files[current-1]->output,files[current-1]->output_proc); } /* transfer unique non-overlapping data from input file to current file */ bytes_to_xfer = files[current]->new_data_size; if (0 != current) bytes_to_xfer -= leadout_bytes; if (numfiles - 1 != current) bytes_to_xfer -= leadin_bytes; if (transfer_n_bytes(info->input,files[current]->output,bytes_to_xfer,&proginfo) != bytes_to_xfer) { prog_error(&proginfo); st_warning("error while transferring %ld bytes of data",bytes_to_xfer); goto cleanup; } /* if this is the last file, close it */ if (numfiles - 1 == current) { /* pad and close current file */ if (PROB_ODD_SIZED_DATA(files[current]) && (1 != write_padding(files[current]->output,1,&proginfo))) { prog_error(&proginfo); st_warning("error while NULL-padding odd-sized data chunk"); goto cleanup; } close_output(files[current]->output,files[current]->output_proc); // uwe transcription st_output("</Trans>\n"); } // uwe disable // prog_success(&proginfo); } close_input_stream(info); success = TRUE; cleanup: if (!success) { close_output(files[current]->output,files[current]->output_proc); remove_file(outfilename); st_error("failed to split file"); } return success; }
static int tunnel_to(int sock, unsigned int ip, unsigned short port, proxy_type pt,char *user,char *pass) { int len; char buff[BUFF_SIZE]; bzero (buff,sizeof(buff)); switch(pt) { case HTTP_TYPE: { sprintf(buff,"CONNECT %s:%d HTTP/1.0\r\n", inet_ntoa( * (struct in_addr *) &ip), ntohs(port)); if (user[0]) { char src[256]; char dst[512]; strcpy(src,user); strcat(src,":"); strcat(src,pass); encode_base_64(src,dst,512); strcat(buff,"Proxy-Authorization: Basic "); strcat(buff,dst); strcat(buff,"\r\n\r\n"); } else strcat(buff,"\r\n"); len=strlen(buff); if(len!=send(sock,buff,len,0)) return SOCKET_ERROR; bzero(buff,sizeof(buff)); len=0 ; // read header byte by byte. while(len<BUFF_SIZE) { if(1==read_n_bytes(sock,buff+len,1)) len++; else return SOCKET_ERROR; if ( len > 4 && buff[len-1]=='\n' && buff[len-2]=='\r' && buff[len-3]=='\n' && buff[len-4]=='\r' ) break; } // if not ok (200) or response greather than BUFF_SIZE return BLOCKED; if ( (len==BUFF_SIZE) || ! ( buff[9] =='2' && buff[10]=='0' && buff[11]=='0' )) return BLOCKED; return SUCCESS; } break; case SOCKS4_TYPE: { memset(buff,0,sizeof(buff)); buff[0]=4; // socks version buff[1]=1; // connect command memcpy(&buff[2],&port,2); // dest port memcpy(&buff[4],&ip,4); // dest host len=strlen(user)+1; // username if(len>1) strcpy(&buff[8],user); if((len+8)!=write_n_bytes(sock,buff,(8+len))) return SOCKET_ERROR; if(8!=read_n_bytes(sock,buff,8)) return SOCKET_ERROR; if (buff[0]!=0||buff[1]!=90) return BLOCKED; return SUCCESS; } break; case SOCKS5_TYPE: { if(user) { buff[0]=5; //version buff[1]=2; //nomber of methods buff[2]=0; // no auth method buff[3]=2; /// auth method -> username / password if(4!=write_n_bytes(sock,buff,4)) return SOCKET_ERROR; } else { buff[0]=5; //version buff[1]=1; //nomber of methods buff[2]=0; // no auth method if(3!=write_n_bytes(sock,buff,3)) return SOCKET_ERROR; } memset(buff,0,sizeof(buff)); if(2!=read_n_bytes(sock,buff,2)) return SOCKET_ERROR; if (buff[0]!=5||(buff[1]!=0&&buff[1]!=2)) { if((buff[0]==0x05)&&(buff[1]==(char)0xFF)) return BLOCKED; else return SOCKET_ERROR; } if (buff[1]==2) { // authentication char in[2]; char out[515]; char* cur=out; int c; *cur++=1; // version c=strlen(user); *cur++=c; strncpy(cur,user,c); cur+=c; c=strlen(pass); *cur++=c; strncpy(cur,pass,c); cur+=c; if((cur-out)!=write_n_bytes(sock,out,cur-out)) return SOCKET_ERROR; if(2!=read_n_bytes(sock,in,2)) return SOCKET_ERROR; if(in[0]!=1||in[1]!=0) { if(in[0]!=1) return SOCKET_ERROR; else return BLOCKED; } } buff[0]=5; // version buff[1]=1; // connect buff[2]=0; // reserved buff[3]=1; // ip v4 memcpy(&buff[4],&ip,4); // dest host memcpy(&buff[8],&port,2); // dest port if(10!=write_n_bytes(sock,buff,10)) return SOCKET_ERROR; if(4!=read_n_bytes(sock,buff,4)) return SOCKET_ERROR; if (buff[0]!=5||buff[1]!=0) return SOCKET_ERROR; switch (buff[3]) { case 1: len=4; break; case 4: len=16; break; case 3: len=0; if(1!=read_n_bytes(sock,(char*)&len,1)) return SOCKET_ERROR; break; default: return SOCKET_ERROR; } if((len+2)!=read_n_bytes(sock,buff,(len+2))) return SOCKET_ERROR; return SUCCESS; } break; } return SOCKET_ERROR; }