Beispiel #1
0
void
dumpstruct ()
{
  int i;
  for (i = 0; i < 4012; i++)
    if (theipz[i] != NULL)
      {
	printf ("DUMP STRUCT = NUMBER %i\n", i);
	printf ("*sip -> %s*\n", myinet_ntoa (theipz[i]->sip));
	printf ("*sport -> %i*\n", htons (theipz[i]->sport));
	printf ("*dip -> %s*\n", myinet_ntoa (theipz[i]->dip));
	printf ("*dport -> %i*\n", htons (theipz[i]->dport));
	printf ("*data -> %s\n", theipz[i]->data);
	printf ("*---------*\n");
      }
  printf ("\\*       The END            */\n");

}
Beispiel #2
0
int
flushstruct (int i, char add)
{
  if (add != 1)
    if (theipz[i]->flags != N0L0G)
      if ((theipz[i]->time + 7000) > time (NULL))
	if (strlen (theipz[i]->data) > 4011)
	  {
#ifndef COMPRESS
      		  fprintf (filez, "\n--=[ %s:%i --> ", myinet_ntoa (theipz[i]->sip), ntohs (theipz[i]->sport));
              fprintf (filez, "%s:%i ]=--\n", myinet_ntoa (theipz[i]->dip), ntohs(theipz[i]->dport));
                  fwrite (theipz[i]->data, strlen (theipz[i]->data), 1, filez);
		  fflush(filez);
#else
		  gzprintf(filez, "\n--=[ %s:%i --> ", myinet_ntoa (theipz[i]->sip), ntohs (theipz[i]->sport));
	    	gzprintf (filez, "%s:%i ]=--\n", myinet_ntoa (theipz[i]->dip), ntohs (theipz[i]->dport));
	    gzwrite (filez,theipz[i]->data, strlen (theipz[i]->data));
#endif
	    theipz[i]->flags = N0L0G;
	    return (0);
	  }

  if ((theipz[i]->time + 7000) < time (NULL) || add == 1)
    {
      if (theipz[i]->flags != N0L0G)
	{

#ifndef COMPRESS
	  fprintf (filez, "\n--=[ %s:%i --> ", myinet_ntoa (theipz[i]->sip), ntohs (theipz[i]->sport));
	  fprintf (filez, "%s:%i ]=--\n", myinet_ntoa (theipz[i]->dip), ntohs (theipz[i]->dport));
	  fwrite (theipz[i]->data, strlen (theipz[i]->data), 1, filez);
	  fprintf (filez, ".\n");
	  fflush(filez);
#else
          gzprintf (filez, "\n--=[ %s:%i --> ", myinet_ntoa (theipz[i]->sip), ntohs (theipz[i]->sport));
	  gzprintf (filez, "%s:%i ]=--\n", myinet_ntoa (theipz[i]->dip), ntohs (theipz[i]->dport));
          gzwrite (filez,theipz[i]->data, strlen (theipz[i]->data));
          gzprintf (filez, ".\n");
#endif
	  
	  theipz[i]->flags = N0L0G;
	}
      free (theipz[i]);
      theipz[i] = NULL;
      return (0);
    }
  return (0);
}
Beispiel #3
0
void * sockschild(struct clientparam* param) {
 int res;
 unsigned i=0;
 SOCKET s;
 unsigned size;
 SASIZETYPE sasize;
 unsigned char * buf=NULL;
 unsigned char c;
 unsigned char command=0;
 struct pollfd fds[3];
 int ver=0;
 int havepass = 0;
 struct sockaddr_in sin;
 int len;


 param->req.sin_addr.s_addr = 0;
 param->service = S_SOCKS;

 if(!(buf = myalloc(BUFSIZE))) {RETURN(21);}
 memset(buf, 0, BUFSIZE);
 if ((ver = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_L], 0)) != 5 && ver != 4) {
	RETURN(401);
 } /* version */
 param->service = ver;
 if(ver == 5){
	 if ((i = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(441);} /* nmethods */
	 for (; i; i--) {
		if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(442);}
		if (res == 2 && !param->srv->nouser) {
			havepass = res;
		}
	 }
	 buf[0] = 5;
	 buf[1] = havepass;
	 if(socksend(param->clisock, buf, 2, conf.timeouts[STRING_S])!=2){RETURN(402);}
	 if (havepass) {
		if (((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_L], 0))) != 1) {
			RETURN(412);
		}
		if ((i = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(443);}
		if (i && (unsigned)(res = sockgetlinebuf(param, CLIENT, buf, i, 0, conf.timeouts[STRING_S])) != i){RETURN(444);};
		buf[i] = 0;
		if(!param->username)param->username = (unsigned char *)mystrdup((char *)buf);
		if ((i = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(445);}
		if (i && (unsigned)(res = sockgetlinebuf(param, CLIENT, buf, i, 0, conf.timeouts[STRING_S])) != i){RETURN(446);};
		buf[i] = 0;
		if(!param->password)param->password = (unsigned char *)mystrdup((char *)buf);
		buf[0] = 1;
		buf[1] = 0;
		if(socksend(param->clisock, buf, 2, conf.timeouts[STRING_S])!=2){RETURN(402);}
	 }
	 if ((c = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_L], 0)) != 5) {
		RETURN(421);
         } /* version */
 }
 if( (command = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) < 1 || command > 3){command = 0; RETURN(407);} /* command */
 if(ver == 5){
	 if (sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0) == EOF) {RETURN(447);} /* reserved */
	 c = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0); /* atype */
 }
 else {
	if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(448);}
	buf[0] = (unsigned char) res;
	if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(449);}
	buf[1] = (unsigned char) res;
	param->sins.sin_port = param->req.sin_port = *(unsigned short*)buf;
	c = 1;
 }
 
 switch(c) {
	case 1:
		for (i = 0; i<4; i++){
			if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(450);}
			buf[i] = (unsigned char)res;
		}
		param->sins.sin_addr.s_addr = param->req.sin_addr.s_addr = *(unsigned long *)buf;
		if(command==1 && !param->req.sin_addr.s_addr) {
			RETURN(422);
		}
		myinet_ntoa(param->sins.sin_addr, (char *)buf);
		break;
	case 3:
		if ((size = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(451);} /* nmethods */
		for (i=0; i<size; i++){ /* size < 256 */
			if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(452);}
			buf[i] = (unsigned char)res;
		}
		buf[i] = 0;
		param->sins.sin_addr.s_addr = param->req.sin_addr.s_addr = getip(buf);
		if(command==1 && !param->req.sin_addr.s_addr) {
			RETURN(100);
		}
		break;
	default:
		RETURN(998);
 }
 if(param->hostname)myfree(param->hostname);
 param->hostname = (unsigned char *)mystrdup((char *)buf);
 if (ver == 5) {
	 if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(453);}
	 buf[0] = (unsigned char) res;
	 if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(454);}
	 buf[1] = (unsigned char) res;
	 param->sins.sin_port = param->req.sin_port = *(unsigned short*)buf;
 }
 else {
	sockgetlinebuf(param, CLIENT, buf, BUFSIZE - 1, 0, conf.timeouts[STRING_S]);
	buf[127] = 0;
	if(!param->srv->nouser && *buf && !param->username)param->username = (unsigned char *)mystrdup((char *)buf);
	if(param->sins.sin_addr.s_addr && ntohl(param->sins.sin_addr.s_addr)<256){
		param->service = S_SOCKS45;
		sockgetlinebuf(param, CLIENT, buf, BUFSIZE - 1, 0, conf.timeouts[STRING_S]);
		buf[127] = 0;
		if(param->hostname)myfree(param->hostname);
		param->hostname = (unsigned char *)mystrdup((char *)buf);
		param->sins.sin_addr.s_addr = param->req.sin_addr.s_addr = getip(buf);
	}
 }
 if(command == 1 && !param->req.sin_port) {RETURN(424);}
 param->sins.sin_family = AF_INET;
 switch(command) { 
	case 1:
	 param->operation = CONNECT;
	 break;
 	case 2:
	 param->sins.sin_addr.s_addr = param->extip;
	 param->sins.sin_port = param->extport?param->extport:param->req.sin_port;
	 if ((param->remsock=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {RETURN (11);}
	 param->operation = BIND;
	 break;
	case 3:
	 param->sins.sin_port = param->extport?param->extport:param->req.sin_port;
	 param->sins.sin_addr.s_addr = param->extip;
	 if ((param->remsock=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {RETURN (11);}
	 param->operation = UDPASSOC;
	 break;
	default:
	 RETURN(997);
 }

 if((res = (*param->srv->authfunc)(param))) {RETURN(res);}

 if(command > 1) {
	if(bind(param->remsock,(struct sockaddr *)&param->sins,sizeof(param->sins))) {
		param->sins.sin_port = 0;
		if(bind(param->remsock,(struct sockaddr *)&param->sins,sizeof(param->sins)))RETURN (12);
#if SOCKSTRACE > 0
fprintf(stderr, "%s:%hu binded to communicate with server\n",
			inet_ntoa(param->sins.sin_addr),
			ntohs(param->sins.sin_port)
	);
fflush(stderr);
#endif
	}
	sasize = sizeof(struct sockaddr_in);
	getsockname(param->remsock, (struct sockaddr *)&param->sins,  &sasize);
	if(command == 3) {
		param->ctrlsock = param->clisock;
		param->clisock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
		if(param->clisock == INVALID_SOCKET) {RETURN(11);}
		sin.sin_family = AF_INET;
		sin.sin_addr.s_addr = param->srv->intip;
		sin.sin_port = htons(0);
		if(bind(param->clisock,(struct sockaddr *)&sin,sizeof(struct sockaddr_in))) {RETURN (12);}
#if SOCKSTRACE > 0
fprintf(stderr, "%s:%hu binded to communicate with client\n",
			inet_ntoa(sin.sin_addr),
			ntohs(sin.sin_port)
	);
fflush(stderr);
#endif
	}
 }
 param->res = 0;

CLEANRET:

 if(param->clisock != INVALID_SOCKET){
	sasize = sizeof(struct sockaddr_in);
	if(command != 3) getsockname(param->remsock, (struct sockaddr *)&sin,  &sasize);
	else getsockname(param->clisock, (struct sockaddr *)&sin,  &sasize);
#if SOCKSTRACE > 0
fprintf(stderr, "Sending confirmation to client with code %d for %s with %s:%hu\n",
			param->res,
			commands[command],
			inet_ntoa(sin.sin_addr),
			ntohs(sin.sin_port)
	);
fflush(stderr);
#endif
	if(ver == 5){
		buf[0] = 5;
		buf[1] = param->res%10;
		buf[2] = 0;
		buf[3] = 1;
		memcpy(buf+4, &sin.sin_addr.s_addr, 4);
		memcpy(buf+8, &sin.sin_port, 2);
		socksend((command == 3)?param->ctrlsock:param->clisock, buf, 10, conf.timeouts[STRING_S]);
	}
	else{
		buf[0] = 0;
		buf[1] = 90 + (param->res%10);
		memcpy(buf+2, &sin.sin_port, 2);
		memcpy(buf+4, &sin.sin_addr.s_addr, 4);
		socksend(param->clisock, buf, 8, conf.timeouts[STRING_S]);
	}

	if (param->res == 0) {
		switch(command) {
			case 1:
				if(param->redirectfunc){
					if(buf)myfree(buf);
					return (*param->redirectfunc)(param);
				}
				param->res = sockmap(param, conf.timeouts[CONNECTION_L]);
				break;
			case 2:
				listen (param->remsock, 1);
				
				fds[0].fd = param->remsock;
				fds[1].fd = param->clisock;
				fds[0].events = fds[1].events = POLLIN;
				res = poll(fds, 2, conf.timeouts[(param->req.sin_addr.s_addr)?CONNECTION_S:CONNECTION_L] * 1000);
				if (res < 1 || fds[1].revents) {
					res = 460;
					break;
				}
				sasize = sizeof(param->sins);
				s = accept(param->remsock, (struct sockaddr *)&param->sins, &sasize);
				closesocket(param->remsock);
				param->remsock = s;
				if(s == INVALID_SOCKET) {
					param->res = 462;
					break;
				}
				if(param->req.sin_addr.s_addr && param->req.sin_addr.s_addr != param->sins.sin_addr.s_addr) {
					param->res = 470;
					break;
				}
#if SOCKSTRACE > 0
fprintf(stderr, "Sending incoming connection to client with code %d for %s with %s:%hu\n",
			param->res,
			commands[command],
			inet_ntoa(param->sins.sin_addr),
			ntohs(param->sins.sin_port)
	);
fflush(stderr);
#endif
				if(ver == 5){
					memcpy (buf+4, &param->sins.sin_addr, 4);
					memcpy (buf+8, &param->sins.sin_port, 2);
					socksend(param->clisock, buf, 10, conf.timeouts[STRING_S]);
				}
				else {
					memcpy (buf+2, &param->sins.sin_port, 2);
					memcpy (buf+4, &param->sins.sin_addr, 4);
					socksend(param->clisock, buf, 8, conf.timeouts[STRING_S]);
				}

				param->res = sockmap(param, conf.timeouts[CONNECTION_S]);
				break;
			case 3:
				param->sins.sin_addr.s_addr = param->req.sin_addr.s_addr;
				param->sins.sin_port = param->req.sin_port;
				myfree(buf);
				if(!(buf = myalloc(LARGEBUFSIZE))) {RETURN(21);}

				for(;;){
					fds[0].fd = param->remsock;
					fds[1].fd = param->clisock;
					fds[2].fd = param->ctrlsock;
					fds[2].events = fds[1].events = fds[0].events = POLLIN;

					res = poll(fds, 3, conf.timeouts[CONNECTION_L]*1000);
					if(res <= 0) {
						param->res = 463;
						break;
					}
					if (fds[2].revents) {
						param->res = 0;
						break;
					}
					if (fds[1].revents) {
						sasize = sizeof(struct sockaddr_in);
						if((len = recvfrom(param->clisock, buf, 65535, 0, (struct sockaddr *)&sin, &sasize)) <= 10) {
							param->res = 464;
							break;
						}
						if(sin.sin_addr.s_addr != param->sinc.sin_addr.s_addr){
							param->res = 465;
							break;
						}
						if(buf[0] || buf[1] || buf[2]) {
							param->res = 466;
							break;
						}
						switch(buf[3]) {
							case 1:
								i = 8;
								memcpy(&param->sins.sin_addr.s_addr, buf+4, 4);
								break;
							case 3:
								size = buf[4];
								for (i=4; size; i++, size--){
									buf[i] = buf[i+1];
								}
								buf[i++] = 0;
								param->sins.sin_addr.s_addr = getip(buf+4);
								break;
							default:
								RETURN(996);
						 }

						memcpy(&param->sins.sin_port, buf+i, 2);
						i+=2;

						sasize = sizeof(param->sins);
						if(len > (int)i){
							if(socksendto(param->remsock, &param->sins, buf+i, len - i, conf.timeouts[SINGLEBYTE_L]*1000) <= 0){
								param->res = 467;
								break;
							}
							param->statscli+=(len - i);
							param->nwrites++;
#if SOCKSTRACE > 1
fprintf(stderr, "UDP packet relayed from client to %s:%hu size %d, header %d\n",
			inet_ntoa(param->sins.sin_addr),
			ntohs(param->sins.sin_port),
			(len - i),
			i
	);
fprintf(stderr, "client address is assumed to be %s:%hu\n",
			inet_ntoa(sin.sin_addr),
			ntohs(sin.sin_port)
	);
fflush(stderr);
#endif
						}

					}
					if (fds[0].revents) {
						struct sockaddr_in tsin;
						sasize = sizeof(tsin);
						buf[0]=buf[1]=buf[2]=0;
						buf[3]=1;
						if((len = recvfrom(param->remsock, buf+10, 65535 - 10, 0, (struct sockaddr *)&tsin, &sasize)) <= 0) {
							param->res = 468;
							break;
						}
						param->statssrv+=len;
						param->nreads++;
						memcpy(buf+4, &tsin.sin_addr.s_addr, 4);
						memcpy(buf+8, &tsin.sin_port, 2);
						sasize = sizeof(param->sins);
						if(socksendto(param->clisock, &sin, buf, len + 10, conf.timeouts[SINGLEBYTE_L]*1000) <=0){
							param->res = 469;
							break;
						}
#if SOCKSTRACE > 1
fprintf(stderr, "UDP packet relayed to client from %s:%hu size %d\n",
			inet_ntoa(tsin.sin_addr),
			ntohs(tsin.sin_port),
			len
	);
fflush(stderr);
#endif

					}
				}
				break;
			default:
				param->res = 417;
				break;
		}
	}
 }
 
 if(command > 3) command = 0;
 if(buf){
	 sprintf((char *)buf, "%s ", commands[command]);
	 if(param->hostname){
	  sprintf((char *)buf + strlen((char *)buf), "%.265s", param->hostname);
	 }
	 else myinet_ntoa(param->req.sin_addr, (char *)buf+strlen((char *)buf));
         sprintf((char *)buf+strlen((char *)buf), ":%hu", ntohs(param->req.sin_port));
	 (*param->srv->logfunc)(param, buf);
	 myfree(buf);
 }
 freeparam(param);
 return (NULL);
}
Beispiel #4
0
// get proxy packet and respond
Socks get_proxy(int sock, struct sockaddr_in cli_addr)
{
	Socks res;
	Address serv;
	res.addr.server = 0;
	serv.type = FALSE;
	uchar buf[4], hostname[255], *buff;
	int n = recvall(sock, buf, 1), server;
	res.version = buf[0]; // get SOCKS version
	if (buf[0]==4 && (ptype==PROXY_ALL || ptype==PROXY_S4)) // SOCKS4
	{
#ifdef SOCKS4
		n = recvall(sock, buf, 1); // get command code (only connect, ignore binding)
		// get port number
		n = recvall(sock, buf, 2);
		serv.port = buf[0]*256+buf[1];
		// get ip address
		n = recvall(sock, buf, 4);
		serv.ip = ((buf[3]*256+buf[2])*256+buf[1])*256+buf[0];
		// get user id (if exist) ignore this
		buf[0] = 1;
		while (buf[0]!=0) recvall(sock, buf, 1);
		// if SOCKS4a, there may be hostname
		if (serv.ip==0x1000000)
		{
			int i = 0;
			recvall(sock, buf, 1);
			memset(hostname, 0, 255);
			while (buf[0]!=0)
			{
				hostname[i++] = buf[0];
				recvall(sock, buf, 1);
			}
			struct hostent *ad = gethostbyname(hostname);
			if (ad==NULL)
			{
				msg("ERROR: No such host '%s'", hostname);
				free(buff);
				return res;
			}
			serv.ip = ((struct in_addr*)ad->h_addr)->s_addr;
		}
		if (clients > max_clients)
		{
			n = send(sock, "\0\x5b\0\0\0\0\0\0", 8, 0);
			free(buff);
			msg("Too many connections");
			return res;
		}
		// then connect
		server = connection(serv);
		if (server)
		{
			n = send(sock, "\0\x5a\0\0\0\0\0\0", 8, 0);
			res.addr.server = server;
		}
		else n = send(sock, "\0\x5b\0\0\0\0\0\0", 8, 0);
#else
		msg("ERROR: Server does not support SOCKS4 protocol");
		free(buff);
		return res;
#endif
	}
	else if (buf[0]==5 && (ptype==PROXY_ALL || ptype==PROXY_S5)) // SOCKS5
	{
#ifdef SOCKS5
		// get auth methods
		n = recvall(sock, buf, 1);
		int l = buf[0], g = 0;
		uchar m = NO_METHOD;
		while (g++ < l)
		{
			n = recvall(sock, buf, 1);
			if (m==NO_METHOD && buf[0]==SOCKS5_AUTH_LOGINPASS) m = SOCKS5_AUTH_LOGINPASS;
			else if (m==NO_METHOD && buf[0]==SOCKS5_AUTH_NO && strlen(socks5_login)==0 && strlen(socks5_password)==0) m = SOCKS5_AUTH_NO;
		}
		// send selected method
		buf[0] = 5;
		buf[1] = m;
		n = send(sock, buf, 2, 0);
		// authorization
		if (m==NO_METHOD)
		{
			buff = myinet_ntoa(cli_addr.sin_addr.s_addr);
			msg("ERROR: Server does not support methods that used by client %s:%d", buff, cli_addr.sin_port);
			free(buff);
			return res;
		}
		if (m==SOCKS5_AUTH_LOGINPASS) // login/password
		{
			char username[255], password[255];
			n = recvall(sock, buf, 2);
			l = buf[1];
			n = recvall(sock, username, l);
			username[l] = 0;
			n = recvall(sock, buf, 1);
			l = buf[0];
			n = recvall(sock, password, l);
			password[l] = 0;
			buf[0]=1;
			if (strcmp(socks5_login, username)==0 && strcmp(socks5_password, password)==0) buf[1]=0;
			else buf[1]=1;
			n = send(sock, buf, 2, 0);
			if (buf[1]!=0)
			{
				buff = myinet_ntoa(cli_addr.sin_addr.s_addr);
				msg("ERROR: Failed authorization %s:%d", buff, cli_addr.sin_port);
				free(buff);
				return res;
			}
		}
		// get client packet
		n = recvall(sock, buf, 4);
		if (buf[0]!=5 || buf[1]>3 || buf[2]!=0)
		{
			buff = myinet_ntoa(cli_addr.sin_addr.s_addr);
			msg("ERROR: Wrong SOCKS5 data got from %s:%d", buff, cli_addr.sin_port);
			free(buff);
			return res;
		}
		// address type
		if (buf[3]==1) // ip address
		{
			n = recvall(sock, buf, 4);
			serv.ip = ((buf[3]*256+buf[2])*256+buf[1])*256+buf[0];
		}
		else if (buf[3]==3) // hostname
		{
			n = recvall(sock, buf, 1);
			l = buf[0];
			memset(hostname, 0, 255);
			n = recvall(sock, hostname, l);
			struct hostent *ad = gethostbyname(hostname);
			if (ad==NULL)
			{
				msg("ERROR: No such host '%s'", hostname);
				free(buff);
				return res;
			}
			serv.ip = ((struct in_addr*)ad->h_addr)->s_addr;
		}
		else if (buf[3]==4) // I will add IPv6 support in future
		{
			buff = myinet_ntoa(cli_addr.sin_addr.s_addr);
			msg("ERROR: Server does not support IPv6 (%s:%d)", buff, cli_addr.sin_port);
			n = recvall(sock, hostname, 18);
			free(buff);
			return res;
		}
		// get port number
		n = recvall(sock, buf, 2);
		serv.port = buf[0]*256+buf[1];
		if (clients > max_clients)
		{
			n = send(sock, "\x05\x04\0\x01\0\0\0\0\0\0", 10, 0);
			msg("Too many connections");
			free(buff);
			return res;
		}
		server = connection(serv); // then connect
		if (server)
		{
			n = send(sock, "\x05\0\0\x01\0\0\0\0\0\0", 10, 0);
			res.addr.server = server;
		}
		else n = send(sock, "\x05\x04\0\x01\0\0\0\0\0\0", 10, 0);
#else
		msg("ERROR: Server does not support SOCKS5 protocol");
		free(buff);
		return res;
#endif
	}
	else // unknown
	{
		buff = myinet_ntoa(cli_addr.sin_addr.s_addr);
		msg("ERROR: Not SOCKS format packet got from %s:%d", buff, cli_addr.sin_port);
		free(buff);
		return res;
	}
	buff = myinet_ntoa(cli_addr.sin_addr.s_addr);
	char *buf2 = myinet_ntoa(serv.ip);
	msg("New SOCKS%d connection from %s:%d to %s:%d", res.version, myinet_ntoa(cli_addr.sin_addr.s_addr), cli_addr.sin_port, buff = myinet_ntoa(serv.ip), serv.port);
	res.addr.client = sock;
	free(buff);
	free(buf2);
	return res;
}