예제 #1
0
/// Replacement gethostbyname.
struct hostent* gethostbyname(const char *name)
{
  if (!real_gethostbyname)
  {
    real_gethostbyname = (struct hostent*(*)(const char*))(intptr_t)dlsym(RTLD_NEXT, "gethostbyname");
  }

  return real_gethostbyname(host_lookup(name).c_str());
}
예제 #2
0
/// Replacement getaddrinfo.
int getaddrinfo(const char *node,
                const char *service,
                const struct addrinfo *hints,
                struct addrinfo **res)
{
  if (!real_getaddrinfo)
  {
    real_getaddrinfo = (int(*)(const char*, const char*, const struct addrinfo*, struct addrinfo**))(intptr_t)dlsym(RTLD_NEXT, "getaddrinfo");
  }

  return real_getaddrinfo(host_lookup(node).c_str(), service, (const struct addrinfo*)hints, (struct addrinfo**)res);
}
예제 #3
0
		/* FIXME: we should save client ipaddr into c->ipaddr after accept */
		static int dbs_verify_ipaddr(char const * addrlist, t_d2dbs_connection * c)
		{
			char			* adlist;
			char			* s, *temp;
			t_elem			* elem;
			t_d2dbs_connection	* tempc;
			unsigned int		valid;
			unsigned int		resolveipaddr;

			adlist = xstrdup(addrlist);
			temp = adlist;
			valid = 0;
			while ((s = strsep(&temp, ","))) {
				host_lookup(s, &resolveipaddr);
				if (resolveipaddr == 0) continue;

				if (c->ipaddr == resolveipaddr) {
					valid = 1;
					break;
				}
			}
			xfree(adlist);
			if (valid) {
				eventlog(eventlog_level_info, __FUNCTION__, "ip address %s is valid", addr_num_to_ip_str(c->ipaddr));
				LIST_TRAVERSE(dbs_server_connection_list, elem)
				{
					if (!(tempc = (t_d2dbs_connection*)elem_get_data(elem))) continue;
					if (tempc != c && tempc->ipaddr == c->ipaddr) {
						eventlog(eventlog_level_info, __FUNCTION__, "destroying previous connection %d", tempc->serverid);
						dbs_server_shutdown_connection(tempc);
						list_remove_elem(dbs_server_connection_list, &elem);
					}
				}
				c->verified = 1;
				return 0;
			}
			else {
예제 #4
0
파일: process.c 프로젝트: krichter722/gfarm
gfarm_error_t
process_replica_adding(struct process *process,
	struct peer *peer, struct host *spool_host, char *src_host, int fd,
	gfarm_ino_t *inump, gfarm_uint64_t *genp,
	gfarm_int64_t *mtime_secp, gfarm_int32_t *mtime_nsecp)
{
	struct file_opening *fo;
	struct gfarm_timespec *mtime;
	gfarm_error_t e = process_get_file_opening(process, fd, &fo);

	if (e != GFARM_ERR_NO_ERROR)
		return (e);
	if (!inode_is_file(fo->inode)) /* i.e. is a directory */
		return (GFARM_ERR_OPERATION_NOT_PERMITTED);
	if (fo->u.f.spool_opener != NULL) /* already REOPENed */
		return (GFARM_ERR_OPERATION_NOT_PERMITTED);
	if (inode_is_creating_file(fo->inode)) /* no file copy */
		return (GFARM_ERR_NO_SUCH_OBJECT);
	if (!inode_has_replica(fo->inode, host_lookup(src_host)))
		return (GFARM_ERR_NO_SUCH_OBJECT);
	if (inode_has_replica(fo->inode, spool_host))
		return (GFARM_ERR_ALREADY_EXISTS);

	e = inode_add_replica(fo->inode, spool_host, 0);
	if (e != GFARM_ERR_NO_ERROR)
		return (e);

	fo->u.f.spool_opener = peer;
	fo->u.f.spool_host = spool_host;
	*inump = inode_get_number(fo->inode);
	*genp = inode_get_gen(fo->inode);
	mtime = inode_get_mtime(fo->inode);
	*mtime_secp = mtime->tv_sec;
	*mtime_nsecp = mtime->tv_nsec;
	return (GFARM_ERR_NO_ERROR);
}
예제 #5
0
int arp_hijack(struct conn_info *ci, char *src_fake_mac, char *dst_fake_mac,
	       int input_mode)
{
	struct iphdr *iph;
	struct tcphdr *tcph;
	struct tcp_spec ts;
	struct ifunc_item ifunc_dst, ifunc_src;
	struct packet *p;
	int count_dst = 0, count_src = 0;
	pthread_t thr_tty;
	struct watch_tty_data wtd;

	asi_src = asi_dst = NULL;
	
	dont_relay = arp_dont_relay_insert(ci->src_addr, ci->dst_addr,
	 	 		           ci->src_port, ci->dst_port);
	if (src_fake_mac) {
		if (!(asi_src = start_arp_spoof(ci->src_addr, ci->dst_addr, NULL, NULL, NULL, 0, 0, 0))) {
			asi_src = start_arp_spoof(ci->src_addr, ci->dst_addr,
			  		      ci->src.src_mac, ci->dst.src_mac,
					      src_fake_mac, 0, 0, 0);
		}
	} else
		asi_src = get_arp_spoof(ci->src_addr, ci->dst_addr);
	if (asi_src && user_arpspoof_test(asi_src)) {
		if (user_run_arpspoof_until_successed(asi_src)) {
			set_tty_color(COLOR_BRIGHTRED);
			printf("ARP spoof of %s in host %s FAILED\n",
			       host_lookup(asi_src->src_addr, hl_mode),
			       host_lookup(asi_src->dst_addr, hl_mode));
			set_tty_color(COLOR_LIGHTGRAY);
			fflush(stdout);
			if (src_fake_mac)
				stop_arp_spoof(asi_src);
			asi_src = NULL;
		}
	}
	if (dst_fake_mac) {
		if (!(asi_dst = start_arp_spoof(ci->dst_addr, ci->src_addr, NULL, NULL, NULL, 0, 0, 0))) {
			asi_dst = start_arp_spoof(ci->dst_addr, ci->src_addr,
					      ci->dst.src_mac, ci->src.src_mac,
					      dst_fake_mac, 0, 0, 0);
		}
	} else
		asi_dst = get_arp_spoof(ci->dst_addr, ci->src_addr);
	
	if (asi_dst && user_arpspoof_test(asi_dst)) {
		if (user_run_arpspoof_until_successed(asi_dst)) {
			set_tty_color(COLOR_BRIGHTRED);
			printf("ARP spoof of %s in host %s FAILED\n",
			       host_lookup(asi_dst->src_addr, hl_mode),
			       host_lookup(asi_dst->dst_addr, hl_mode));
			set_tty_color(COLOR_LIGHTGRAY);
			fflush(stdout);
			if (dst_fake_mac)
				stop_arp_spoof(asi_dst);
			asi_dst = NULL;
		}
	}
	set_tty_color(COLOR_WHITE);
	printf("you took over the connection\n");
	set_tty_color(COLOR_BRIGHTRED);
	printf("CTRL-] to break\n");
	set_tty_color(COLOR_LIGHTGRAY);
	fflush(stdout);

	wtd.src_fake_mac = asi_src ? asi_src->src_fake_mac : ci->src.src_mac;
	wtd.ci = ci;
	wtd.input_mode = input_mode;
	
	list_produce_start(&l_hijack_conn);
	pthread_create(&thr_tty, NULL, (void *(*)(void *)) watch_tty, &wtd);
	
	ifunc_dst.func = (void(*)(struct packet *, void *)) func_hijack_dst;
	ifunc_dst.arg = ci;
	list_enqueue(&l_ifunc_tcp, &ifunc_dst);
	ifunc_src.func = (void(*)(struct packet *, void *)) func_hijack_src;
	ifunc_src.arg = ci;
	list_enqueue(&l_ifunc_tcp, &ifunc_src);
	
	while ((p = list_consume(&l_hijack_conn, NULL))) {
		iph = p->p_iph;
		tcph = p->p_hdr.p_tcph;
		if (iph->saddr == ci->dst_addr &&
		    iph->daddr == ci->src_addr &&
		    tcph->source == ci->dst_port &&
		    tcph->dest == ci->src_port) {
			/* packet from dest */
			if (p->p_data_len) {
				print_data_packet(p, p->p_data_len, ++count_dst, 1);
				packet_free(p);
				/* send ACK */
				memset(&ts, 0, sizeof(ts));
				ts.saddr = ci->src_addr;
				ts.daddr = ci->dst_addr;
				ts.sport = ci->src_port;
				ts.dport = ci->dst_port;
				ts.src_mac = asi_src ? asi_src->src_fake_mac :
						ci->src.src_mac;
				ts.dst_mac = ci->dst.src_mac;
				ts.seq = ci->dst.next_d_seq;
				ts.ack_seq = ci->dst.next_seq;
				ts.window = ci->src.window ? ci->src.window : htons(242);
				ts.id = htons(ntohs(ci->src.id) + 1);
				ts.ack = 1;
				ts.psh = 1;
				ts.rst = 0;
				ts.data = NULL;
				ts.data_len = 0;
				send_tcp_packet(&ts);
			} else
				packet_free(p);
		} else {
			if (p->p_data_len) {
				/* packet from source */
				print_data_packet(p, p->p_data_len, ++count_src, 0);
				memset(&ts, 0, sizeof(ts));
				ts.saddr = ci->dst_addr;
				ts.daddr = ci->src_addr;
				ts.sport = ci->dst_port;
				ts.dport = ci->src_port;
				ts.src_mac = asi_dst ? asi_dst->src_fake_mac : 
							ci->dst.src_mac;
				ts.dst_mac = ci->src.src_mac;
				ts.seq = ci->src.next_d_seq;
				ts.ack_seq = ci->src.next_seq;
				ts.window = ci->dst.window ? ci->dst.window : 
							htons(242);
				ts.id = htons(ntohs(ci->dst.id) + 1);
				ts.ack = 1;
				ts.psh = 1;
				ts.rst = 0;
				if (p->p_data[0] == '\r' || p->p_data[0] == '\n') {
					ts.data = "\r\n$ ";
					ts.data_len = 4;
				} else {
					ts.data = p->p_data;
					ts.data_len = p->p_data_len;
				}
				send_tcp_packet(&ts);
			}
			packet_free(p);
		}
	}
	list_remove(&l_ifunc_tcp, &ifunc_dst);
	list_remove(&l_ifunc_tcp, &ifunc_src);
	packet_flush(&l_hijack_conn);
	pthread_join(thr_tty, NULL);

	return 0;
}
예제 #6
0
파일: addr.c 프로젝트: Danteoriginal/bnetd
extern t_netaddr * netaddr_create_str(char const * netstr)
{
    t_netaddr *  netaddr;
    char *       temp;
    char const * netipstr;
    char const * netmaskstr;
    unsigned int netip;
    unsigned int netmask;
    
    if (!netstr)
    {
	eventlog(eventlog_level_error,"netaddr_create_str","unable to allocate memory for netaddr");
	return NULL;
    }
    
    if (!(temp = strdup(netstr)))
    {
	eventlog(eventlog_level_error,"netaddr_create_str","could not allocate memory for temp");
	return NULL;
    }
    if (!(netipstr = strtok(temp,"/")))
    {
	free(temp);
	return NULL;
    }
    if (!(netmaskstr = strtok(NULL,"/")))
    {
	free(temp);
	return NULL;
    }
    
    if (!(netaddr = malloc(sizeof(t_netaddr))))
    {
	eventlog(eventlog_level_error,"netaddr_create_str","could not allocate memory for netaddr");
	free(temp);
	return NULL;
    }
    
    /* FIXME: call getnetbyname() first, then host_lookup() */
    if (!host_lookup(netipstr,&netip))
    {
	eventlog(eventlog_level_error,"netaddr_create_str","could not lookup net");
	free(netaddr);
	free(temp);
	return NULL;
    }
    netaddr->ip = netip;
    
    if (str_to_uint(netmaskstr,&netmask)<0)
    {
	struct sockaddr_in tsa;
	
	if (inet_aton(netmaskstr,&tsa.sin_addr))
	    netmask = ntohl(tsa.sin_addr.s_addr);
	else
	{
	    eventlog(eventlog_level_error,"netaddr_create_str","could not convert mask");
	    free(netaddr);
	    free(temp);
	    return NULL;
	}
    }
    else
    {
	if (netmask>32)
	{
	    eventlog(eventlog_level_error,"netaddr_create_str","network bits must be less than or equal to 32 (%u)",netmask);
	    free(netaddr);
	    free(temp);
	    return NULL;
	}
	/* for example, 8 -> 11111111000000000000000000000000 */
	if (netmask!=0)
	    netmask = ~((1<<(32-netmask))-1);
    }
    netaddr->mask = netmask;
    
    return netaddr;
}
예제 #7
0
파일: addr.c 프로젝트: Danteoriginal/bnetd
extern t_addr * addr_create_str(char const * str, unsigned int defipaddr, unsigned short defport)
#endif
{
    char *             tstr;
    t_addr *           temp;
    unsigned int       ipaddr;
    unsigned short     port;
    char const *       hoststr;
    char *             portstr;
    char const *       hostname;
    
    if (!str)
    {
	eventlog(eventlog_level_error,"addr_create_str","got NULL str");
	return NULL;
    }
    
    if (!(tstr = strdup(str)))
    {
	eventlog(eventlog_level_error,"addr_create_str","could not allocate memory for str");
	return NULL;
    }
    
    if ((portstr = strrchr(tstr,':')))
    {
	char * protstr;
	
	*portstr = '\0';
	portstr++;
	
	if ((protstr = strrchr(portstr,'/')))
	{
	    *protstr = '\0';
	    protstr++;
	}
	
	if (portstr[0]!='\0')
	{
	    if (str_to_ushort(portstr,&port)<0)
	    {
#ifdef HAVE_GETSERVBYNAME
		struct servent * sp;
		
		if (!(sp = getservbyname(portstr,protstr?protstr:"tcp")))
#endif
		{
		    eventlog(eventlog_level_error,"addr_create_str","could not convert \"%s\" to a port number",portstr);
		    free(tstr);
		    return NULL;
		}
#ifdef HAVE_GETSERVBYNAME
		port = ntohs(sp->s_port);
#endif
	    }
	}
	else
	    port = defport;
    }
    else
	port = defport;
    
    if (tstr[0]!='\0')
	hoststr = tstr;
    else
    {
	struct sockaddr_in tsa;
	
	tsa.sin_addr.s_addr = htonl(defipaddr);
	hoststr = inet_ntoa(tsa.sin_addr);
    }
    
    if (!(hostname = host_lookup(hoststr,&ipaddr)))
    {
	eventlog(eventlog_level_error,"addr_create_str","could not lookup host \"%s\"",hoststr);
	free(tstr);
	return NULL;
    }
    
#ifdef USE_CHECK_ALLOC
    if (!(temp = check_malloc_real(sizeof(t_addr),fn,ln)))
#else
    if (!(temp = malloc(sizeof(t_addr))))
#endif
    {
	eventlog(eventlog_level_error,"addr_create_str","unable to allocate memory for addr");
	free(tstr);
	return NULL;
    }
    
    if (!(temp->str = strdup(hostname)))
    {
	eventlog(eventlog_level_error,"addr_create_str","could not allocate memory for str");
	free(temp);
	free(tstr);
	return NULL;
    }
    free(tstr);
    
    temp->ip     = ipaddr;
    temp->port   = port;
    temp->data.p = NULL;
    
    return temp;
}
예제 #8
0
파일: ftp.c 프로젝트: casualuser/yafc
int ftp_open_url(url_t *urlp, bool reset_vars)
{
    bool use_proxy;
    int i;

    if(reset_vars)
        ftp_reset_vars();
    /* don't assume server is in ascii mode initially even if RFC says so */
    ftp->prev_type = '?';

#ifdef HAVE_POSIX_SIGSETJMP
    if(sigsetjmp(open_timeout_jmp, 1))
#else
    if(setjmp(open_timeout_jmp))
#endif
    {
        ftp_close();
        ftp_err(_("Connection timeout after %u seconds\n"),
                ftp->open_timeout);
        return 1;
    }
    ftp_set_signal(SIGALRM, ftp_open_handler);
    alarm(ftp->open_timeout);

    use_proxy = (proxy_type(urlp) != 0);

    ftp_err(_("Looking up %s... "),
            use_proxy ? gvProxyUrl->hostname : urlp->hostname);

    /* Set the default port (22) for SSH if no port is specified. We
     * need to do this here, 'cause host_lookup() sets it to 21
     * (default port for vanilla FTP)
     */
    if(urlp->protocol) {
        if(strcmp(urlp->protocol, "sftp") == 0)
            url_setprotocol(urlp, "ssh");
        if(strcmp(urlp->protocol, "ssh") == 0 && urlp->port == -1)
            urlp->port = 22; /* default SSH port */
    }

    ftp->host = host_create(use_proxy ? gvProxyUrl : urlp);

    if(!host_lookup(ftp->host)) {
        herror(host_getname(ftp->host));
        alarm(0);
        ftp_set_signal(SIGALRM, SIG_IGN);
        return -1;
    }
    /* keep the value in urlp->port
    urlp->port = ntohs(ftp->host->port);
    and set it to 21 if it is -1 */
    if(urlp->port == -1) {
	    urlp->port = 21;
    }


    fprintf(stderr, "\r               ");
    i = strlen(use_proxy ? gvProxyUrl->hostname : urlp->hostname);
    while(i--)
        fprintf(stderr, " ");
    fprintf(stderr, "\r");
    ftp_trace("\n");

#ifdef HAVE_LIBSSH
    if(urlp->protocol && strcmp(urlp->protocol, "ssh") == 0) {
        int ret = ssh_open_url(urlp);
        alarm(0);
        return ret;
    }
#endif

    if(urlp->protocol && strcmp(urlp->protocol, "ftp") != 0) {
        ftp_err(_("Sorry, don't know how to handle your '%s' protocol\n"
                  "trying 'ftp' instead...\n"),
                urlp->protocol);
        url_setprotocol(urlp, 0);
    }

    if(use_proxy) {
        ftp_err(_("Connecting to proxy %s at port %d...\n"),
                host_getoname(ftp->host), urlp->port);
    } else {
        ftp_err(_("Connecting to %s at port %d...\n"),
                host_getoname(ftp->host), urlp->port);
    }

    ftp->ctrl = sock_create();
    if (ftp->ctrl == 0) {
        ftp_err(_("Unable to create socket.\n"));
        alarm(0);
        ftp_set_signal(SIGALRM, SIG_IGN);
        return -1;
    }

    if(!sock_connect_host(ftp->ctrl, ftp->host)) {
        alarm(0);
        ftp_set_signal(SIGALRM, SIG_IGN);
        return -1;
    }
    sock_lowdelay(ftp->ctrl);
    char* ip = host_getip(ftp->host);
    ftp_err(_("Connected to %s ([%s]:%d).\n"),
        host_getoname(ftp->host), ip, urlp->port);
    free(ip);

    /* read startup message from server */
    ftp_set_tmp_verbosity(vbCommand);
    ftp_read_reply();
    if(ftp->fullcode == 120) {
        ftp_set_tmp_verbosity(vbCommand);
        ftp_read_reply();
    }
    alarm(0);
    ftp_set_signal(SIGALRM, SIG_IGN);
    if(!sock_connected(ftp->ctrl)) {
        ftp_close();
        return 1;
    }
    ftp->connected = (ftp->fullcode == 220);

    if(ftp->connected) {
        void (*tracefunq)(const char *fmt, ...);

        url_destroy(ftp->url);
        ftp->url = url_clone(urlp);

        tracefunq = (ftp->verbosity == vbDebug ? ftp_err : ftp_trace);

        char* remote_addr = printable_address(sock_remote_addr(ftp->ctrl)),
            *local_addr = printable_address(sock_local_addr(ftp->ctrl));
        tracefunq("remote address: %s\n", remote_addr);
        tracefunq("local address: %s\n", local_addr);
        free(remote_addr);
        free(local_addr);

        return 0;
    } else {
        ftp_close();
        return 1;
    }
}
예제 #9
0
	extern t_addr * addr_create_str(char const * str, unsigned int defipaddr, unsigned short defport)
	{
		char *             tstr;
		t_addr *           temp;
		unsigned int       ipaddr;
		unsigned short     port;
		char const *       hoststr;
		char *             portstr;
		char const *       hostname;

		if (!str)
		{
			eventlog(eventlog_level_error, __FUNCTION__, "got NULL str");
			return NULL;
		}

		tstr = xstrdup(str);

		if ((portstr = std::strrchr(tstr, ':')))
		{
			char * protstr;

			*portstr = '\0';
			portstr++;

			if ((protstr = std::strrchr(portstr, '/')))
			{
				*protstr = '\0';
				protstr++;
			}

			if (portstr[0] != '\0')
			{
				if (str_to_ushort(portstr, &port) < 0)
				{
#ifdef HAVE_GETSERVBYNAME
					struct servent * sp;

					if (!(sp = getservbyname(portstr, protstr ? protstr : "tcp")))
#endif
					{
						eventlog(eventlog_level_error, __FUNCTION__, "could not convert \"%s\" to a port number", portstr);
						xfree(tstr);
						return NULL;
					}
#ifdef HAVE_GETSERVBYNAME
					port = ntohs(sp->s_port);
#endif
				}
			}
			else
				port = defport;
		}
		else
			port = defport;

		if (tstr[0] != '\0')
			hoststr = tstr;
		else
		{
			struct sockaddr_in tsa;

			tsa.sin_addr.s_addr = htonl(defipaddr);
			char addrstr[INET_ADDRSTRLEN] = { 0 };
			hoststr = inet_ntop(AF_INET, &(tsa.sin_addr), addrstr, sizeof(addrstr));
		}

		if (!(hostname = host_lookup(hoststr, &ipaddr)))
		{
			eventlog(eventlog_level_error, __FUNCTION__, "could not lookup host \"%s\"", hoststr);
			xfree(tstr);
			return NULL;
		}

		temp = (t_addr*)xmalloc(sizeof(t_addr));
		temp->str = xstrdup(hostname);
		xfree(tstr);

		temp->ip = ipaddr;
		temp->port = port;
		temp->data.p = NULL;

		return temp;
	}
예제 #10
0
main(int argc, char *argv[])
{
unsigned long int contador;
char *charptr;
int client;
int first[2], second[2];
char hname[200];
struct hostent *he;
int aux;
fd_set infd, tinfd;
struct timeval tv, *ptrtv;

// SACAR TODOS LOS PARAMETROS
init_params(argc, argv);


///////////////////////// SACAR NOMBRE HOST LOCAL  /////////////////////////////
// SI ESTAMOS EN MODO CLIENTE Y (1 SOLO PARAMETRO O -v)
gethostname(hname, 200);
IFV(printf("Local host: %s\n\n", hname));

if(!params.S)
{ // SI ESTAMOS EN MODO CLIENTE SACAR ESTADISTICAS DEL HOST REMOTO
  /*in_addr i;
  he=gethostbyaddres(&i, SIZEOF(i), AF_INET);*/
  he=gethostbyname(params.host);
  if(!he) perror_exit("Host not found");
  IFV(print_host_stats(he));
}

////////// A PARTIR DE AQUI SOLO SE CONECTA SI SE PASO PUERTO OMO ULTIMO PARAMETRO
if(NPARAMS==1) return 0; // SI SOLO HUBO UN PARAMETRO, SOLO QUERIAMOS COMPROBAR EL HOST, ADIOS

// SI LLEGAMOS AQUI, EL Nº DE PUERTO ES EL ULTIMO PARAMETRO

//PRINTV(NPARAMS);

///////////////////////////////////////////////////////////////////////////////////
// AQUI SE DECIDE EL COMPORTAMIENTO PRINCIPAL DEL PROGRAMA CLIENTE/SERVIDOR
if(!params.S) // CLIENTE
{
  charptr=he_addr(he, 0);  // LO INTENTAMOS CON LA 1A DIRECCION
  IFV( printf("\nTrying to connect to %s on port %d... ", charptr, params.port) );
  client=socket_connect(charptr, params.port);
  if(client==-1) perror_exit("Error connecting to server");
  IFV(printf("connected.\n"));
  // CONFIGURACION DE ORDEN DE LECTURA DE CANALES EN MODO CLIENTE
  first[0]=0; first[1]=client;
  second[0]=client; second[1]=1;
}
else   //SERVIDOR //
{
  IFV(printf("Listening on local port %d... ", params.port));
  client=quick_accept(params.port);
  if(client==-1) perror_exit("Cannot bind to specified port");
  IFV(printf("connected.\n"));

  close(aux);
  IFV(printf("Reverse host lookup\n"));
  IFV(print_host_stats(host_lookup(client)));
  
  if(params.e) execute_command(client, argc, argv);  // ESTA ES LA MEJOR OPCION...
  // CONFIGURACION DE ORDEN DE LECTURA DE CANALES EN MODO SERVIDOR
  first[0]=client; first[1]=1; // PRIMERO LEER DE SOCKET Y ESCRIBIR A STDOUT
  second[0]=0; second[1]=client;  // LUEGO "RESPONDER", LEYENDO DE STDIN Y ESCRIBIENDO A SOCKET

  // DAR TIEMPO AL CLIENTE A QUE NOS MANDE ALGO
  uwait(100); // ESPERAR 100 milisegundos
}

// INICIALIZAR LA ESTRUCTURA PARA select()
if(params.t==-1) ptrtv=NULL; // LE PASAREMOS NULL A select
else
{
  BZERO(&tv);
  tv.tv_sec=params.t;
  ptrtv=&tv;
}

// INICIALIZAR VBLES DE CONTROL DEL BUCLE PRINCIPAL
FD_ZERO(&infd);
FD_ZERO(&tinfd);
FD_SET(first[0], &infd); // ANYADIR fd AL CONJUNTO DE DESCRIPTORES
FD_SET(second[0], &infd);

// DESCARTAR CANALES QUE NO NOS INTERESEN
// LEER SOLO DE SOCKET
if(params.r)
  if(params.S) FD_CLR(second[0], &infd); 
  else FD_CLR(first[0], &infd);
// SOLO ESCRIBIR EN SOCKET
if(params.w) 
  if(params.S) FD_CLR(first[0], &infd);  
  else FD_CLR(second[0], &infd);         


////////////////////////////////////////////////////////////////////////////////
////////////// BUCLE PRINCIPAL DE LECTURA/ESCRITURA ////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// SERVIDOR: SOCKET->STDOUT;
//           STDIN->SOCKET;
//
// CLIENTE:  STDIN->SOCKET;
//           SOCKET->STDOUT;
//
// USO MUY IMPORTANTE DE tinfd E infd PARA EL CONTROL DE FLUJO DE DATOS
////////////////////////////////////////////////////////////////////////////////
tinfd=infd;
while(FD_ISSET(first[0], &infd) || FD_ISSET(second[0], &infd))  // MIENTRAS HAY CONEXION EN ALGUN SENTIDO
{
  // PRIMERO UN SELECT DE TANTEO
  
  if(select(MAX(first[0], second[0])+1, &tinfd, NULL, NULL, ptrtv)==-1)
    perror_exit("Fatal error");
  
  // SI NO OCURRIO NADA DE INTERES, SALIR A LO BURRO
  if(!FD_ISSET(first[0], &tinfd) && !FD_ISSET(second[0], &tinfd))
  {
    IFV(printf_exit("\nTimeout!!!"));
    exit(0);
  }
//if(FD_ISSET(first[0], &tinfd)) printf("\nhay algo en first[0]=%d\n", first[0]);
//if(FD_ISSET(second[0], &tinfd)) printf("\nhay algo en second[0]=%d\n", second[0]);

  read_write(first, &tinfd, &infd);  // MODIFICAN infd PARA SABER CUANDO LLEGAMOS A EOF
  fflush(NULL);
  read_write(second, &tinfd, &infd); // SACANDO EL DESCRIPTOR CORRESPONDIENTE DE ENTRADA
  fflush(NULL);
  tinfd=infd;
  
}// DEL WHILE

IFV(printf("\nnk finished gracefully.\n"));
close(client);
return 0;
}