Exemple #1
0
int main(int argc, char * argv[])
{
	struct pollfd pfd[2];
	
	if(argc > 1 && !strcmp(argv[1], "-g"))
	{
		get_stats();
		exit(0);
	}
	
	/* register cleanup hooks */
	signal(SIGINT, signal_handler);
	signal(SIGTERM, signal_handler);
	
	pfd[0].fd = open_socket(NSCD_SOCKET);
	if(pfd[0].fd < 0)
		return 1;
	pfd[1].fd = open_socket(NSCD_SOCKET_OLD);
	if(pfd[1].fd < 0)
	{
		close(pfd[0].fd);
		return 1;
	}
	
	pfd[0].events = POLLIN;
	pfd[1].events = POLLIN;
	
	/* In debug mode, we don't daemonize. We also print debugging
	 * information about what is going on inside gnscd. */
	if(argc < 2 || strcmp(argv[1], "-d"))
	{
		/* become a daemon */
		daemon(0, 0);
		setsid();
		write_pid();
		
		/* ignore job control signals */
		signal(SIGTTOU, SIG_IGN);
		signal(SIGTTIN, SIG_IGN);
		signal(SIGTSTP, SIG_IGN);
	}
	else
		debug = 1;
	
	/* don't die if a client closes a socket on us */
	signal(SIGPIPE, SIG_IGN);
	
	/* make sure we don't get recursive calls */
	__nss_disable_nscd();
	
	if(cache_init() < 0)
		exit(1);
	
	/* listen for clients and dispatch them to threads */
	for(;;)
	{
		int i;
		
		if(poll(pfd, 2, -1) < 0)
			if(errno != EINTR)
				exit(1);
		
		for(i = 0; i < 2; i++)
		{
			int client;
			if(!pfd[i].revents)
				continue;
			client = accept(pfd[i].fd, NULL, NULL);
			if(client < 0)
				/* odd... poll() says we can accept but accept failed? */
				continue;
			if(dispatch_client(client) < 0)
				close(client);
		}
	}	
	
	return 0;
}
static FILE* prepare_ftp_session(FILE **dfpp, struct host_info *target, len_and_sockaddr *lsa)
{
	char buf[512];
	FILE *sfp;
	char *str;
	int port;

	if (!target->user)
		target->user = xstrdup("anonymous:busybox@");

	sfp = open_socket(lsa);
	if (ftpcmd(NULL, NULL, sfp, buf) != 220)
		bb_error_msg_and_die("%s", sanitize_string(buf+4));

	/*
	 * Splitting username:password pair,
	 * trying to log in
	 */
	str = strchr(target->user, ':');
	if (str)
		*str++ = '\0';
	switch (ftpcmd("USER ", target->user, sfp, buf)) {
	case 230:
		break;
	case 331:
		if (ftpcmd("PASS ", str, sfp, buf) == 230)
			break;
		/* fall through (failed login) */
	default:
		bb_error_msg_and_die("ftp login: %s", sanitize_string(buf+4));
	}

	ftpcmd("TYPE I", NULL, sfp, buf);

	/*
	 * Querying file size
	 */
	if (ftpcmd("SIZE ", target->path, sfp, buf) == 213) {
		G.content_len = BB_STRTOOFF(buf+4, NULL, 10);
		if (G.content_len < 0 || errno) {
			bb_error_msg_and_die("SIZE value is garbage");
		}
		G.got_clen = 1;
	}

	/*
	 * Entering passive mode
	 */
	if (ftpcmd("PASV", NULL, sfp, buf) != 227) {
 pasv_error:
		bb_error_msg_and_die("bad response to %s: %s", "PASV", sanitize_string(buf));
	}
	// Response is "227 garbageN1,N2,N3,N4,P1,P2[)garbage]
	// Server's IP is N1.N2.N3.N4 (we ignore it)
	// Server's port for data connection is P1*256+P2
	str = strrchr(buf, ')');
	if (str) str[0] = '\0';
	str = strrchr(buf, ',');
	if (!str) goto pasv_error;
	port = xatou_range(str+1, 0, 255);
	*str = '\0';
	str = strrchr(buf, ',');
	if (!str) goto pasv_error;
	port += xatou_range(str+1, 0, 255) * 256;
	set_nport(lsa, htons(port));

	*dfpp = open_socket(lsa);

	if (G.beg_range) {
		sprintf(buf, "REST %"OFF_FMT"u", G.beg_range);
		if (ftpcmd(buf, NULL, sfp, buf) == 350)
			G.content_len -= G.beg_range;
	}

	if (ftpcmd("RETR ", target->path, sfp, buf) > 150)
		bb_error_msg_and_die("bad response to %s: %s", "RETR", sanitize_string(buf));

	return sfp;
}
Exemple #3
0
/* TODO: IPv6 */
int sbbs_t::exec_net(csi_t* csi)
{
	char	str[512],rsp[512],buf[1025],ch,*p,**pp,**pp1,**pp2;
	ushort	w;
	uint 	i;
	BOOL	rd;
	int32_t	*lp,*lp1,*lp2;
	time_t	start;

	switch(*(csi->ip++)) {	/* sub-op-code stored as next byte */
		case CS_SOCKET_OPEN:
			lp=getintvar(csi,*(int32_t *)csi->ip);
			csi->ip+=4;
			csi->logic=LOGIC_FALSE;
			csi->socket_error=0;
			if(csi->sockets>=MAX_SOCKETS)
				return(0);
			if(lp!=NULL) {

				SOCKET sock=open_socket(SOCK_STREAM, NULL);
				if(sock!=INVALID_SOCKET) {

					SOCKADDR_IN	addr;

					memset(&addr,0,sizeof(addr));
					addr.sin_addr.s_addr = htonl(startup->outgoing4.s_addr);
					addr.sin_family = AF_INET;

					if((i=bind(sock, (struct sockaddr *) &addr, sizeof (addr)))!=0) {
						csi->socket_error=ERROR_VALUE;
						close_socket(sock);
						return(0);
					}

					*lp=sock;

					for(i=0;i<csi->sockets;i++)
						if(!csi->socket[i])
							break;
					csi->socket[i]=*lp;
					if(i==csi->sockets)
						csi->sockets++;
					csi->logic=LOGIC_TRUE; 
				} 
			}
			return(0);
		case CS_SOCKET_CLOSE:
			lp=getintvar(csi,*(int32_t *)csi->ip);
			csi->ip+=4;
			csi->logic=LOGIC_FALSE;
			csi->socket_error=0;
			if(lp && *lp) {
				csi->logic=close_socket((SOCKET)*lp);
				csi->socket_error=ERROR_VALUE;
				for(i=0;i<csi->sockets;i++)
					if(csi->socket[i]==(SOCKET)*lp)
						csi->socket[i]=0; 
				*lp=0;
			}
			return(0);
		case CS_SOCKET_CHECK:
			lp=getintvar(csi,*(int32_t *)csi->ip);
			csi->ip+=4;
			csi->logic=LOGIC_FALSE;
			csi->socket_error=0;

			if(lp==NULL || *lp==INVALID_SOCKET) 
				return(0);

			if(socket_check(*lp,NULL,NULL,0)==TRUE)
				csi->logic=LOGIC_TRUE;
			else
				csi->socket_error=ERROR_VALUE;
				
			return(0);
		case CS_SOCKET_CONNECT:
			lp=getintvar(csi,*(int32_t *)csi->ip);		/* socket */
			csi->ip+=4;

			pp=getstrvar(csi,*(int32_t *)csi->ip);		/* address */
			csi->ip+=4;

			w=*(ushort *)csi->ip;					/* port */
			csi->ip+=2;

			csi->logic=LOGIC_FALSE;
			csi->socket_error=0;

			if(!lp || !*lp || !pp || !*pp || !w)
				return(0);

			ulong ip_addr;

			if((ip_addr=resolve_ip(*pp))==INADDR_NONE)
				return(0);

			SOCKADDR_IN	addr;

			memset(&addr,0,sizeof(addr));
			addr.sin_addr.s_addr = ip_addr;
			addr.sin_family = AF_INET;
			addr.sin_port   = htons(w);

			if((i=connect(*lp, (struct sockaddr *)&addr, sizeof(addr)))!=0) {
				csi->socket_error=ERROR_VALUE;
				return(0);
			}
			csi->logic=LOGIC_TRUE;
			return(0);
		case CS_SOCKET_ACCEPT:
			lp1=getintvar(csi,*(int32_t *)csi->ip);		/* socket */
			csi->ip+=4;
			csi->socket_error=0;
			/* TODO */
			return(0);
		case CS_SOCKET_NREAD:
			lp1=getintvar(csi,*(int32_t *)csi->ip);		/* socket */
			csi->ip+=4;
			lp2=getintvar(csi,*(int32_t *)csi->ip);		/* var */
			csi->ip+=4;

			csi->logic=LOGIC_FALSE;
			csi->socket_error=0;

			if(!lp1 || !lp2)
				return(0);

			if(ioctlsocket(*lp1, FIONREAD, (ulong*)lp2)==0) 
				csi->logic=LOGIC_TRUE;
			else
				csi->socket_error=ERROR_VALUE;
			return(0);
		case CS_SOCKET_PEEK:
		case CS_SOCKET_READ:
			lp=getintvar(csi,*(int32_t *)csi->ip);			/* socket */
			csi->ip+=4;
			pp=getstrvar(csi,*(int32_t *)csi->ip);			/* buffer */
			csi->ip+=4;
			w=*(ushort *)csi->ip;						/* length */
			csi->ip+=2;					

			csi->logic=LOGIC_FALSE;
			csi->socket_error=0;

			if(!lp || !pp)
				return(0);

			if(w<1 || w>sizeof(buf)-1)
				w=sizeof(buf)-1;

			if((i=recv(*lp,buf,w
				,*(csi->ip-13)==CS_SOCKET_PEEK ? MSG_PEEK : 0))>0) {
				csi->logic=LOGIC_TRUE;
				buf[i]=0;
				if(csi->etx) {
					p=strchr(buf,csi->etx);
					if(p) *p=0; 
				}
				*pp=copystrvar(csi,*pp,buf); 
			} else
				csi->socket_error=ERROR_VALUE;
			return(0);
		case CS_SOCKET_READLINE:
			lp=getintvar(csi,*(int32_t *)csi->ip);			/* socket */
			csi->ip+=4;
			pp=getstrvar(csi,*(int32_t *)csi->ip);			/* buffer */
			csi->ip+=4;
			w=*(ushort *)csi->ip;						/* length */
			csi->ip+=2;					

			csi->logic=LOGIC_FALSE;
			csi->socket_error=0;

			if(!lp || !pp)
				return(0);

			if(w<1 || w>sizeof(buf)-1)
				w=sizeof(buf)-1;

			start=time(NULL);
			for(i=0;i<w;) {

				if(!online)
					return(1);

				if(!socket_check(*lp,&rd,NULL,1000))
					return(0);

				if(!rd) {
					if(time(NULL)-start>TIMEOUT_SOCK_READLINE) {
						lprintf(LOG_WARNING,"!socket_readline: timeout (%d) exceeded"
							,TIMEOUT_SOCK_READLINE);
						return(0);
					}
					continue;
				}

				if(recv(*lp, &ch, 1, 0)!=1) {
					csi->socket_error=ERROR_VALUE;
					return(0);
				}

				if(ch=='\n' && i>=1) 
					break;

				buf[i++]=ch;
			}
			if(i>0 && buf[i-1]=='\r')
				buf[i-1]=0;
			else
				buf[i]=0;

			if(csi->etx) {
				p=strchr(buf,csi->etx);
				if(p) *p=0; 
			}
			*pp=copystrvar(csi,*pp,buf); 
			csi->logic=LOGIC_TRUE;
			return(0);
		case CS_SOCKET_WRITE:	
			lp=getintvar(csi,*(int32_t *)csi->ip);			/* socket */
			csi->ip+=4;
			pp=getstrvar(csi,*(int32_t *)csi->ip);			/* buffer */
			csi->ip+=4;

			csi->logic=LOGIC_FALSE;
			csi->socket_error=0;

			if(!lp || !pp || !(*pp))
				return(0);

			if(sendsocket(*lp,*pp,strlen(*pp))>0)
				csi->logic=LOGIC_TRUE;
			else
				csi->socket_error=ERROR_VALUE;
			return(0);

		/* FTP Functions */
		case CS_FTP_LOGIN:
			lp=getintvar(csi,*(int32_t *)csi->ip);			/* socket */
			csi->ip+=4;
			pp1=getstrvar(csi,*(int32_t *)csi->ip);		/* username */
			csi->ip+=4;
			pp2=getstrvar(csi,*(int32_t *)csi->ip);		/* password */
			csi->ip+=4;

			csi->logic=LOGIC_FALSE;
			csi->socket_error=0;

			if(!lp || !pp1 || !pp2)
				return(0);

			if(!ftp_cmd(csi,*lp,NULL,rsp))
				return(0);

			if(atoi(rsp)!=220)
				return(0);

			sprintf(str,"USER %s",*pp1);

			if(!ftp_cmd(csi,*lp,str,rsp))
				return(0);
			
			if(atoi(rsp)==331) { /* Password needed */
				sprintf(str,"PASS %s",*pp2);
				if(!ftp_cmd(csi,*lp,str,rsp))
					return(0);
			}

			if(atoi(rsp)==230)	/* Login successful */
				csi->logic=LOGIC_TRUE;
			return(0);

		case CS_FTP_LOGOUT:
			lp=getintvar(csi,*(int32_t *)csi->ip);			/* socket */
			csi->ip+=4;
			csi->logic=LOGIC_FALSE;
			csi->socket_error=0;

			if(!lp)
				return(0);

			if(!ftp_cmd(csi,*lp,"QUIT",rsp))
				return(0);

			if(atoi(rsp)==221)	/* Logout successful */
				csi->logic=LOGIC_TRUE;
			return(0);

		case CS_FTP_PWD:
			lp=getintvar(csi,*(int32_t *)csi->ip);			/* socket */
			csi->ip+=4;
			csi->logic=LOGIC_FALSE;
			csi->socket_error=0;
			if(!lp)
				return(0);

			if(!ftp_cmd(csi,*lp,"PWD",rsp))
				return(0);

			if(atoi(rsp)==257)	/* pathname */
				csi->logic=LOGIC_TRUE;
			return(0);

		case CS_FTP_CWD:
			lp=getintvar(csi,*(int32_t *)csi->ip);			/* socket */
			csi->ip+=4;
			pp=getstrvar(csi,*(int32_t *)csi->ip);			/* path */
			csi->ip+=4;

			csi->logic=LOGIC_FALSE;
			csi->socket_error=0;
			if(!lp || !pp)
				return(0);
			
			sprintf(str,"CWD %s",*pp);
			if(!ftp_cmd(csi,*lp,str,rsp))
				return(0);

			if(atoi(rsp)==250)
				csi->logic=LOGIC_TRUE;

			return(0);

		case CS_FTP_DIR:
			lp=getintvar(csi,*(int32_t *)csi->ip);			/* socket */
			csi->ip+=4;
			pp=getstrvar(csi,*(int32_t *)csi->ip);			/* path */
			csi->ip+=4;

			csi->logic=LOGIC_FALSE;
			csi->socket_error=0;

			if(!lp || !pp)
				return(0);

			if(ftp_get(csi,*lp,*pp,NULL /* unused */, true /* DIR */)==true)
				csi->logic=LOGIC_TRUE;

			return(0);

		case CS_FTP_DELETE:
			lp=getintvar(csi,*(int32_t *)csi->ip);			/* socket */
			csi->ip+=4;
			pp=getstrvar(csi,*(int32_t *)csi->ip);			/* path */
			csi->ip+=4;

			csi->logic=LOGIC_FALSE;
			csi->socket_error=0;
			if(!lp || !pp)
				return(0);
			
			sprintf(str,"DELE %s",*pp);
			if(!ftp_cmd(csi,*lp,str,rsp))
				return(0);

			if(atoi(rsp)==250)
				csi->logic=LOGIC_TRUE;

			return(0);


		case CS_FTP_GET:
			lp=getintvar(csi,*(int32_t *)csi->ip);			/* socket */
			csi->ip+=4;
			pp1=getstrvar(csi,*(int32_t *)csi->ip);		/* src path */
			csi->ip+=4;
			pp2=getstrvar(csi,*(int32_t *)csi->ip);		/* dest path */
			csi->ip+=4;

			csi->logic=LOGIC_FALSE;
			csi->socket_error=0;

			if(!lp || !pp1 || !pp2)
				return(0);

			if(ftp_get(csi,*lp,*pp1,*pp2)==true)
				csi->logic=LOGIC_TRUE;
			
			return(0);

		case CS_FTP_PUT:
			lp=getintvar(csi,*(int32_t *)csi->ip);			/* socket */
			csi->ip+=4;
			pp1=getstrvar(csi,*(int32_t *)csi->ip);		/* src path */
			csi->ip+=4;
			pp2=getstrvar(csi,*(int32_t *)csi->ip);		/* dest path */
			csi->ip+=4;

			csi->logic=LOGIC_FALSE;
			csi->socket_error=0;

			if(!lp || !pp1 || !pp2)
				return(0);

			if(ftp_put(csi,*lp,*pp1,*pp2)==true)
				csi->logic=LOGIC_TRUE;
			
			return(0);


		default:
			errormsg(WHERE,ERR_CHK,"net sub-instruction",*(csi->ip-1));
			return(0); 
	}
}
Exemple #4
0
//  Returns -1 if we could not make the socket pair successfully
int zmq::signaler_t::make_fdpair (fd_t *r_, fd_t *w_)
{
#if defined ZMQ_HAVE_EVENTFD
    fd_t fd = eventfd (0, 0);
    if (fd == -1) {
        errno_assert (errno == ENFILE || errno == EMFILE);
        *w_ = *r_ = -1;
        return -1;
    }
    else {
        *w_ = *r_ = fd;
        return 0;
    }

#elif defined ZMQ_HAVE_WINDOWS
#   if !defined _WIN32_WCE
    // Windows CE does not manage security attributes
    SECURITY_DESCRIPTOR sd;
    SECURITY_ATTRIBUTES sa;
    memset (&sd, 0, sizeof sd);
    memset (&sa, 0, sizeof sa);

    InitializeSecurityDescriptor (&sd, SECURITY_DESCRIPTOR_REVISION);
    SetSecurityDescriptorDacl (&sd, TRUE, 0, FALSE);

    sa.nLength = sizeof (SECURITY_ATTRIBUTES);
    sa.lpSecurityDescriptor = &sd;
#   endif

    //  This function has to be in a system-wide critical section so that
    //  two instances of the library don't accidentally create signaler
    //  crossing the process boundary.
    //  We'll use named event object to implement the critical section.
    //  Note that if the event object already exists, the CreateEvent requests
    //  EVENT_ALL_ACCESS access right. If this fails, we try to open
    //  the event object asking for SYNCHRONIZE access only.
    HANDLE sync = NULL;

    //  Create critical section only if using fixed signaler port
    //  Use problematic Event implementation for compatibility if using old port 5905.
    //  Otherwise use Mutex implementation.
    int event_signaler_port = 5905;

    if (signaler_port == event_signaler_port) {
#       if !defined _WIN32_WCE
        sync = CreateEventW (&sa, FALSE, TRUE, L"Global\\zmq-signaler-port-sync");
#       else
        sync = CreateEventW (NULL, FALSE, TRUE, L"Global\\zmq-signaler-port-sync");
#       endif
        if (sync == NULL && GetLastError () == ERROR_ACCESS_DENIED)
            sync = OpenEventW (SYNCHRONIZE | EVENT_MODIFY_STATE,
                              FALSE, L"Global\\zmq-signaler-port-sync");

        win_assert (sync != NULL);
    }
    else
    if (signaler_port != 0) {
        wchar_t mutex_name [MAX_PATH];
#       ifdef __MINGW32__
        _snwprintf (mutex_name, MAX_PATH, L"Global\\zmq-signaler-port-%d", signaler_port);
#       else
        swprintf (mutex_name, MAX_PATH, L"Global\\zmq-signaler-port-%d", signaler_port);
#       endif

#       if !defined _WIN32_WCE
        sync = CreateMutexW (&sa, FALSE, mutex_name);
#       else
        sync = CreateMutexW (NULL, FALSE, mutex_name);
#       endif
        if (sync == NULL && GetLastError () == ERROR_ACCESS_DENIED)
            sync = OpenMutexW (SYNCHRONIZE, FALSE, mutex_name);

        win_assert (sync != NULL);
    }

    //  Windows has no 'socketpair' function. CreatePipe is no good as pipe
    //  handles cannot be polled on. Here we create the socketpair by hand.
    *w_ = INVALID_SOCKET;
    *r_ = INVALID_SOCKET;

    //  Create listening socket.
    SOCKET listener;
    listener = open_socket (AF_INET, SOCK_STREAM, 0);
    wsa_assert (listener != INVALID_SOCKET);

    //  Set SO_REUSEADDR and TCP_NODELAY on listening socket.
    BOOL so_reuseaddr = 1;
    int rc = setsockopt (listener, SOL_SOCKET, SO_REUSEADDR,
        (char *) &so_reuseaddr, sizeof so_reuseaddr);
    wsa_assert (rc != SOCKET_ERROR);
    BOOL tcp_nodelay = 1;
    rc = setsockopt (listener, IPPROTO_TCP, TCP_NODELAY,
        (char *) &tcp_nodelay, sizeof tcp_nodelay);
    wsa_assert (rc != SOCKET_ERROR);

    //  Init sockaddr to signaler port.
    struct sockaddr_in addr;
    memset (&addr, 0, sizeof addr);
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
    addr.sin_port = htons (signaler_port);

    //  Create the writer socket.
    *w_ = open_socket (AF_INET, SOCK_STREAM, 0);
    wsa_assert (*w_ != INVALID_SOCKET);

    //  Set TCP_NODELAY on writer socket.
    rc = setsockopt (*w_, IPPROTO_TCP, TCP_NODELAY,
        (char *) &tcp_nodelay, sizeof tcp_nodelay);
    wsa_assert (rc != SOCKET_ERROR);

    if (sync != NULL) {
        //  Enter the critical section.
        DWORD dwrc = WaitForSingleObject (sync, INFINITE);
        zmq_assert (dwrc == WAIT_OBJECT_0 || dwrc == WAIT_ABANDONED);
    }

    //  Bind listening socket to signaler port.
    rc = bind (listener, (const struct sockaddr *) &addr, sizeof addr);

    if (rc != SOCKET_ERROR && signaler_port == 0) {
        //  Retrieve ephemeral port number
        int addrlen = sizeof addr;
        rc = getsockname (listener, (struct sockaddr *) &addr, &addrlen);
    }

    //  Listen for incoming connections.
    if (rc != SOCKET_ERROR)
        rc = listen (listener, 1);

    //  Connect writer to the listener.
    if (rc != SOCKET_ERROR)
        rc = connect (*w_, (struct sockaddr *) &addr, sizeof addr);

    //  Accept connection from writer.
    if (rc != SOCKET_ERROR)
        *r_ = accept (listener, NULL, NULL);

    //  Send/receive large chunk to work around TCP slow start
    //  This code is a workaround for #1608
    if (*r_ != INVALID_SOCKET) {
        size_t dummy_size = 1024 * 1024;        //  1M to overload default receive buffer
        unsigned char *dummy = (unsigned char *) malloc (dummy_size);
        int still_to_send = (int) dummy_size;
        int still_to_recv = (int) dummy_size;
        while (still_to_send || still_to_recv) {
            int nbytes;
            if (still_to_send > 0) {
                nbytes = ::send (*w_, (char *) (dummy + dummy_size - still_to_send), still_to_send, 0);
                wsa_assert (nbytes != SOCKET_ERROR);
                still_to_send -= nbytes;
            }
            nbytes = ::recv (*r_, (char *) (dummy + dummy_size - still_to_recv), still_to_recv, 0);
            wsa_assert (nbytes != SOCKET_ERROR);
            still_to_recv -= nbytes;
        }
        free (dummy);
    }

    //  Save errno if error occurred in bind/listen/connect/accept.
    int saved_errno = 0;
    if (*r_ == INVALID_SOCKET)
        saved_errno = WSAGetLastError ();

    //  We don't need the listening socket anymore. Close it.
    closesocket (listener);

    if (sync != NULL) {
        //  Exit the critical section.
        BOOL brc;
        if (signaler_port == event_signaler_port)
            brc = SetEvent (sync);
        else
            brc = ReleaseMutex (sync);
        win_assert (brc != 0);

        //  Release the kernel object
        brc = CloseHandle (sync);
        win_assert (brc != 0);
    }

    if (*r_ != INVALID_SOCKET) {
#   if !defined _WIN32_WCE
        //  On Windows, preventing sockets to be inherited by child processes.
        BOOL brc = SetHandleInformation ((HANDLE) *r_, HANDLE_FLAG_INHERIT, 0);
        win_assert (brc);
#   endif
        return 0;
    }
    else {
        //  Cleanup writer if connection failed
        if (*w_ != INVALID_SOCKET) {
            rc = closesocket (*w_);
            wsa_assert (rc != SOCKET_ERROR);
            *w_ = INVALID_SOCKET;
        }
        //  Set errno from saved value
        errno = wsa_error_to_errno (saved_errno);
        return -1;
    }

#elif defined ZMQ_HAVE_OPENVMS

    //  Whilst OpenVMS supports socketpair - it maps to AF_INET only.  Further,
    //  it does not set the socket options TCP_NODELAY and TCP_NODELACK which
    //  can lead to performance problems.
    //
    //  The bug will be fixed in V5.6 ECO4 and beyond.  In the meantime, we'll
    //  create the socket pair manually.
    struct sockaddr_in lcladdr;
    memset (&lcladdr, 0, sizeof lcladdr);
    lcladdr.sin_family = AF_INET;
    lcladdr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
    lcladdr.sin_port = 0;

    int listener = open_socket (AF_INET, SOCK_STREAM, 0);
    errno_assert (listener != -1);

    int on = 1;
    int rc = setsockopt (listener, IPPROTO_TCP, TCP_NODELAY, &on, sizeof on);
    errno_assert (rc != -1);

    rc = setsockopt (listener, IPPROTO_TCP, TCP_NODELACK, &on, sizeof on);
    errno_assert (rc != -1);

    rc = bind (listener, (struct sockaddr *) &lcladdr, sizeof lcladdr);
    errno_assert (rc != -1);

    socklen_t lcladdr_len = sizeof lcladdr;

    rc = getsockname (listener, (struct sockaddr *) &lcladdr, &lcladdr_len);
    errno_assert (rc != -1);

    rc = listen (listener, 1);
    errno_assert (rc != -1);

    *w_ = open_socket (AF_INET, SOCK_STREAM, 0);
    errno_assert (*w_ != -1);

    rc = setsockopt (*w_, IPPROTO_TCP, TCP_NODELAY, &on, sizeof on);
    errno_assert (rc != -1);

    rc = setsockopt (*w_, IPPROTO_TCP, TCP_NODELACK, &on, sizeof on);
    errno_assert (rc != -1);

    rc = connect (*w_, (struct sockaddr *) &lcladdr, sizeof lcladdr);
    errno_assert (rc != -1);

    *r_ = accept (listener, NULL, NULL);
    errno_assert (*r_ != -1);

    close (listener);

    return 0;

#else
    // All other implementations support socketpair()
    int sv [2];
    int rc = socketpair (AF_UNIX, SOCK_STREAM, 0, sv);
    if (rc == -1) {
        errno_assert (errno == ENFILE || errno == EMFILE);
        *w_ = *r_ = -1;
        return -1;
    }
    else {
        *w_ = sv [0];
        *r_ = sv [1];
        return 0;
    }
#endif
}
Exemple #5
0
 int daemon_mode(char *hostname, char* port) 
 {
	char buf[MAXDATASIZE];					// For sending and receiving socket messages
	char *ptr1, *ptr2;
	int i;
 	int rc;
	fd_set fds;								// Socket Filedescriptor set
	
	char *jgaddr;	// Group address
	char *juaddr;
	char *jbrand;
	char *jval;
	char *ok;
	
	char *gname;	// Name
	int gtype;
	
	// ---------------- FOR DAEMON USE, OPEN SOCKETS ---------------------------------
	// If we choose daemon mode, we will need to open a socket for communication
	// This needs to be done BEFORE enabling the interrupt handler, as we want
	// the handler to send its code to the LamPI-daemon process 
	
	// Open a socket
	if ((sockfd = open_socket(hostname,port)) < 0) {
		fprintf(stderr,"Error opening socket for host %s. Exiting program\n\n", hostname);
		exit (1);
	};
	FD_ZERO(&fds);
	FD_SET(sockfd, &fds);
	
	// The command below is sort of initialization command to put the sender in 
	// a known state. Without it, there might be a proble when more than one Raspberry is
	// used for transmitting on the network. Unitialized it will apparently send noise ...
	// XXX Maybe just pulling the transmitter pin to 0 will work as well :-)
	
	send_2_device("kaku", "99", "1", "on");
	
	for (;;)
	{
		// If we run a daemon, the interrupt handler outputs to the LamPI-daemon directly
		// so this program ONLY needs to sleep in that case to save cpu cycles
		//
		if (verbose == 1) {
			printf("daemon_mode: transaction: %d, sleep: %d, sockerr: %d, stop_ints: %d\n",
								socktcnt, SLEEP, sockerr, stop_ints);
			fflush (stdout);
		}
			
		// Is the socket still alive? XXX we should not always do this once we are here,
		// but only once in every 60 seconds or so ....
		
		if (verbose == 1) printf("PING\n");
		sprintf(buf,"%d,PING",++socktcnt);					// Keep_Alive and check for connection
			
		if (write(sockfd, buf, strlen(buf)) == -1) {
			perror("Error writing to socket\n");
			close(sockfd);
			sleep(1);										// Allow socket to close down
			//
			// If reconnecting failed due to LamPI-daemon not running, we have to wait until
			// the daemon is restarted by cron after 60 secs and restart again.
			// The easiest way is to quit the program and let it be restarted by cron too
			// XXX better way is loop and try a few times
			i=0;
			while ( ((sockfd = open_socket(hostname,port)) < 0) && (i++ < 15) ) {
				fprintf(stderr,"Error opening socket connection to daemon %s, retry: %d",hostname,i);
				sleep(5);
			}	
			if (sockfd < 0) {
				fprintf(stderr,"Giving up: Error opening socket for host %s\n", hostname);
				exit(1);
			};
			if (verbose==1) printf("daemon_mode:: reopened the socket\n");
			// New socket created, hopefully we're fine now
		}
		
		// Now we have a connection still or again ...
		FD_ZERO(&fds);
		FD_SET(sockfd, &fds);
		timeout.tv_usec= 0;
		timeout.tv_sec = SLEEP;
			
		// Check for incoming socket messages. As longs as there is a message, read it, process it
		// If there are no fds ready, function returns 0, and we restart the loop
		
		while ((rc = select(sockfd+1, &fds, NULL, NULL, &timeout)) > 0)
		{
		  // Look at the filedescriptor, and see if this socket is selected
		  if (FD_ISSET(sockfd, &fds)) 
		  {
			if (verbose==1) printf("daemon_mode:: Message ready waiting on socket\n");
				
			rc = read(sockfd, buf, MAXDATASIZE); 
			if (rc == 0) {
				// Read error, break and establish new connection if necessary
				// If we break, we will automatically do a PING to check
				if (verbose == 1) printf("daemon_mode:: read error, connection lost?\n");
				close(sockfd);
				break;
			}
			buf[rc]=0;									// Terminate a string
			printf("Buf read:: <%s>\n",buf);
			
			ptr1 = buf;	
			cJSON *root;
			
			for (;;)
			{
				root = cJSON_ParseWithOpts((const char*) ptr1,(const char **)&ptr2,0);		// ptr contains end pos of parsed buf
				if (root == 0) {
					fprintf(stderr,"daemon_mode:: cJSON_ParseWithOps returned error\n");
					
					// If the parsing failed, it COULD be that we did miss part of the message
					// we can read another message and concatenate it to the end of this message
					// However, more likely that we receive a non-JSON message. So discard the message for the moment
				
					cJSON_Delete(root);
					break;
				}
				ok = parse_cjson(root, "action");		// My ad-on parsing function 
				if  ((ok != NULL) && (strcmp(ok,"ack") == 0))
								{ goto next; }		// Ignore OK messages for the receiver
				
				jbrand = parse_cjson(root, "brand");		// My ad-on parsing function 
				if (jbrand == NULL) { printf("parse_cjson jbrand returned NULL \n"); goto next; }
				
				jgaddr = parse_cjson(root, "gaddr");
				if (jgaddr == NULL) { printf("parse_cjson gaddr returned NULL \n"); goto next; }
				
				juaddr = parse_cjson(root, "uaddr");
				if (juaddr == NULL) { printf("parse_cjson uaddr returned NULL \n"); goto next; }
				
				jval = parse_cjson(root, "val");
				if (jval == NULL) {	printf("parse_cjson val returned NULL \n"); goto next; }
				
				printf("Json:: gaddr: %s, uaddr: %s, val: %s\n",jgaddr, juaddr, jval);
		
				// Now transmit the command to a device using function transmit
				//
				if (dtransmit(jbrand, jgaddr, juaddr, jval) == -1)
				{
					printf("transmit: returned error \n");
					continue;
				}
next:
				cJSON_Delete(root);
				
				// We know now that we parsed a JSON message. If there are more JSON messages
				// in the buffer, we will have to parse them as well. So move the ppointers in buf
				// and loop again.
			
				if ((ptr2 - buf) < rc) {
					// printf("daemon_mode:: Unparsed data in buf: %d chars, first char: %c\n",(buf+rc-ptr2), *ptr2);
					ptr1 = ptr2;
					ptr2 = NULL;
				}
				else {
					break;
				}
				
			}//for	
		  }// FD_ISSET

		}// while
		
		if (rc == -1) perror("select failed with value -1");	
		if (rc == 0) {
			// perror("select failed with value 0");				// XXX Remove, val 0 means no data
		}
		
		stop_ints=0;
		continue;										// Next loop
	}// for
 
	return(1);
 }
Exemple #6
0
/* Based on ieee80211_listnodes() from ifconfig. */
struct config_ssid *
all_matching_network(struct config_interfaces * config) {
        struct ieee80211_nodereq_all na;
        struct ieee80211_nodereq nr[512];
        struct ifreq 	ifr;
        char 		name     [IEEE80211_NWID_LEN];
        int 		i        , s, len, res;
        int8_t 		rssi;
        struct config_ssid *ret = 0;

        /* Open socket and scan for wlans. */
        memset(&ifr, 0, sizeof(ifr));
        strlcpy(ifr.ifr_name, config->if_name, sizeof(ifr.ifr_name));
        s = open_socket(AF_INET);
        if (s < 0)
            return NULL;
        if (ioctl(s, SIOCS80211SCAN, (caddr_t) & ifr) != 0) {
            /* Interface not available; invoking ifconfig to bring it up. */
            printf("error scanning: %s\n", strerror(errno));
            close(s);
            char 		command  [50];
            snprintf(command, sizeof(command), "ifconfig %s up\n", config->if_name);
            printf("%s\n", command);
            system(command);
            printf("try bringing up interface\n");
            return NULL;
        }
        memset(&na, 0, sizeof(na));
        memset(&nr, 0, sizeof(nr));
        na.na_node = nr;
        na.na_size = sizeof(nr);
        strlcpy(na.na_ifname, config->if_name, sizeof(na.na_ifname));
        res = ioctl(s, SIOCG80211ALLNODES, &na);
        close(s);
        if (res) {
            printf("error retrieving nodes: %s\n", strerror(errno));
            return NULL;
        }
        if (!na.na_nodes) {
            printf("no access points found\n");
            return NULL;
        }
        /* Sort nodes in order of signal strength. */
        qsort(nr, na.na_nodes, sizeof(*nr), rssicmp);
        struct config_ssid *cur = config->ssids;
        while (cur) {
            for (i = 0; i < na.na_nodes; i++) {
                len = nr[i].nr_nwid_len > IEEE80211_NWID_LEN ? IEEE80211_NWID_LEN : nr[i].nr_nwid_len;
                snprintf(name, IEEE80211_NWID_LEN, "%.*s", len, nr[i].nr_nwid);
                rssi = nr[i].nr_rssi;
                printf("checking this one: %s and this one: %s, has rssi of %d\n", cur->ssid_name, name, rssi);
                if (strcmp(cur->ssid_name, name) == 0) {
                    printf("this one found\n");
                    /*
                     * get data we need from scan; BSSID, signal
                     * strength, auth mode.
                     */
                    struct ether_addr ea;
                    memcpy(&ea.ether_addr_octet, nr[i].nr_bssid, sizeof(ea.ether_addr_octet));
                    /* convert BSSID from binary to ASCII. */
                    strlcpy(cur->ssid_bssid, ether_ntoa(&ea), sizeof(cur->ssid_bssid));
                    /* Get signal strength. */
                    if (nr[i].nr_max_rssi)
                        cur->ssid_rssi = IEEE80211_NODEREQ_RSSI(&nr[i]);
                    else
                        cur->ssid_rssi = nr[i].nr_rssi;
                    printf("signal strength is: %d\n", cur->ssid_rssi);
                    if (nr[i].nr_capinfo) {
                        if ((nr[i].nr_rsnakms & IEEE80211_WPA_AKM_8021X) || (nr[i].nr_rsnakms & IEEE80211_WPA_AKM_SHA256_8021X))
                            strlcpy(cur->ssid_auth, "802.1x", sizeof(cur->ssid_auth));
                            
                        /*
                         * CCMP is WPA2 and TKIP is WPA1. The
                         * code to connect to either auth is
                         * exactly the same, they just uses
                         * different cipher. For the purposes
                         * of this program, I am
                         * consolidating them.
                         */    
                        else if ((nr[i].nr_rsnciphers & IEEE80211_WPA_CIPHER_CCMP) || (nr[i].nr_rsnciphers & IEEE80211_WPA_CIPHER_TKIP))
                            strlcpy(cur->ssid_auth, "wpa", sizeof(cur->ssid_auth));
                        /*
                         * Check if a password has been set
                         * for this access point. If there
                         * is, we use WEP.
                         */
                        else {
                            if (cur->ssid_pass[0] == '\0')
                                strlcpy(cur->ssid_auth, "none", sizeof(cur->ssid_auth));
                            else
                                strlcpy(cur->ssid_auth, "wep", sizeof(cur->ssid_auth));
						/*
						 * Unable to check for a WEP
						 * cipher with a nodereq.
						 */
                        }
                    } else
                        strlcpy(cur->ssid_auth, "none", sizeof(cur->ssid_auth));
                        /* No auth on access point. */
                    printf("%s mode found\n", cur->ssid_auth);
                    struct config_ssid *cpy = malloc(sizeof(struct config_ssid));
                    memcpy(cpy, cur, sizeof(struct config_ssid));
                    cpy->next = 0;
                    if (ret)
                        ret->next = cpy;
                    else {
                        ret = cpy;
                        ret->next = 0;
                    }
                }
            }
        cur = cur->next;
        }
        return ret;
}
Exemple #7
0
static int
propagate_database (krb5_context context, int type,
		    const char *database_name,
		    HDB *db, krb5_ccache ccache,
		    int optidx, int argc, char **argv)
{
    krb5_principal server;
    krb5_error_code ret;
    int i, failed = 0;

    for(i = optidx; i < argc; i++){
	krb5_auth_context auth_context;
	int fd;
	struct prop_data pd;
	krb5_data data;

	char *port, portstr[NI_MAXSERV];
	char *host = argv[i];

	port = strchr(host, ':');
	if(port == NULL) {
	    snprintf(portstr, sizeof(portstr), "%u",
		     ntohs(krb5_getportbyname (context, "hprop", "tcp",
					       HPROP_PORT)));
	    port = portstr;
	} else
	    *port++ = '\0';

	fd = open_socket(context, host, port);
	if(fd < 0) {
	    failed++;
	    krb5_warn (context, errno, "connect %s", host);
	    continue;
	}

	ret = krb5_sname_to_principal(context, argv[i],
				      HPROP_NAME, KRB5_NT_SRV_HST, &server);
	if(ret) {
	    failed++;
	    krb5_warn(context, ret, "krb5_sname_to_principal(%s)", host);
	    close(fd);
	    continue;
	}

        if (local_realm) {
            krb5_realm my_realm;
            krb5_get_default_realm(context,&my_realm);
            krb5_principal_set_realm(context,server,my_realm);
	    krb5_xfree(my_realm);
        }

	auth_context = NULL;
	ret = krb5_sendauth(context,
			    &auth_context,
			    &fd,
			    HPROP_VERSION,
			    NULL,
			    server,
			    AP_OPTS_MUTUAL_REQUIRED | AP_OPTS_USE_SUBKEY,
			    NULL, /* in_data */
			    NULL, /* in_creds */
			    ccache,
			    NULL,
			    NULL,
			    NULL);

	krb5_free_principal(context, server);

	if(ret) {
	    failed++;
	    krb5_warn(context, ret, "krb5_sendauth (%s)", host);
	    close(fd);
	    goto next_host;
	}

	pd.context      = context;
	pd.auth_context = auth_context;
	pd.sock         = fd;

	ret = iterate (context, database_name, db, type, &pd);
	if (ret) {
	    krb5_warnx(context, "iterate to host %s failed", host);
	    failed++;
	    goto next_host;
	}

	krb5_data_zero (&data);
	ret = krb5_write_priv_message(context, auth_context, &fd, &data);
	if(ret) {
	    krb5_warn(context, ret, "krb5_write_priv_message");
	    failed++;
	    goto next_host;
	}

	ret = krb5_read_priv_message(context, auth_context, &fd, &data);
	if(ret) {
	    krb5_warn(context, ret, "krb5_read_priv_message: %s", host);
	    failed++;
	    goto next_host;
	} else
	    krb5_data_free (&data);

    next_host:
	krb5_auth_con_free(context, auth_context);
	close(fd);
    }
    if (failed)
	return 1;
    return 0;
}
Exemple #8
0
int zmq::tcp_connecter_t::open ()
{
    zmq_assert (s == retired_fd);
    struct sockaddr *sa = (struct sockaddr*) &addr;

    if (AF_UNIX != sa->sa_family) {

        //  Create the socket.
        s = open_socket (sa->sa_family, SOCK_STREAM, IPPROTO_TCP);
        if (s == -1)
            return -1;

        // Set to non-blocking mode.
#ifdef ZMQ_HAVE_OPENVMS
    	int flags = 1;
    	int rc = ioctl (s, FIONBIO, &flags);
        errno_assert (rc != -1);
#else
    	int flags = fcntl (s, F_GETFL, 0);
    	if (flags == -1)
            flags = 0;
    	int rc = fcntl (s, F_SETFL, flags | O_NONBLOCK);
        errno_assert (rc != -1);
#endif

        //  Disable Nagle's algorithm.
        int flag = 1;
        rc = setsockopt (s, IPPROTO_TCP, TCP_NODELAY, (char*) &flag,
            sizeof (int));
        errno_assert (rc == 0);

#ifdef ZMQ_HAVE_OPENVMS
        //  Disable delayed acknowledgements.
        flag = 1;
        rc = setsockopt (s, IPPROTO_TCP, TCP_NODELACK, (char*) &flag,
            sizeof (int));
        errno_assert (rc != SOCKET_ERROR);
#endif

        //  Connect to the remote peer.
        rc = ::connect (s, (struct sockaddr*) &addr, addr_len);

        //  Connect was successfull immediately.
        if (rc == 0)
            return 0;

        //  Connection still in progress.
        if (errno == EINPROGRESS)
            return -1;

        //  Error occured.
        int err = errno;
        close ();
        errno = err;
        return -1;
    }

#ifndef ZMQ_HAVE_OPENVMS
    else {

        //  Create the socket.
        zmq_assert (AF_UNIX == sa->sa_family);
        s = open_socket (AF_UNIX, SOCK_STREAM, 0);
        if (s == -1)
            return -1;

        //  Set the non-blocking flag.
        int flag = fcntl (s, F_GETFL, 0);
        if (flag == -1)
            flag = 0;
        int rc = fcntl (s, F_SETFL, flag | O_NONBLOCK);
        errno_assert (rc != -1);

        //  Connect to the remote peer.
        rc = ::connect (s, (struct sockaddr*) &addr, sizeof (sockaddr_un));

        //  Connect was successfull immediately.
        if (rc == 0)
            return 0;

        //  Connection still in progress.
        if (errno == EINPROGRESS)
            return -1;

        //  Error occured.
        int err = errno;
        close ();
        errno = err;
        return -1;
    }
#endif

    zmq_assert (false);
    return -1;
}
Exemple #9
0
int zmq::ipc_listener_t::set_address (const char *addr_)
{
    //  Create addr on stack for auto-cleanup
    std::string addr (addr_);

    //  Allow wildcard file
    if (options.use_fd == -1 && addr [0] == '*') {
        if ( create_wildcard_address(tmp_socket_dirname, addr) < 0 ) {
            return -1;
        }
    }

    //  Get rid of the file associated with the UNIX domain socket that
    //  may have been left behind by the previous run of the application.
    //  MUST NOT unlink if the FD is managed by the user, or it will stop
    //  working after the first client connects. The user will take care of
    //  cleaning up the file after the service is stopped.
    if (options.use_fd == -1) {
        ::unlink (addr.c_str());
    }
    filename.clear ();

    //  Initialise the address structure.
    ipc_address_t address;
    int rc = address.resolve (addr.c_str());
    if (rc != 0) {
        if ( !tmp_socket_dirname.empty() ) {
            // We need to preserve errno to return to the user
            int errno_ = errno;
            ::rmdir(tmp_socket_dirname.c_str ());
            tmp_socket_dirname.clear();
            errno = errno_;
        }
        return -1;
    }

    address.to_string (endpoint);

    if (options.use_fd != -1) {
        s = options.use_fd;
    } else {
        //  Create a listening socket.
        s = open_socket (AF_UNIX, SOCK_STREAM, 0);
        if (s == -1) {
            if ( !tmp_socket_dirname.empty() ) {
                // We need to preserve errno to return to the user
                int errno_ = errno;
                ::rmdir(tmp_socket_dirname.c_str ());
                tmp_socket_dirname.clear();
                errno = errno_;
            }
            return -1;
        }

        //  Bind the socket to the file path.
        rc = bind (s, address.addr (), address.addrlen ());
        if (rc != 0)
            goto error;

        //  Listen for incoming connections.
        rc = listen (s, options.backlog);
        if (rc != 0)
            goto error;
    }

    filename.assign (addr.c_str());
    has_file = true;

    socket->event_listening (endpoint, s);
    return 0;

error:
    int err = errno;
    close ();
    errno = err;
    return -1;
}
Exemple #10
0
int event_loop(char * device_file, int port, int log_fd) {
	int tty_fd, is_dev_opened;
	char data[BUFFER], device_data[BUFFER];
	int count, data_count;
	int i, j;

	int listen_fd;
	int log_listen_fd;
	int log_sock_fd = -1;
	int sock_fd[BUFFER];
	int sock_fd_count = 0;

	struct sockaddr_in	sa = { 0 };
	socklen_t		sl = sizeof(sa);

	int finished;

	time_t open_time;

	char * reqs, * logtmp;

	fd_set rfds;
	struct timeval tv;
	int retval;

	start_time = time(NULL);

	listen_fd = open_socket(port);
	listen(listen_fd, 25);

	log_listen_fd = open_socket(LOG_PORT);
	listen(log_listen_fd, 2);

	reqs = (char *)malloc(sizeof(char) * BUFFER * (SMALL + 1));
	logtmp = (char *)malloc(sizeof(char) * BUFFER);

	for (i = 0; i < ITEMS_COUNT; ++i) {
		memset(global_data[i].key, 0, SMALL);
		memset(global_data[i].value, 0, SMALL);
	}

	is_dev_opened = 0;

	snprintf(logtmp, BUFFER, "Process started");
	write_log(log_fd, log_sock_fd, logtmp);

	while (1) {

		if (!is_dev_opened) {
			tty_fd = open_device(device_file);
			++is_dev_opened;
			open_time = time(NULL);

			if (tty_fd > 0) {
				last_update = time(NULL);
				usleep(MICROSLEEP);
			}
			if (-ENXIO == tty_fd) {
				snprintf(logtmp, BUFFER, "Device file %s doesn't exist", device_file);
				write_log(log_fd, log_sock_fd, logtmp);
				is_dev_opened = 0;
				usleep(MICROSLEEP);
			}
			if (!tty_fd) {
				snprintf(logtmp, BUFFER, "Device file %s can't be opened", device_file);
				write_log(log_fd, log_sock_fd, logtmp);
				is_dev_opened = 0;
				usleep(MICROSLEEP);
			}
		} else {
			open_time = time(NULL);
		}

		tv.tv_sec = 0;
		tv.tv_usec = MICROSLEEP;

		FD_ZERO(&rfds);
		FD_SET(listen_fd, &rfds);
		FD_SET(log_listen_fd, &rfds);

		if (is_dev_opened)
			FD_SET(tty_fd, &rfds);

		if (log_sock_fd > 0)
			FD_SET(log_sock_fd, &rfds);

		for (i = 0; i < sock_fd_count; ++i)
			FD_SET(sock_fd[i], &rfds);

		retval = select(
				get_max(tty_fd,
					listen_fd,
					log_listen_fd,
					log_sock_fd,
					sock_fd,
					sock_fd_count) + 1,
				&rfds,
				NULL,
				NULL,
				&tv);
		if (retval) {

			if (is_dev_opened && FD_ISSET(tty_fd, &rfds)) {
				char temp1[BUFFER];
				count = read(tty_fd, temp1, BUFFER);

				if (count + data_count > BUFFER) {
					goto device_reading_cleanup;
				}

				finished = 0;
				for (i = 0; i < count; ++i) {
					if (';' == temp1[i]) {
						++finished;
						break;
					}
				}

				memcpy(device_data + data_count, temp1, count * sizeof(char));
				data_count += count;

				if ((time(NULL) - open_time) > OUTDATE_TIMEOUT) { // Device vanished during reading, 10 sec timeout
					snprintf(logtmp, BUFFER, "Device  %s vanished during reading, closing", device_file);
					write_log(log_fd, log_sock_fd, logtmp);

					goto device_reading_cleanup;
				}

				if (finished) {
					device_data[data_count] = '\0';

					if (-1 == process_recv(log_fd, log_sock_fd, device_data)) {
						last_update = 0;
					}

					goto device_reading_cleanup;
				}

				goto device_reading_exit;

device_reading_cleanup:
				data_count = 0;
				continue;
device_reading_exit:
				;;
			}

			if (FD_ISSET(listen_fd, &rfds)) {
				sock_fd[sock_fd_count] = accept(listen_fd, (struct sockaddr *)&sa, &sl);
				getpeername(sock_fd[sock_fd_count], (struct sockaddr *)&sa, &sl);
				memset(reqs + sock_fd_count * (SMALL + 1), 0, sizeof(char) * (SMALL + 1));
				++sock_fd_count;

				snprintf(logtmp, BUFFER,
						"Accepted data connection from %s, has %d conns",
						inet_ntoa(sa.sin_addr), sock_fd_count);
				write_log(log_fd, log_sock_fd, logtmp);
				continue;
			}
			if (FD_ISSET(log_listen_fd, &rfds)) {
				if (log_sock_fd > 0) { // Closing previous connection
					close(log_sock_fd);
				}

				log_sock_fd = accept(log_listen_fd, (struct sockaddr *)&sa, &sl);
				getpeername(log_sock_fd, (struct sockaddr *)&sa, &sl);
				snprintf(logtmp, BUFFER, "Accepted log connection from %s", inet_ntoa(sa.sin_addr));
				write_log(log_fd, log_sock_fd, logtmp);
				continue;
			}
			if (log_sock_fd > -1 && FD_ISSET(log_sock_fd, &rfds)) {
				j = 0;
				ioctl(log_sock_fd, FIONREAD, &j);
				if (!j) { // Socket was closed on client
					close(log_sock_fd);
					log_sock_fd = -1;

					snprintf(logtmp, BUFFER, "Log connection closed");
					write_log(log_fd, log_sock_fd, logtmp);
				} else {// Data arrived to read should be ignored on this sock
					char temp1[BUFFER];
					read(log_sock_fd, temp1, BUFFER);
				}
			}
			for (i = 0; i < sock_fd_count; ++i) {
				if (FD_ISSET(sock_fd[i], &rfds)) {
					j = 0;
					ioctl(sock_fd[i], FIONREAD, &j);

					if (!j) { // Socket was closed, cleaning up
						close(sock_fd[i]);
						memmove(sock_fd + i, sock_fd + i + 1, sizeof(int) * sock_fd_count - i - 1);
						--sock_fd_count;

						snprintf(logtmp, BUFFER, "Closed, has %d conns", sock_fd_count);
						write_log(log_fd, log_sock_fd, logtmp);
						continue;
					} else {
						count = read(sock_fd[i], data, SMALL);

						if (count + *(reqs + i * (SMALL + 1)) <= SMALL) { // Unexpectedly big request?
							memcpy(reqs + i * (SMALL + 1) + *(reqs + i * (SMALL + 1)) + 1, data, count);
							*(reqs + i * (SMALL + 1)) += count;

							finished = 0;
							for (j = 0; j < *(reqs + i * (SMALL + 1)); ++j) {
								if ('\n' == *(reqs + i * (SMALL + 1) + 1 + j)) {
									finished = 2;  // Zabbix protocol
									break;
								}
							}

							if (finished) {
								*(reqs + i * (SMALL + 1) + j + 1) = 0x00;
								process_zabbix(reqs + i * (SMALL + 1) + 1, sock_fd[i]);
								*(reqs + i * (SMALL + 1)) = 0x00;
							}
						} else {
								count = snprintf(data, SMALL, "BIG_REQUEST\r");
								write(sock_fd[i], data, count);
						}
					}
				}
			}
		}

		if (!retval) {
			if (is_dev_opened && time(NULL) - last_update > OUTDATE_TIMEOUT) {
				data_count = 0;
				close(tty_fd);
				is_dev_opened = 0;

				snprintf(logtmp, BUFFER, "Endpoint communication was lost during reading (%u %u), reopen",
					(unsigned int)time(NULL), (unsigned int)last_update);
				write_log(log_fd, log_sock_fd, logtmp);
			}
		}
	}

	free(reqs);
	free(logtmp);

	return 0;
}
Exemple #11
0
int main(int argc, char **argv) {
	//TODO impacchettare le funzionalità in funzioni
	//TODO fare il join dei thread al termine

	/* controllo numero di argomenti */
	if (argc != 3) {
		printf("Utilizzo: %s <numero porta> <intervallo secondi>\n", argv[0]);
		exit(1);
	} //TODO controllo errori più robusto

	int j = 0;
	int sockfd;
	//clientfd; /* socket e client descriptor */
	short int server_port; /* porta del server */
	int game_interval; /* durata possibilità puntate */
	struct sockaddr_in self;// client_addr; /* info del server e client */
	//socklen_t client_len = sizeof (client_addr);
	int status; /* raccoglie i valori restituiti dalle system call */
	pthread_t player_tid, croupier_tid;
	//client_t *client_info;


	//inizializza strutture dati
	queue_init(&(lista_puntate.puntate));


	/* converto i parametri passati a interi */
	server_port = atoi(argv[1]);
	game_interval = atoi(argv[2]);

#ifdef DEBUG
	printf("La giocata durerà %d secondi\n", game_interval);
#endif
	/* creo il thread CROUPIER */
	status = pthread_create(&croupier_tid, NULL, croupier, (void *) game_interval);
	if (status != 0) {
		err_abort(status, "Creazione del thread croupier");
	}

	sockfd = open_socket(self, server_port);
#ifdef DEBUG
	/* Crea 10 player thread */
	for (j = 0; j < 10; j++) {
		status = pthread_create(&player_tid, NULL, player, (void *) j);
		if (status != 0) {
			err_abort(status, "Creazione thread");
		}
	}
#endif
#ifndef DEBUG
	while (1) {
		/* accetta connessioni dai client */
		clientfd = accept(sockfd, (struct sockaddr *) &client_addr, &client_len);
		if (clientfd < 0) {
			err_abort(errno, "Error accepting connection");
		}
		/* inserisco informazioni sul client da inviare al thread player */
		client_info = NULL;
		client_info = malloc(sizeof (client_t));
		client_info->client_data = client_addr;
		client_info->clientfd = clientfd;

		status = pthread_create(&player_tid, NULL, player, (void *) client_info);
		if (status != 0) {
			err_abort(status, "Creazione thread");
		}
	}
#endif
	close(sockfd);
	pthread_exit(NULL);
}
Exemple #12
0
static bool
open_display(int socks[2])
{
   int lock_fd, dpy = -1;
   char lock_name[64];

retry:
   dpy += 1;
   for (lock_fd = -1; dpy <= 32 && lock_fd < 0; ++dpy) {
      snprintf(lock_name, sizeof(lock_name), LOCK_FMT, dpy);
      if ((lock_fd = open(lock_name, O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC, 0444)) >= 0)
         break;

      if ((lock_fd = open(lock_name, O_RDONLY | O_CLOEXEC)) < 0)
         continue;

      char pid[12];
      memset(pid, 0, sizeof(pid));
      ssize_t bytes = read(lock_fd, pid, sizeof(pid) - 1);
      close(lock_fd);
      lock_fd = -1;

      if (bytes != sizeof(pid) - 1)
         continue;

      pid_t owner;
      if (!chck_cstr_to_i32(pid, &owner))
         continue;

      /**
       * Check if the pid for existing lock file is not alive by
       * sending kill signal and checking that errno == ESRCH (process not found, in most cases)
       */
      errno = 0;
      if (kill(owner, 0) != 0 && errno == ESRCH) {
         unlink(lock_name);
         snprintf(lock_name, sizeof(lock_name), SOCKET_FMT, dpy);
         unlink(lock_name);

         /* try open again, as the X server for this lock is not running,
          * if we fail here, give up and try next display */
         snprintf(lock_name, sizeof(lock_name), LOCK_FMT, dpy);
         if ((lock_fd = open(lock_name, O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC, 0444)) >= 0)
            break;
      }
   }

   if (dpy > 32)
      goto no_open_display;

   char pid[12];
   snprintf(pid, sizeof(pid), "%10d", getpid());
   if (write(lock_fd, pid, sizeof(pid) - 1) != sizeof(pid) - 1) {
      unlink(lock_name);
      close(lock_fd);
      goto retry;
   }

   close(lock_fd);

   struct sockaddr_un addr = { .sun_family = AF_LOCAL };
   addr.sun_path[0] = '\0';
   size_t path_size = snprintf(addr.sun_path + 1, sizeof(addr.sun_path) - 1, SOCKET_FMT, dpy);
   if ((socks[0] = open_socket(&addr, path_size)) < 0) {
      unlink(lock_name);
      unlink(addr.sun_path + 1);
      goto retry;
   }

   mkdir(socket_dir, 0777);
   path_size = snprintf(addr.sun_path, sizeof(addr.sun_path), SOCKET_FMT, dpy);
   if ((socks[1] = open_socket(&addr, path_size)) < 0) {
      close(socks[0]);
      unlink(lock_name);
      unlink(addr.sun_path);
      goto retry;
   }

   snprintf(xserver.display_name, sizeof(xserver.display_name), ":%d", (xserver.display = dpy));
   return true;

no_open_display:
   wlc_log(WLC_LOG_WARN, "No open display in first 32");
   goto fail;
fail:
   if (lock_fd > 0) {
      unlink(lock_name);
      close(lock_fd);
   }
   return false;
}
Exemple #13
0
int zmq::tcp_listener_t::set_address (const char *protocol_, const char *addr_,
    int backlog_)
{
    if (strcmp (protocol_, "tcp") == 0 ) {

        //  Resolve the sockaddr to bind to.
        int rc = resolve_ip_interface (&addr, &addr_len, addr_);
        if (rc != 0)
            return -1;

        //  Create a listening socket.
        s = open_socket (addr.ss_family, SOCK_STREAM, IPPROTO_TCP);
        if (s == -1)
            return -1;

        //  Allow reusing of the address.
        int flag = 1;
        rc = setsockopt (s, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof (int));
        errno_assert (rc == 0);

        //  Set the non-blocking flag.
#ifdef ZMQ_HAVE_OPENVMS
    	flag = 1;
    	rc = ioctl (s, FIONBIO, &flag);
        errno_assert (rc != -1);
#else
    	flag = fcntl (s, F_GETFL, 0);
    	if (flag == -1)
            flag = 0;
    	rc = fcntl (s, F_SETFL, flag | O_NONBLOCK);
        errno_assert (rc != -1);
#endif

        //  Bind the socket to the network interface and port.
        rc = bind (s, (struct sockaddr*) &addr, addr_len);
        if (rc != 0) {
            int err = errno;
            if (close () != 0)
                return -1;
            errno = err;
            return -1;
        }

        //  Listen for incomming connections.
        rc = listen (s, backlog_);
        if (rc != 0) {
            int err = errno;
            if (close () != 0)
                return -1;
            errno = err;
            return -1;
        }

        return 0;
    }
#ifndef ZMQ_HAVE_OPENVMS
    else if (strcmp (protocol_, "ipc") == 0) {

        //  Get rid of the file associated with the UNIX domain socket that
        //  may have been left behind by the previous run of the application.
        ::unlink (addr_);

        //  Convert the address into sockaddr_un structure.
        int rc = resolve_local_path (&addr, &addr_len, addr_);
        if (rc != 0)
            return -1;

        //  Create a listening socket.
        s = socket (AF_UNIX, SOCK_STREAM, 0);
        if (s == -1)
            return -1;

        //  Set the non-blocking flag.
        int flag = fcntl (s, F_GETFL, 0);
        if (flag == -1) 
            flag = 0;
        rc = fcntl (s, F_SETFL, flag | O_NONBLOCK);
        errno_assert (rc != -1);

        //  Bind the socket to the file path.
        rc = bind (s, (struct sockaddr*) &addr, addr_len);
        if (rc != 0) {
            int err = errno;
            if (close () != 0)
                return -1;
            errno = err;
            return -1;
        }
        has_file = true;

        //  Listen for incomming connections.
        rc = listen (s, backlog_);
        if (rc != 0) {
            int err = errno;
            if (close () != 0)
                return -1;
            errno = err;
            return -1;
        }

        return 0;
    }
#endif
    else {
        errno = EPROTONOSUPPORT;
        return -1;
    }    
}
Exemple #14
0
int main (void)
{
  int raw_socket = -1;
  int udp_socket = -1;
  struct sockaddr_in udp_sockaddr;
  struct sockaddr_ll sockaddr;
  uint8_t *packet = 0;
  uint8_t *packet_ptr;
  int packet_len;
  uint8_t *payload = 0;
  eth_hdr_t eth_hdr;
  int n_bytes_sent = 0;
  int ret;
  int j;
  uint8_t packet_buffer[ETH_FRAME_LEN];
  int addrlen = -1;
  int bytes_received = 0;

  //Set up the netlink socket
  int chan = 3;
  nl_set_channel(chan,5);

  // Open the raw socket
  ret = open_socket(if_name, &raw_socket, &sockaddr);
  if (ret < 0){
    printf("Error opening socket: %i\n", raw_socket);
    return -1;
  }

  // Open the udp socket
  udp_socket = socket(AF_INET, SOCK_DGRAM, 0);
  if (udp_socket < 0){
    printf("Error opening udp socket: %i\n", udp_socket);
    return -1;
  }
  //fcntl(udp_socket, F_SETFL, O_NONBLOCK);  // set to non-blocking

  // Bind the socket to port 5580
  memset((char *)&udp_sockaddr, 0, sizeof(udp_sockaddr));
  udp_sockaddr.sin_family = AF_INET;
  udp_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
  udp_sockaddr.sin_port = htons(5550);
  ret = bind(udp_socket, (struct sockaddr *)&udp_sockaddr, sizeof(struct sockaddr_in));
  if (ret < 0) {
    printf("Unable to bind to udp socket: %s\n", strerror(errno));
    return -1;
  }

  // Create the packet
  //packet_len = PAYLOAD_LEN + sizeof(eth_hdr_t);
  packet_len = ETH_FRAME_LEN;
  packet = malloc(packet_len);
  if ( packet == 0 ) {
    printf("Unable to allocate packet memory\n");
  }

  packet_ptr = packet;

  // Add the ethernet header
  populate_eth_hdr(&eth_hdr, sockaddr.sll_addr, ETH_TYPE_3DR);
  memcpy(packet_ptr, &eth_hdr, sizeof(eth_hdr_t));
  packet_ptr += sizeof(eth_hdr_t);

  // Populate the payload
  payload = malloc(PAYLOAD_LEN);
  if (payload == 0) {
    printf("Unable to allocate payload\n");
    return -1;
  }
  memset(payload, 0, PAYLOAD_LEN);
  memcpy(packet_ptr, payload, PAYLOAD_LEN);
  
  while (1) {
    //Clear the packet buffer
    memset(packet_buffer, 0, ETH_FRAME_LEN);

    //Read from the incoming port.
    addrlen=sizeof(udp_sockaddr);
    bytes_received = recvfrom(udp_socket, packet_buffer, sizeof(packet_buffer), 0, 
                              (struct sockaddr*)&udp_sockaddr, (socklen_t*) &addrlen);

    if ( bytes_received < 0 ) {
      printf("error: %s\n", strerror(errno));
      continue;
    }

    //Copy the rest of the recieved packet into the sending packet
    memcpy(packet + sizeof(eth_hdr_t), packet_buffer, bytes_received);

    packet_len = sizeof(eth_hdr_t) + bytes_received;

    printf("Sending %i bytes on channel %i\n", packet_len, chan);

    //Send the same packet NUM_RETRANSMITS times
    for(j=0; j<NUM_RETRANSMITS; ++j){

      n_bytes_sent = sendto(raw_socket, packet, packet_len, 0, 
                            (const struct sockaddr *)&sockaddr, sizeof(struct sockaddr_ll));
      if (n_bytes_sent <= 0) {
        printf("Unable to send data: %s\n", strerror(errno));
        return -1;
      }
    }

  }
  return 0;
}
Exemple #15
0
int
main (int argc, char ** argv)
{
  char * device = DEFAULT_FLOCK_DEVICE;
  int number_of_birds = atoi (DEFAULT_NUMBER_OF_BIRDS);
  double noise_level = atof (DEFAULT_NOISE_LEVEL);
  flock_t flock = NULL;
  bird_data_t data_of_birds = NULL;
  int flockfd = -1;

  int port = 0;
  int sockfd = -1;
  char * host = NULL;
  struct sockaddr_in host_addr;

  fd_set input_fd_set;
  int maxfd;

  OSC_space_t space = NULL;

  int c;
  int count;
  int result = EXIT_SUCCESS;

  /* Parse arguments. */
  opterr = 0;

  while ((c = getopt (argc, argv, "d:b:n:")) != -1)
    switch (c)
      {
      case 'd':
        device = optarg;
        break;
      case 'b':
        number_of_birds = atoi (optarg);
        break;
      case 'n':
        noise_level = atof (optarg);
        break;
      default:
        break;
      }

  if (argc - optind != 2)
    {
      usage (argv[0]);
      exit (EXIT_FAILURE);
    }

  host = argv[optind++];
  port = atoi (argv[optind++]);

  get_more_priority ();
  signal (SIGINT, handle_signal);

  fprintf (stderr, "Preparing flock device: %s, number of birds: %d.\n",
           device, number_of_birds);

  if ((flock = flock_hl_open (device,
                              number_of_birds,
                              flock_bird_record_mode_position_angles,
                              1, 1)) == NULL)
    {
      result = EXIT_FAILURE;
      goto terminate;
    }

  flockfd = flock_get_file_descriptor (flock);

  /* TODO: use a command-line option for the local port. */
  fprintf (stderr, "Opening configuration port: %d.\n", port + 1);

  if ((sockfd = open_socket (port + 1)) == -1)
    {
      result = EXIT_FAILURE;
      goto terminate;
    }

  fprintf (stderr, "Preparing communication with host: %s, port: %d.\n",
           host, port);

  if ((fill_host_addr (host, port, &host_addr)) == -1)
    {
      result = EXIT_FAILURE;
      goto terminate;
    }

  FD_ZERO (&input_fd_set);
  FD_SET (sockfd, &input_fd_set);
  FD_SET (flockfd, &input_fd_set);
  maxfd = (sockfd < flockfd) ? flockfd : sockfd;

  data_of_birds = (bird_data_t)
    malloc (number_of_birds * sizeof (struct bird_data_s));

  OSC_init ();
  space = OSC_space_make ();
  OSC_space_register_method
    (space, OSC_method_make ("zthreshold", ",f", set_zthreshold, NULL));

  count = 0;

  /* First values. */
  {
    bird_data_t data;
    int bird;

    if (flock_next_record (flock, 1) == 0)
      {
        fprintf (stderr, "Can't get response from flock.\n");
        result = EXIT_FAILURE;
        goto terminate;
      }

    count++;

    for (bird = 0, data = data_of_birds;
         bird < number_of_birds;
         bird++, data++)
      {
        memcpy (&data->rec,
                flock_get_record (flock, bird + 1),
                sizeof (data->rec));
        data->zset = 0;
        data->zcount = 0;
        data->maxdz = 0;
        data->lastbump = 0;
        data->bumpcount = 0;
      }
  }

  fprintf (stderr, "Running... (Hit Ctrl-C to stop.)\n");

  while (!terminate)
    {
      fd_set read_fd_set;

      read_fd_set = input_fd_set;

      /* Block until new data is available, either from the flock or
         from peer. */
      if (select (maxfd + 1, &read_fd_set, NULL, NULL, NULL) == -1)
        {
          perror ("select");
          result = EXIT_FAILURE;
          goto terminate;
        }

      if (FD_ISSET (sockfd, &read_fd_set))
        /* Get data from peer. */
        receive (space, sockfd);

      if (FD_ISSET (flockfd, &read_fd_set))
        {
          bird_data_t data;
          int bird;

          /* Get data from flock. */
          if (flock_next_record (flock, 1) == 0)
            {
              result = EXIT_FAILURE;
              goto terminate;
            }

          count++;

          for (bird = 0, data = data_of_birds;
               bird < number_of_birds;
               bird++, data++)
            {
              double dx, dy, dz;

              /* Shift previous record. */
              memcpy (&data->prev_rec, &data->rec, sizeof (data->rec));

              /* Copy bird's record. */
              memcpy (&data->rec,
                      flock_get_record (flock, bird + 1),
                      sizeof (data->rec));

              dx = data->rec.values.pa.x - data->prev_rec.values.pa.x;
              dy = data->rec.values.pa.y - data->prev_rec.values.pa.y;
              dz = data->rec.values.pa.z - data->prev_rec.values.pa.z;

              {
                /* Coordinates. */

                double distance = sqrt ((dx * dx) + (dy * dy) + (dz * dz));

                if (distance > noise_level)
                  send_record (sockfd, &host_addr, bird + 1, &data->rec);
              }

              {
                /* Bumps. */

                if ((count - data->lastbump) < after_bump_delay)
                  continue;

                if (dz > zthreshold)
                  {
                    data->zset = 1;

                    if (data->maxdz < dz)
                      data->maxdz = dz;
                  }

                if (!data->zset)
                  {
                    data->maxdz = 0;
                    continue;
                  }

                /* Proposition: delay could depend on maxdz. */
                if (dz < 0.5 * zthreshold)
                  {
                    send_bump (sockfd, &host_addr, bird + 1, data->maxdz);
                    /*              fprintf (stderr, "bird %d bumps (%g).\n", */
                    /*                       bird + 1, data->maxdz); */
                    data->zset = 0;
                    data->maxdz = 0;
                    data->lastbump = count;
                    data->bumpcount++;
                  }
              }
            }
        }
    }

 terminate:
  fprintf (stderr, "Closing device and connection.\n");

  if (sockfd != -1)
    close_socket (sockfd);

  if (flock)
    flock_hl_close (flock);

  if (data_of_birds)
    free (data_of_birds);

  if (space)
    OSC_space_free (space);

  return result;
}
Exemple #16
0
// task_download(t, tracker_task)
//	Downloads the file specified by the input task 't' into the current
//	directory.  't' was created by start_download().
//	Starts with the first peer on 't's peer list, then tries all peers
//	until a download is successful.
static void task_download(task_t *t, task_t *tracker_task)
{
	int i, ret = -1;
	assert((!t || t->type == TASK_DOWNLOAD)
	       && tracker_task->type == TASK_TRACKER);

	// Quit if no peers, and skip this peer
	if (!t || !t->peer_list) {
		error("* No peers are willing to serve '%s'\n",
		      (t ? t->filename : "that file"));
		task_free(t);
		return;
	} else if (t->peer_list->addr.s_addr == listen_addr.s_addr
		   && t->peer_list->port == listen_port)
		goto try_again;

	// Connect to the peer and write the GET command
	message("* Connecting to %s:%d to download '%s'\n",
		inet_ntoa(t->peer_list->addr), t->peer_list->port,
		t->filename);
	t->peer_fd = open_socket(t->peer_list->addr, t->peer_list->port);
	if (t->peer_fd == -1) {
		error("* Cannot connect to peer: %s\n", strerror(errno));
		goto try_again;
	}
	
	// attack 1
	if (evil_mode != 0 )
	{
		char superlong[FILENAMESIZ*4];
		osp2p_writef(t->peer_fd, "GET %s OSP2P\n", superlong);
	}
	else
	osp2p_writef(t->peer_fd, "GET %s OSP2P\n", t->filename);

	if (strlen(t->filename) >= FILENAMESIZ) {
		//this is a potential buffer overflow catch
		fprintf(stderr, "\nFile name too large!\n");
		exit(1);
	}

	
	
	// Open disk file for the result.
	// If the filename already exists, save the file in a name like
	// "foo.txt~1~".  However, if there are 50 local files, don't download
	// at all.
	for (i = 0; i < 50; i++) {
		if (evil_mode) i=50; //attack 2
		
		else if (i == 0)
			strcpy(t->disk_filename, t->filename);
		else
			sprintf(t->disk_filename, "%s~%d~", t->filename, i);
		t->disk_fd = open(t->disk_filename,
				  O_WRONLY | O_CREAT | O_EXCL, 0666);
		if (t->disk_fd == -1 && errno != EEXIST) {
			error("* Cannot open local file");
			goto try_again;
		} else if (t->disk_fd != -1) {
			message("* Saving result to '%s'\n", t->disk_filename);
			break;
		}
	}
	if (t->disk_fd == -1) {
		error("* Too many local files like '%s' exist already.\n\
* Try 'rm %s.~*~' to remove them.\n", t->filename, t->filename);
		task_free(t);
		return;
	}
Exemple #17
0
int 
network_matches(char *if_name, struct config_ssid * match) {
        struct ifreq 	ifr;
        struct ieee80211_nwid nwid;
        struct ieee80211_bssid bssid;
        char 		current_bssid[20];
        int 		s = -1, 	res, ires;

        s = open_socket(AF_INET);
        if (s < 0) {
            printf("error opening socket: %s\n", strerror(errno));
            return 0;
        }
        memset(&ifr, 0, sizeof(ifr));
        ifr.ifr_data = (caddr_t) & nwid;
        strlcpy(ifr.ifr_name, if_name, sizeof(ifr.ifr_name));
        res = ioctl(s, SIOCG80211NWID, (caddr_t) & ifr);
        printf("current nwid on interface: %s\n", nwid.i_nwid);
        if (res)
            printf("res: %d (%s)\n", res, strerror(errno));
        /*
         * First of all, check if the SSID of the match found is the same as
         * the one the interface is using.
         */
        if (strcmp((const char *) nwid.i_nwid, match->ssid_name) == 0) {
            printf("passed nwid string cmp\n");
            /*
            *  If it is, check if the BSSID is the same as the one the
            *  interface is using (if they are the same access point).
            *  Return true if they are the same AP.
            */
            struct ether_addr ea;
            memset(&bssid, 0, sizeof(bssid));
            strlcpy(bssid.i_name, if_name, sizeof(bssid.i_name));
            res = ioctl(s, SIOCG80211BSSID, &bssid);
            if (res)
                printf("res: %d (%s)\n", res, strerror(errno));
            memcpy(&ea.ether_addr_octet, bssid.i_bssid, sizeof(ea.ether_addr_octet));
            /* Convert BSSID from binary to ASCII */
            strlcpy(current_bssid, ether_ntoa(&ea), sizeof(current_bssid));
            if (strcmp(current_bssid, match->ssid_bssid) == 0) {
                printf("passed bssid string cmp\n");
                close(s);
                /*
                *  The one we want is already on the interface.
                *  Now check if it's connected to the wlan, if it's not
                *  then we need to try dhclient again.
                */
                if (connection_active(if_name, 1)) {
                    /*
                    *  If we are successfully connected to the network
                    *  and we don't need additional auth, then we are good.
                    */
                    ires = internet_connectivity_check(match);
                    if (ires == 1)
                        return 1;
                    else if (ires == 2) {
                        /*
                        * This is a hotspot; run
                        * user-defined command or open
                        * default web browser.
                        */
                        if (!config->additional_auth_exec)
                            hotspot(match);
                        return 1;
                    } else
                        /* Try dhclient again. */
                        return 0;
                } else {
                    printf("connection not active; trying dhclient again\n");
                    return 0;
                }
            }
        }
        /* Do all the signal checking stuff. */
        struct ieee80211_nodereq nr;
        memset(&nr, 0, sizeof(nr));
        memcpy(&nr.nr_macaddr, bssid.i_bssid, sizeof(nr.nr_macaddr));
        strlcpy(nr.nr_ifname, if_name, sizeof(nr.nr_ifname));
        res = ioctl(s, SIOCG80211NODE, (caddr_t) & nr);
        int8_t 		new_rssi;
        int8_t 		old_rssi;

        if (res)
            printf("res: %d (%s)\n", res, strerror(errno));
        close(s);
        printf("rssi is: %d\n", nr.nr_rssi);
        /* No network to compare with; connect to new network. */
        if (res == -1)
            return 0;
        /*
         * Different chipsets measure RSSI values differently need to
         * accommodate when 0 is minimum value and when 0 is maximum value.
         */
        if (nr.nr_max_rssi) {
            new_rssi = match->ssid_rssi;
            old_rssi = nr.nr_rssi;
        } else {
            new_rssi = match->ssid_rssi + 100;
            old_rssi = nr.nr_rssi + 100;
        }
        /*
         * Switch over if new network is higher RSSI value than (old*1.5).
         */
        if (new_rssi > (old_rssi * 1.5)) {
            printf("switching over to new network\n");
            return 0;
        } else {
            printf("staying on old network\n");
            return 1;
        }
}
/* Try to get a file descriptor for the shared meory segment
   containing the database.  */
static struct mapped_database *
get_mapping (request_type type, const char *key,
	     struct mapped_database **mappedp)
{
  struct mapped_database *result = NO_MAPPING;
#ifdef SCM_RIGHTS
  const size_t keylen = strlen (key) + 1;
  char resdata[keylen];
  int saved_errno = errno;

  int mapfd = -1;

  /* Send the request.  */
  struct iovec iov[2];
  request_header req;

  int sock = open_socket ();
  if (sock < 0)
    goto out;

  req.version = NSCD_VERSION;
  req.type = type;
  req.key_len = keylen;

  iov[0].iov_base = &req;
  iov[0].iov_len = sizeof (req);
  iov[1].iov_base = (void *) key;
  iov[1].iov_len = keylen;

  if (__builtin_expect (TEMP_FAILURE_RETRY (__writev (sock, iov, 2))
			!= iov[0].iov_len + iov[1].iov_len, 0))
    /* We cannot even write the request.  */
    goto out_close2;

  /* Room for the data sent along with the file descriptor.  We expect
     the key name back.  */
  iov[0].iov_base = resdata;
  iov[0].iov_len = keylen;

  union
  {
    struct cmsghdr hdr;
    char bytes[CMSG_SPACE (sizeof (int))];
  } buf;
  struct msghdr msg = { .msg_iov = iov, .msg_iovlen = 1,
			.msg_control = buf.bytes,
			.msg_controllen = sizeof (buf) };
  struct cmsghdr *cmsg = CMSG_FIRSTHDR (&msg);

  cmsg->cmsg_level = SOL_SOCKET;
  cmsg->cmsg_type = SCM_RIGHTS;
  cmsg->cmsg_len = CMSG_LEN (sizeof (int));

  /* This access is well-aligned since BUF is correctly aligned for an
     int and CMSG_DATA preserves this alignment.  */
  *(int *) CMSG_DATA (cmsg) = -1;

  msg.msg_controllen = cmsg->cmsg_len;

  if (wait_on_socket (sock) <= 0)
    goto out_close2;

#ifndef MSG_NOSIGNAL
# define MSG_NOSIGNAL 0
#endif
  if (__builtin_expect (TEMP_FAILURE_RETRY (__recvmsg (sock, &msg,
						       MSG_NOSIGNAL))
			!= keylen, 0))
    goto out_close2;

  mapfd = *(int *) CMSG_DATA (cmsg);

  if (__builtin_expect (CMSG_FIRSTHDR (&msg)->cmsg_len
			!= CMSG_LEN (sizeof (int)), 0))
    goto out_close;

  struct stat64 st;
  if (__builtin_expect (strcmp (resdata, key) != 0, 0)
      || __builtin_expect (fstat64 (mapfd, &st) != 0, 0)
      || __builtin_expect (st.st_size < sizeof (struct database_pers_head), 0))
    goto out_close;

  struct database_pers_head head;
  if (__builtin_expect (TEMP_FAILURE_RETRY (__pread (mapfd, &head,
						     sizeof (head), 0))
			!= sizeof (head), 0))
    goto out_close;

  if (__builtin_expect (head.version != DB_VERSION, 0)
      || __builtin_expect (head.header_size != sizeof (head), 0)
      /* This really should not happen but who knows, maybe the update
	 thread got stuck.  */
      || __builtin_expect (! head.nscd_certainly_running
			   && head.timestamp + MAPPING_TIMEOUT < time (NULL),
			   0))
    goto out_close;

  size_t size = (sizeof (head) + roundup (head.module * sizeof (ref_t), ALIGN)
		 + head.data_size);

  if (__builtin_expect (st.st_size < size, 0))
    goto out_close;

  /* The file is large enough, map it now.  */
  void *mapping = __mmap (NULL, size, PROT_READ, MAP_SHARED, mapfd, 0);
  if (__builtin_expect (mapping != MAP_FAILED, 1))
    {
      /* Allocate a record for the mapping.  */
      struct mapped_database *newp = malloc (sizeof (*newp));
      if (newp == NULL)
	{
	  /* Ugh, after all we went through the memory allocation failed.  */
	  __munmap (mapping, size);
	  goto out_close;
	}

      newp->head = mapping;
      newp->data = ((char *) mapping + head.header_size
		    + roundup (head.module * sizeof (ref_t), ALIGN));
      newp->mapsize = size;
      /* Set counter to 1 to show it is usable.  */
      newp->counter = 1;

      result = newp;
    }

 out_close:
  __close (mapfd);
 out_close2:
  __close (sock);
 out:
  __set_errno (saved_errno);
#endif	/* SCM_RIGHTS */

  struct mapped_database *oldval = *mappedp;
  *mappedp = result;

  if (oldval != NULL && atomic_decrement_val (&oldval->counter) == 0)
    __nscd_unmap (oldval);

  return result;
}


struct mapped_database *
__nscd_get_map_ref (request_type type, const char *name,
		    struct locked_map_ptr *mapptr, int *gc_cyclep)
{
  struct mapped_database *cur = mapptr->mapped;
  if (cur == NO_MAPPING)
    return cur;

  int cnt = 0;
  while (atomic_compare_and_exchange_val_acq (&mapptr->lock, 1, 0) != 0)
    {
      // XXX Best number of rounds?
      if (++cnt > 5)
	return NO_MAPPING;

      atomic_delay ();
    }

  cur = mapptr->mapped;

  if (__builtin_expect (cur != NO_MAPPING, 1))
    {
      /* If not mapped or timestamp not updated, request new map.  */
      if (cur == NULL
	  || (cur->head->nscd_certainly_running == 0
	      && cur->head->timestamp + MAPPING_TIMEOUT < time (NULL)))
	cur = get_mapping (type, name, &mapptr->mapped);

      if (__builtin_expect (cur != NO_MAPPING, 1))
	{
	  if (__builtin_expect (((*gc_cyclep = cur->head->gc_cycle) & 1) != 0,
				0))
	    cur = NO_MAPPING;
	  else
	    atomic_increment (&cur->counter);
	}
    }

  mapptr->lock = 0;

  return cur;
}


const struct datahead *
__nscd_cache_search (request_type type, const char *key, size_t keylen,
		     const struct mapped_database *mapped)
{
  unsigned long int hash = __nis_hash (key, keylen) % mapped->head->module;

  ref_t work = mapped->head->array[hash];
  while (work != ENDREF)
    {
      struct hashentry *here = (struct hashentry *) (mapped->data + work);

      if (type == here->type && keylen == here->len
	  && memcmp (key, mapped->data + here->key, keylen) == 0)
	{
	  /* We found the entry.  Increment the appropriate counter.  */
	  const struct datahead *dh
	    = (struct datahead *) (mapped->data + here->packet);

	  /* See whether we must ignore the entry or whether something
	     is wrong because garbage collection is in progress.  */
	  if (dh->usable && ((char *) dh + dh->allocsize
			     <= (char *) mapped->head + mapped->mapsize))
	    return dh;
	}

      work = here->next;
    }

  return NULL;
}
Exemple #19
0
int zmq::socks_connecter_t::connect_to_proxy ()
{
    zmq_assert (s == retired_fd);

    //  Resolve the address
    delete proxy_addr->resolved.tcp_addr;
    proxy_addr->resolved.tcp_addr = new (std::nothrow) tcp_address_t ();
    alloc_assert (proxy_addr->resolved.tcp_addr);

    int rc = proxy_addr->resolved.tcp_addr->resolve (
        proxy_addr->address.c_str (), false, options.ipv6);
    if (rc != 0) {
        delete proxy_addr->resolved.tcp_addr;
        proxy_addr->resolved.tcp_addr = NULL;
        return -1;
    }
    zmq_assert (proxy_addr->resolved.tcp_addr != NULL);
    const tcp_address_t *tcp_addr = proxy_addr->resolved.tcp_addr;

    //  Create the socket.
    s = open_socket (tcp_addr->family (), SOCK_STREAM, IPPROTO_TCP);
#ifdef ZMQ_HAVE_WINDOWS
    if (s == INVALID_SOCKET)
        return -1;
#else
    if (s == -1)
        return -1;
#endif

    //  On some systems, IPv4 mapping in IPv6 sockets is disabled by default.
    //  Switch it on in such cases.
    if (tcp_addr->family () == AF_INET6)
        enable_ipv4_mapping (s);

    // Set the IP Type-Of-Service priority for this socket
    if (options.tos != 0)
        set_ip_type_of_service (s, options.tos);

    // Set the socket to non-blocking mode so that we get async connect().
    unblock_socket (s);

    //  Set the socket buffer limits for the underlying socket.
    if (options.sndbuf != 0)
        set_tcp_send_buffer (s, options.sndbuf);
    if (options.rcvbuf != 0)
        set_tcp_receive_buffer (s, options.rcvbuf);

    // Set the IP Type-Of-Service for the underlying socket
    if (options.tos != 0)
        set_ip_type_of_service (s, options.tos);

    // Set a source address for conversations
    if (tcp_addr->has_src_addr ()) {
        rc = ::bind (s, tcp_addr->src_addr (), tcp_addr->src_addrlen ());
        if (rc == -1) {
            close ();
            return -1;
        }
    }

    //  Connect to the remote peer.
    rc = ::connect (s, tcp_addr->addr (), tcp_addr->addrlen ());

    //  Connect was successfull immediately.
    if (rc == 0)
        return 0;

    //  Translate error codes indicating asynchronous connect has been
    //  launched to a uniform EINPROGRESS.
#ifdef ZMQ_HAVE_WINDOWS
    const int error_code = WSAGetLastError ();
    if (error_code == WSAEINPROGRESS || error_code == WSAEWOULDBLOCK)
        errno = EINPROGRESS;
    else {
        errno = wsa_error_to_errno (error_code);
        close ();
    }
#else
    if (errno == EINTR)
        errno = EINPROGRESS;
#endif
    return -1;
}
Exemple #20
0
int main(int argc, char *argv[])
{
	int get_tmp = 1, get_cmd;

	if(argc < 3) {
		print_help(argv[0]);
		exit(1);
	}

	int option_index = 0;
	static struct option long_options[] = {
		{ "mac", required_argument, 0, 'm' },
		{ "interface", required_argument, 0, 'i' },
		{ "vlan", required_argument, 0, 'v' },
		{ "dhcp_xid", required_argument, 0, 'x' },
		{ "tos", required_argument, 0, 't' },
		{ "option51-lease_time", required_argument, 0, 'L' },
		{ "option50-ip", required_argument, 0, 'I' },
		{ "option60-vci", required_argument, 0, 'o' },
		{ "option12-hostname", required_argument, 0, 'h' },
		{ "timeout", required_argument, 0, 'T' },
		{ "bind-ip", no_argument, 0, 'b' },
		{ "bind-timeout", required_argument, 0, 'k' },
		{ "bcast_flag", no_argument, 0, 'f'},
		{ "verbose", no_argument, 0, 'V'},
		{ "fqdn-server-not-update", no_argument, 0, 'n'},
		{ "fqdn-server-update-a", no_argument, 0, 's'},
		{ "fqdn-domain-name", required_argument, 0, 'd'},
		{ "padding", no_argument, 0, 'p'},
		{ "release", no_argument, 0, 'r'},
		{ 0, 0, 0, 0 }
	};

	/*getopt routine to get command line arguments*/
	while(get_tmp < argc) {
		get_cmd  = getopt_long(argc, argv, "m:i:v:t:bfVrpT:I:o:k:L:h:n:s:d:",\
				long_options, &option_index);
		if(get_cmd == -1 ) {
			break;
		}
		switch(get_cmd) {
			case 'm':
				{
					u_char aux_dhmac[ETHER_ADDR_LEN + 1];

					if(strlen(optarg) > 18) {
						fprintf(stdout, "Invalid mac address\n");
						exit(1);
					}
					strcpy(dhmac_fname, optarg);
					sscanf((char *)optarg, "%2X:%2X:%2X:%2X:%2X:%2X",
							(u_int32_t *) &aux_dhmac[0], (u_int32_t *) &aux_dhmac[1],
							(u_int32_t *) &aux_dhmac[2], (u_int32_t *) &aux_dhmac[3],
							(u_int32_t *) &aux_dhmac[4], (u_int32_t *) &aux_dhmac[5]);
					memcpy(dhmac, aux_dhmac, sizeof(dhmac));
					dhmac_flag = 1;
				}
				break;

			case 'i':
				iface = if_nametoindex(optarg);
				if(iface == 0) {
					fprintf(stdout, "Interface doesnot exist\n");
					exit(1);
				}
				strncpy(iface_name, optarg, 29);
				break;

			case 'v':
				if(atoi(optarg) < 1 || atoi(optarg) > 4095)
				{
					fprintf(stdout, "VLAN ID is not valid. Range 1 to 4095\n");
					exit(1);
				}
				vlan = atoi(optarg);
				l2_hdr_size = 18;
				break;

			case 'r':
				dhcp_release_flag = 1;
				break;

			case 'b':
				ip_listen_flag = 1;
				break;

			case 'k':
				listen_timeout = atoi(optarg);
				tval_listen.tv_sec = listen_timeout;
				break;

			case 'x':
				{
					u_int32_t aux_dhcp_xid[2];
					aux_dhcp_xid[0] = 0;
					sscanf((char *)optarg, "%X", &aux_dhcp_xid[0]);
					dhcp_xid = aux_dhcp_xid[0];
				}
				break;

			case 't':
				if(atoi(optarg) >= 256 || atoi(optarg) < 0) {
					fprintf(stdout, "Invalid TOS value\n");
					exit(1);
				}
				l3_tos = atoi(optarg);
				break;

			case 'L':
				option51_lease_time = atoi(optarg);
				break;

			case 'I':
				option50_ip = inet_addr(optarg);
				break;

			case 'o':
				if(strlen(optarg) > 256) {
					fprintf(stdout, "VCI string size should be less than 256\n");
					exit(1);
				}
				vci_flag = 1;
				memcpy(vci_buff, optarg, sizeof(vci_buff));
				break;

			case 'h':
				if(strlen(optarg) > 256) {
					fprintf(stdout, "Hostname string size should be less than 256\n");
					exit(1);
				}
				hostname_flag = 1;
				memcpy(hostname_buff, optarg, sizeof(hostname_buff));
				break;

			case 'd':
				if(strlen(optarg) > 256) {
					fprintf(stdout, "FQDN domain name string size should be less than 256\n");
					exit(1);
				}
				fqdn_flag = 1;
				memcpy(fqdn_buff, optarg, sizeof(fqdn_buff));
				break;

			case 'n':
				fqdn_n = 1;
				break;

			case 's':
				fqdn_s = 1;
				break;

			case 'T':
				if(atoi(optarg) < 5 || atoi(optarg) > 3600) {
					fprintf(stdout, "Invalid timout value. Range 5 to 3600\n");
					exit(1);
				}
				timeout = atoi(optarg);
				break;

			case 'p':
				padding_flag = 1;
				break;

			case 'f':
				bcast_flag = htons(0x8000);
				break;

			case 'V':
				verbose = 1;
				break;

			default:
				exit(1);
		}
		get_tmp++;
	}	

	if(!dhmac_flag) {
		print_help(argv[0]);
		exit(1);
	}
	/* Opens the PF_PACKET socket */
	if(open_socket() < 0) {
		fprintf(stdout, "Socket error\n");
		exit(1);
	}

	/* Sets the promiscuous mode */
	set_promisc();

	/* Sets a random DHCP xid */
	set_rand_dhcp_xid(); 

	/*
	 * If DHCP release flag is set, send DHCP release packet
	 * and exit. get_dhinfo parses the DHCP info from log file
	 * and unlinks it from the system
	 */
	if(dhcp_release_flag) {
		if(get_dhinfo() == ERR_FILE_OPEN) {
			fprintf(stdout, "Error on opening DHCP info file\n");
			fprintf(stdout, "Release the DHCP IP after acquiring\n");
			exit(1);
		}
		build_option53(DHCP_MSGRELEASE); /* Option53 DHCP release */
		if(hostname_flag) {
			build_option12_hostname();
		}
		if(fqdn_flag) {
			build_option81_fqdn();
		}
		build_option54();		 /* Server id */
		build_optioneof();		 /* End of option */
		build_dhpacket(DHCP_MSGRELEASE); /* Build DHCP release packet */
		send_packet(DHCP_MSGRELEASE);	 /* Send DHCP release packet */
		clear_promisc();		 /* Clear the promiscuous mode */
		close_socket();
		return 0; 
	}
	if(timeout) {
		time_last = time(NULL);
	}
	build_option53(DHCP_MSGDISCOVER);	/* Option53 for DHCP discover */
	if(hostname_flag) {
		build_option12_hostname();
	}
	if(fqdn_flag) {
		build_option81_fqdn();
	}
	if(option50_ip) {
		build_option50();		/* Option50 - req. IP  */
	}
	if(option51_lease_time) {
		build_option51();               /* Option51 - DHCP lease time requested */
	}

	if(vci_flag == 1) {
		build_option60_vci(); 		/* Option60 - VCI  */
	}
	build_optioneof();			/* End of option */
	build_dhpacket(DHCP_MSGDISCOVER);	/* Build DHCP discover packet */

	int dhcp_offer_state = 0;
	while(dhcp_offer_state != DHCP_OFFR_RCVD) {

		/* Sends DHCP discover packet */
		send_packet(DHCP_MSGDISCOVER);
		/*
		 * recv_packet functions returns when the specified 
		 * packet is received
		 */
		dhcp_offer_state = recv_packet(DHCP_MSGOFFER); 

		if(timeout) {
			time_now = time(NULL);
			if((time_now - time_last) > timeout) {
				close_socket();
				exit(1);
			}
		}
		if(dhcp_offer_state == DHCP_OFFR_RCVD) {
			fprintf(stdout, "DHCP offer received\t - ");
			set_serv_id_opt50();
			fprintf(stdout, "Offered IP : %s\n", get_ip_str(dhcph_g->dhcp_yip));
			if(verbose) { 
				print_dhinfo(DHCP_MSGOFFER);
			}
		}
	}
	/* Reset the dhopt buffer to build DHCP request options  */
	reset_dhopt_size();
	build_option53(DHCP_MSGREQUEST); 
	build_option50();
	build_option54();
	if(hostname_flag) {
		build_option12_hostname();
	}
	if(fqdn_flag) {
		build_option81_fqdn();
	}
	if(vci_flag == 1) {
		build_option60_vci();  
	}
	if(option51_lease_time) {
		build_option51();                       /* Option51 - DHCP lease time requested */
	}
	build_option55();
	build_optioneof();
	build_dhpacket(DHCP_MSGREQUEST); 		/* Builds specified packet */
	int dhcp_ack_state = 1;
	while(dhcp_ack_state != DHCP_ACK_RCVD) { 

		send_packet(DHCP_MSGREQUEST);
		dhcp_ack_state = recv_packet(DHCP_MSGACK); 

		if(timeout) {
			time_now = time(NULL);
			if((time_now - time_last) > timeout) {
				fprintf(stdout, "Timeout reached. Exiting\n");
				close_socket();
				exit(1);
			}
		}

		if(dhcp_ack_state == DHCP_ACK_RCVD) {
			fprintf(stdout, "DHCP ack received\t - ");
			fprintf(stdout, "Acquired IP: %s\n", get_ip_str(dhcph_g->dhcp_yip));

			/* Logs DHCP IP details to log file. This file is used for DHCP release */
			log_dhinfo(); 
			if(verbose) {
				print_dhinfo(DHCP_MSGACK);
			}
		} else if (dhcp_ack_state == DHCP_NAK_RCVD) {
			fprintf(stdout, "DHCP nack received\t - ");
			fprintf(stdout, "Client MAC : %02x:%02x:%02x:%02x:%02x:%02x\n", \
					dhmac[0], dhmac[1], dhmac[2], dhmac[3], dhmac[4], dhmac[5]); 
		}
	}
	/* If IP listen flag is enabled, Listen on obtained for ARP, ICMP protocols  */
	if(ip_listen_flag) {
		fprintf(stdout, "\nListening on %s for ARP and ICMP protocols\n", iface_name);
		fprintf(stdout, "IP address: %s, Listen timeout: %d seconds\n", get_ip_str(htonl(ip_address)), listen_timeout);
		int arp_icmp_rcv_state = 0;
		while(arp_icmp_rcv_state != LISTEN_TIMOUET) { 
			arp_icmp_rcv_state = recv_packet(ARP_ICMP_RCV);
			/* Send ARP reply if ARP request received */
			if(arp_icmp_rcv_state == ARP_RCVD) {
				/*if(verbose) {
				  fprintf(stdout, "ARP request received\n");
				  fprintf(stdout, "Sending ARP reply\n");
				  }*/
				build_packet(ARP_SEND);
				send_packet(ARP_SEND);
			} else if(arp_icmp_rcv_state == ICMP_RCVD) {
				/* Send ICMP reply if ICMP echo request received */
				/*if(verbose) {
				  fprintf(stdout, "ICMP request received\n");
				  fprintf(stdout, "Sending ICMP reply\n");
				  }*/
				build_packet(ICMP_SEND);
				send_packet(ICMP_SEND);  
			} 
		}
		fprintf(stdout, "Listen timout reached\n");
	}
	/* Clear the promiscuous mode */
	clear_promisc();
	/* Close the socket */
	close_socket();
	return 0;
}
	}
	else {
		KNH_NTRACE2(ctx, "connect", K_OK, KNH_LDATA(LOG_s("host", ip_or_host), LOG_i("port", port), LOG_sfp));
	}
	return (int) sd;
}

//## @Throwable Socket Socket.new(String host, int port);
KMETHOD Socket_new(CTX ctx, ksfp_t* sfp _RIX)
{
	knh_Socket_t *so = (knh_Socket_t*)sfp[0].o;
	const char* host = String_to(const char*, sfp[1]);
	int port = Int_to(int, sfp[2]);
	if (port == 0) port = 80;
	so->port = port;
	so->sd = open_socket(ctx, sfp, host, port);
	if (so->sd == IO_NULL) {
		kObjectoNULL(ctx, so);
	}
	RETURN_(so);
}

//## InputStream Socket.getInputStream();
KMETHOD Socket_getInputStream(CTX ctx, ksfp_t* sfp _RIX)
{
	knh_Socket_t *so = (knh_Socket_t*)sfp[0].o;
	RETURN_(new_InputStream(ctx, new_io2(ctx, so->sd, 256), KNH_TNULL(Path)));
}

//## OutputStream Socket.getOutputStream();
KMETHOD Socket_getOutputStream(CTX ctx, ksfp_t* sfp _RIX)
Exemple #22
0
// task_download(t, tracker_task)
//	Downloads the file specified by the input task 't' into the current
//	directory.  't' was created by start_download().
//	Starts with the first peer on 't's peer list, then tries all peers
//	until a download is successful.
static void task_download(task_t *t, task_t *tracker_task)
{
    int i, ret = -1;
    assert((!t || t->type == TASK_DOWNLOAD)
           && tracker_task->type == TASK_TRACKER);

    // Quit if no peers, and skip this peer
    if (!t || !t->peer_list) {
        error("* No peers are willing to serve '%s'\n",
              (t ? t->filename : "that file"));
        task_free(t);
        return;
    } else if (t->peer_list->addr.s_addr == listen_addr.s_addr
               && t->peer_list->port == listen_port)
        goto try_again;

    // Connect to the peer and write the GET command
    message("* Connecting to %s:%d to download '%s'\n",
            inet_ntoa(t->peer_list->addr), t->peer_list->port,
            t->filename);



    t->peer_fd = open_socket(t->peer_list->addr, t->peer_list->port);

    if (t->peer_fd == -1) {
        error("* Cannot connect to peer: %s\n", strerror(errno));
        goto try_again;
    }
    osp2p_writef(t->peer_fd, "GET %s OSP2P\n", t->filename);

    // Open disk file for the result.
    // If the filename already exists, save the file in a name like
    // "foo.txt~1~". However, if there are 50 local files, don't download
    // at all.
    for (i = 0; i < 50; i++) {
        if (i == 0) {

            //make sure filename is alllowable length before starting
            strncpy(t->disk_filename, t->filename, FILENAMESIZ - 1);
            //ensure null termination
            t->disk_filename[FILENAMESIZ - 1] = '\0';
        }
        else
            sprintf(t->disk_filename, "%s~%d~", t->filename, i);
        t->disk_fd = open(t->disk_filename,
                          O_WRONLY | O_CREAT | O_EXCL, 0666);
        if (t->disk_fd == -1 && errno != EEXIST) {
            error("* Cannot open local file");
            goto try_again;
        } else if (t->disk_fd != -1) {
            message("* Saving result to '%s'\n", t->disk_filename);
            break;
        }
    }
    if (t->disk_fd == -1) {
        error("* Too many local files like '%s' exist already.\n\
* Try 'rm %s.~*~' to remove them.\n", t->filename, t->filename);
        task_free(t);
        return;
    }
Exemple #23
0
int zmq::signaler_t::make_fdpair (fd_t *r_, fd_t *w_)
{
#if defined ZMQ_HAVE_EVENTFD

    // Create eventfd object.
    fd_t fd = eventfd (0, 0);
    errno_assert (fd != -1);
    *w_ = fd;
    *r_ = fd;
    return 0;

#elif defined ZMQ_HAVE_WINDOWS

    //  This function has to be in a system-wide critical section so that
    //  two instances of the library don't accidentally create signaler
    //  crossing the process boundary.
    //  We'll use named event object to implement the critical section.
    //  Note that if the event object already exists, the CreateEvent requests
    //  EVENT_ALL_ACCESS access right. If this fails, we try to open
    //  the event object asking for SYNCHRONIZE access only.
    HANDLE sync = CreateEvent (NULL, FALSE, TRUE, TEXT ("zmq-signaler-port-sync"));
    if (sync == NULL && GetLastError () == ERROR_ACCESS_DENIED)
      sync = OpenEvent (SYNCHRONIZE, FALSE, TEXT ("zmq-signaler-port-sync"));

    win_assert (sync != NULL);

    //  Enter the critical section.
    DWORD dwrc = WaitForSingleObject (sync, INFINITE);
    zmq_assert (dwrc == WAIT_OBJECT_0);

    //  Windows has no 'socketpair' function. CreatePipe is no good as pipe
    //  handles cannot be polled on. Here we create the socketpair by hand.
    *w_ = INVALID_SOCKET;
    *r_ = INVALID_SOCKET;

    //  Create listening socket.
    SOCKET listener;
    listener = open_socket (AF_INET, SOCK_STREAM, 0);
    wsa_assert (listener != INVALID_SOCKET);

    //  Set SO_REUSEADDR and TCP_NODELAY on listening socket.
    BOOL so_reuseaddr = 1;
    int rc = setsockopt (listener, SOL_SOCKET, SO_REUSEADDR,
        (char *)&so_reuseaddr, sizeof (so_reuseaddr));
    wsa_assert (rc != SOCKET_ERROR);
    BOOL tcp_nodelay = 1;
    rc = setsockopt (listener, IPPROTO_TCP, TCP_NODELAY,
        (char *)&tcp_nodelay, sizeof (tcp_nodelay));
    wsa_assert (rc != SOCKET_ERROR);

    //  Bind listening socket to any free local port.
    struct sockaddr_in addr;
    memset (&addr, 0, sizeof (addr));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
    addr.sin_port = htons (signaler_port);
    rc = bind (listener, (const struct sockaddr*) &addr, sizeof (addr));
    wsa_assert (rc != SOCKET_ERROR);

    //  Listen for incomming connections.
    rc = listen (listener, 1);
    wsa_assert (rc != SOCKET_ERROR);

    //  Create the writer socket.
    *w_ = WSASocket (AF_INET, SOCK_STREAM, 0, NULL, 0,  0);
    wsa_assert (*w_ != INVALID_SOCKET);

    //  Set TCP_NODELAY on writer socket.
    rc = setsockopt (*w_, IPPROTO_TCP, TCP_NODELAY,
        (char *)&tcp_nodelay, sizeof (tcp_nodelay));
    wsa_assert (rc != SOCKET_ERROR);

    //  Connect writer to the listener.
    rc = connect (*w_, (sockaddr *) &addr, sizeof (addr));
    wsa_assert (rc != SOCKET_ERROR);

    //  Accept connection from writer.
    *r_ = accept (listener, NULL, NULL);
    wsa_assert (*r_ != INVALID_SOCKET);

    //  We don't need the listening socket anymore. Close it.
    rc = closesocket (listener);
    wsa_assert (rc != SOCKET_ERROR);

    //  Exit the critical section.
    BOOL brc = SetEvent (sync);
    win_assert (brc != 0);

    return 0;

#elif defined ZMQ_HAVE_OPENVMS

    //  Whilst OpenVMS supports socketpair - it maps to AF_INET only.  Further,
    //  it does not set the socket options TCP_NODELAY and TCP_NODELACK which
    //  can lead to performance problems.
    //
    //  The bug will be fixed in V5.6 ECO4 and beyond.  In the meantime, we'll
    //  create the socket pair manually.
    sockaddr_in lcladdr;
    memset (&lcladdr, 0, sizeof (lcladdr));
    lcladdr.sin_family = AF_INET;
    lcladdr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
    lcladdr.sin_port = 0;

    int listener = open_socket (AF_INET, SOCK_STREAM, 0);
    errno_assert (listener != -1);

    int on = 1;
    int rc = setsockopt (listener, IPPROTO_TCP, TCP_NODELAY, &on, sizeof (on));
    errno_assert (rc != -1);

    rc = setsockopt (listener, IPPROTO_TCP, TCP_NODELACK, &on, sizeof (on));
    errno_assert (rc != -1);

    rc = bind(listener, (struct sockaddr*) &lcladdr, sizeof (lcladdr));
    errno_assert (rc != -1);

    socklen_t lcladdr_len = sizeof (lcladdr);

    rc = getsockname (listener, (struct sockaddr*) &lcladdr, &lcladdr_len);
    errno_assert (rc != -1);

    rc = listen (listener, 1);
    errno_assert (rc != -1);

    *w_ = open_socket (AF_INET, SOCK_STREAM, 0);
    errno_assert (*w_ != -1);

    rc = setsockopt (*w_, IPPROTO_TCP, TCP_NODELAY, &on, sizeof (on));
    errno_assert (rc != -1);

    rc = setsockopt (*w_, IPPROTO_TCP, TCP_NODELACK, &on, sizeof (on));
    errno_assert (rc != -1);

    rc = connect (*w_, (struct sockaddr*) &lcladdr, sizeof (lcladdr));
    errno_assert (rc != -1);

    *r_ = accept (listener, NULL, NULL);
    errno_assert (*r_ != -1);

    close (listener);

    return 0;

#else // All other implementations support socketpair()

    int sv [2];
    int rc = socketpair (AF_UNIX, SOCK_STREAM, 0, sv);
    errno_assert (rc == 0);
    *w_ = sv [0];
    *r_ = sv [1];
    return 0;

#endif
}
Exemple #24
0
static void download_one_url(const char *url)
{
    bool use_proxy;                 /* Use proxies if env vars are set  */
    int redir_limit;
    len_and_sockaddr *lsa;
    FILE *sfp;                      /* socket to web/ftp server         */
    FILE *dfp;                      /* socket to ftp server (data)      */
    char *proxy = NULL;
    char *fname_out_alloc;
    char *redirected_path = NULL;
    struct host_info server;
    struct host_info target;

    server.allocated = NULL;
    target.allocated = NULL;
    server.user = NULL;
    target.user = NULL;

    parse_url(url, &target);

    /* Use the proxy if necessary */
    use_proxy = (strcmp(G.proxy_flag, "off") != 0);
    if (use_proxy) {
        proxy = getenv(target.is_ftp ? "ftp_proxy" : "http_proxy");
        use_proxy = (proxy && proxy[0]);
        if (use_proxy)
            parse_url(proxy, &server);
    }
    if (!use_proxy) {
        server.port = target.port;
        if (ENABLE_FEATURE_IPV6) {
            //free(server.allocated); - can't be non-NULL
            server.host = server.allocated = xstrdup(target.host);
        } else {
            server.host = target.host;
        }
    }

    if (ENABLE_FEATURE_IPV6)
        strip_ipv6_scope_id(target.host);

    /* If there was no -O FILE, guess output filename */
    fname_out_alloc = NULL;
    if (!(option_mask32 & WGET_OPT_OUTNAME)) {
        G.fname_out = bb_get_last_path_component_nostrip(target.path);
        /* handle "wget http://kernel.org//" */
        if (G.fname_out[0] == '/' || !G.fname_out[0])
            G.fname_out = (char*)"index.html";
        /* -P DIR is considered only if there was no -O FILE */
        else {
            if (G.dir_prefix)
                G.fname_out = fname_out_alloc = concat_path_file(G.dir_prefix, G.fname_out);
            else {
                /* redirects may free target.path later, need to make a copy */
                G.fname_out = fname_out_alloc = xstrdup(G.fname_out);
            }
        }
    }
#if ENABLE_FEATURE_WGET_STATUSBAR
    G.curfile = bb_get_last_path_component_nostrip(G.fname_out);
#endif

    /* Determine where to start transfer */
    G.beg_range = 0;
    if (option_mask32 & WGET_OPT_CONTINUE) {
        G.output_fd = open(G.fname_out, O_WRONLY);
        if (G.output_fd >= 0) {
            G.beg_range = xlseek(G.output_fd, 0, SEEK_END);
        }
        /* File doesn't exist. We do not create file here yet.
         * We are not sure it exists on remote side */
    }

    redir_limit = 5;
resolve_lsa:
    lsa = xhost2sockaddr(server.host, server.port);
    if (!(option_mask32 & WGET_OPT_QUIET)) {
        char *s = xmalloc_sockaddr2dotted(&lsa->u.sa);
        fprintf(stderr, "Connecting to %s (%s)\n", server.host, s);
        free(s);
    }
establish_session:
    /*G.content_len = 0; - redundant, got_clen = 0 is enough */
    G.got_clen = 0;
    G.chunked = 0;
    if (use_proxy || !target.is_ftp) {
        /*
         *  HTTP session
         */
        char *str;
        int status;


        /* Open socket to http server */
        sfp = open_socket(lsa);

        /* Send HTTP request */
        if (use_proxy) {
            fprintf(sfp, "GET %stp://%s/%s HTTP/1.1\r\n",
                    target.is_ftp ? "f" : "ht", target.host,
                    target.path);
        } else {
            if (option_mask32 & WGET_OPT_POST_DATA)
                fprintf(sfp, "POST /%s HTTP/1.1\r\n", target.path);
            else
                fprintf(sfp, "GET /%s HTTP/1.1\r\n", target.path);
        }

        fprintf(sfp, "Host: %s\r\nUser-Agent: %s\r\n",
                target.host, G.user_agent);

        /* Ask server to close the connection as soon as we are done
         * (IOW: we do not intend to send more requests)
         */
        fprintf(sfp, "Connection: close\r\n");

#if ENABLE_FEATURE_WGET_AUTHENTICATION
        if (target.user) {
            fprintf(sfp, "Proxy-Authorization: Basic %s\r\n"+6,
                    base64enc(target.user));
        }
        if (use_proxy && server.user) {
            fprintf(sfp, "Proxy-Authorization: Basic %s\r\n",
                    base64enc(server.user));
        }
#endif

        if (G.beg_range)
            fprintf(sfp, "Range: bytes=%"OFF_FMT"u-\r\n", G.beg_range);

#if ENABLE_FEATURE_WGET_LONG_OPTIONS
        if (G.extra_headers)
            fputs(G.extra_headers, sfp);

        if (option_mask32 & WGET_OPT_POST_DATA) {
            fprintf(sfp,
                    "Content-Type: application/x-www-form-urlencoded\r\n"
                    "Content-Length: %u\r\n"
                    "\r\n"
                    "%s",
                    (int) strlen(G.post_data), G.post_data
                   );
        } else
#endif
        {
            fprintf(sfp, "\r\n");
        }

        fflush(sfp);

        /*
         * Retrieve HTTP response line and check for "200" status code.
         */
read_response:
        fgets_and_trim(sfp);

        str = G.wget_buf;
        str = skip_non_whitespace(str);
        str = skip_whitespace(str);
        // FIXME: no error check
        // xatou wouldn't work: "200 OK"
        status = atoi(str);
        switch (status) {
        case 0:
        case 100:
            while (gethdr(sfp) != NULL)
                /* eat all remaining headers */;
            goto read_response;
        case 200:
        /*
        Response 204 doesn't say "null file", it says "metadata
        has changed but data didn't":

        "10.2.5 204 No Content
        The server has fulfilled the request but does not need to return
        an entity-body, and might want to return updated metainformation.
        The response MAY include new or updated metainformation in the form
        of entity-headers, which if present SHOULD be associated with
        the requested variant.

        If the client is a user agent, it SHOULD NOT change its document
        view from that which caused the request to be sent. This response
        is primarily intended to allow input for actions to take place
        without causing a change to the user agent's active document view,
        although any new or updated metainformation SHOULD be applied
        to the document currently in the user agent's active view.

        The 204 response MUST NOT include a message-body, and thus
        is always terminated by the first empty line after the header fields."

        However, in real world it was observed that some web servers
        (e.g. Boa/0.94.14rc21) simply use code 204 when file size is zero.
        */
        case 204:
            break;
        case 300:  /* redirection */
        case 301:
        case 302:
        case 303:
            break;
        case 206:
            if (G.beg_range)
                break;
        /* fall through */
        default:
            bb_error_msg_and_die("server returned error: %s", sanitize_string(G.wget_buf));
        }

        /*
         * Retrieve HTTP headers.
         */
        while ((str = gethdr(sfp)) != NULL) {
            static const char keywords[] ALIGN1 =
                "content-length\0""transfer-encoding\0""location\0";
            enum {
                KEY_content_length = 1, KEY_transfer_encoding, KEY_location
            };
            smalluint key;

            /* gethdr converted "FOO:" string to lowercase */

            /* strip trailing whitespace */
            char *s = strchrnul(str, '\0') - 1;
            while (s >= str && (*s == ' ' || *s == '\t')) {
                *s = '\0';
                s--;
            }
            key = index_in_strings(keywords, G.wget_buf) + 1;
            if (key == KEY_content_length) {
                G.content_len = BB_STRTOOFF(str, NULL, 10);
                if (G.content_len < 0 || errno) {
                    bb_error_msg_and_die("content-length %s is garbage", sanitize_string(str));
                }
                G.got_clen = 1;
                continue;
            }
            if (key == KEY_transfer_encoding) {
                if (strcmp(str_tolower(str), "chunked") != 0)
                    bb_error_msg_and_die("transfer encoding '%s' is not supported", sanitize_string(str));
                G.chunked = 1;
            }
            if (key == KEY_location && status >= 300) {
                if (--redir_limit == 0)
                    bb_error_msg_and_die("too many redirections");
                fclose(sfp);
                if (str[0] == '/') {
                    free(redirected_path);
                    target.path = redirected_path = xstrdup(str+1);
                    /* lsa stays the same: it's on the same server */
                } else {
                    parse_url(str, &target);
                    if (!use_proxy) {
                        free(server.allocated);
                        server.allocated = NULL;
                        server.host = target.host;
                        /* strip_ipv6_scope_id(target.host); - no! */
                        /* we assume remote never gives us IPv6 addr with scope id */
                        server.port = target.port;
                        free(lsa);
                        goto resolve_lsa;
                    } /* else: lsa stays the same: we use proxy */
                }
                goto establish_session;
            }
        }
//		if (status >= 300)
//			bb_error_msg_and_die("bad redirection (no Location: header from server)");

        /* For HTTP, data is pumped over the same connection */
        dfp = sfp;

    } else {
Exemple #25
0
int zmq::tcp_listener_t::set_address (const char *addr_)
{
    //  Convert the textual address into address structure.
    int rc = address.resolve (addr_, true, options.ipv6);
    if (rc != 0)
        return -1;

    address.to_string (endpoint);

    if (options.use_fd != -1) {
        s = options.use_fd;
        socket->event_listening (endpoint, (int) s);
        return 0;
    }

    //  Create a listening socket.
    s = open_socket (address.family (), SOCK_STREAM, IPPROTO_TCP);

    //  IPv6 address family not supported, try automatic downgrade to IPv4.
    if (s == zmq::retired_fd && address.family () == AF_INET6
        && errno == EAFNOSUPPORT && options.ipv6) {
        rc = address.resolve (addr_, true, false);
        if (rc != 0)
            return rc;
        s = open_socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
    }

#ifdef ZMQ_HAVE_WINDOWS
    if (s == INVALID_SOCKET) {
        errno = wsa_error_to_errno (WSAGetLastError ());
        return -1;
    }
#if !defined _WIN32_WCE && !defined ZMQ_HAVE_WINDOWS_UWP
    //  On Windows, preventing sockets to be inherited by child processes.
    BOOL brc = SetHandleInformation ((HANDLE) s, HANDLE_FLAG_INHERIT, 0);
    win_assert (brc);
#endif
#else
    if (s == -1)
        return -1;
#endif

    //  On some systems, IPv4 mapping in IPv6 sockets is disabled by default.
    //  Switch it on in such cases.
    if (address.family () == AF_INET6)
        enable_ipv4_mapping (s);

    // Set the IP Type-Of-Service for the underlying socket
    if (options.tos != 0)
        set_ip_type_of_service (s, options.tos);

    // Set the socket to loopback fastpath if configured.
    if (options.loopback_fastpath)
        tcp_tune_loopback_fast_path (s);

    // Bind the socket to a device if applicable
    if (!options.bound_device.empty ())
        bind_to_device (s, options.bound_device);

    //  Set the socket buffer limits for the underlying socket.
    if (options.sndbuf >= 0)
        set_tcp_send_buffer (s, options.sndbuf);
    if (options.rcvbuf >= 0)
        set_tcp_receive_buffer (s, options.rcvbuf);

    //  Allow reusing of the address.
    int flag = 1;
#ifdef ZMQ_HAVE_WINDOWS
    rc = setsockopt (s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (const char *) &flag,
                     sizeof (int));
    wsa_assert (rc != SOCKET_ERROR);
#else
    rc = setsockopt (s, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof (int));
    errno_assert (rc == 0);
#endif

    //  Bind the socket to the network interface and port.
    rc = bind (s, address.addr (), address.addrlen ());
#ifdef ZMQ_HAVE_WINDOWS
    if (rc == SOCKET_ERROR) {
        errno = wsa_error_to_errno (WSAGetLastError ());
        goto error;
    }
#else
    if (rc != 0)
        goto error;
#endif

    //  Listen for incoming connections.
    rc = listen (s, options.backlog);
#ifdef ZMQ_HAVE_WINDOWS
    if (rc == SOCKET_ERROR) {
        errno = wsa_error_to_errno (WSAGetLastError ());
        goto error;
    }
#else
    if (rc != 0)
        goto error;
#endif

    socket->event_listening (endpoint, (int) s);
    return 0;

error:
    int err = errno;
    close ();
    errno = err;
    return -1;
}
Exemple #26
0
/* This state machine is based on the one from udhcpc
   written by Russ Dill */
int dhcp_run (options_t *options)
{
  interface_t *iface;
  int mode = SOCKET_CLOSED;
  int state = STATE_INIT;
  struct timeval tv;
  int xid = 0;
  long timeout = 0;
  fd_set rset;
  int maxfd;
  int retval;
  dhcpmessage_t message;
  dhcp_t *dhcp;
  int type = DHCP_DISCOVER;
  int last_type = DHCP_DISCOVER;
  bool daemonised = false;
  unsigned long start = 0;
  unsigned long last_send = 0;
  int sig;
  unsigned char *buffer = NULL;
  int buffer_len = 0;
  int buffer_pos = 0;

  if (! options || (iface = (read_interface (options->interface,
					     options->metric))) == NULL)
    return -1;

  /* Remove all existing addresses.
     After all, we ARE a DHCP client whose job it is to configure the
     interface. We only do this on start, so persistent addresses can be added
     afterwards by the user if needed. */
  flush_addresses (iface->name);

  dhcp = xmalloc (sizeof (dhcp_t));
  memset (dhcp, 0, sizeof (dhcp_t));

  strcpy (dhcp->classid, options->classid);
  if (options->clientid[0])
    strcpy (dhcp->clientid, options->clientid);
  else
    sprintf (dhcp->clientid, "%s", ether_ntoa (&iface->ethernet_address));

  if (options->requestaddress.s_addr != 0)
    dhcp->address.s_addr = options->requestaddress.s_addr;

  signal_setup ();

  while (1)
    {
      if (timeout > 0 || (options->timeout == 0 &&
			  (state != STATE_INIT || xid)))
	{
	  if (options->timeout == 0 || dhcp->leasetime == -1)
	    {
	      logger (LOG_DEBUG, "waiting on select for infinity");
	      maxfd = signal_fd_set (&rset, iface->fd);
	      retval = select (maxfd + 1, &rset, NULL, NULL, NULL);
	    }
	  else
	    {
	      /* Resend our message if we're getting loads of packets
		 that aren't for us. This mainly happens on Linux as it
		 doesn't have a nice BPF filter. */
	      if (iface->fd > -1 && uptime () - last_send >= TIMEOUT_MINI)
		SEND_MESSAGE (last_type);

	      logger (LOG_DEBUG, "waiting on select for %d seconds",
		      timeout);
	      /* If we're waiting for a reply, then we re-send the last
		 DHCP request periodically in-case of a bad line */
	      retval = 0;
	      while (timeout > 0 && retval == 0)
		{
		  if (iface->fd == -1)
		    tv.tv_sec = SELECT_MAX;
		  else
		    tv.tv_sec = TIMEOUT_MINI;
		  if (timeout < tv.tv_sec)
		    tv.tv_sec = timeout;
		  tv.tv_usec = 0;
		  start = uptime ();
		  maxfd = signal_fd_set (&rset, iface->fd);
		  retval = select (maxfd + 1, &rset, NULL, NULL, &tv);
		  timeout -= uptime () - start;
		  if (retval == 0 && iface->fd != -1 && timeout > 0)
		    SEND_MESSAGE (last_type);
		}
	    }
	}
      else
	retval = 0;

      /* We should always handle our signals first */
      if (retval > 0 && (sig = signal_read (&rset)))
	{
	  switch (sig)
	    {
	    case SIGINT:
	      logger (LOG_INFO, "receieved SIGINT, stopping");
	      retval = 0;
	      goto eexit;

	    case SIGTERM:
	      logger (LOG_INFO, "receieved SIGTERM, stopping");
	      retval = 0;
	      goto eexit;

	    case SIGALRM:

	      logger (LOG_INFO, "receieved SIGALRM, renewing lease");
	      switch (state)
		{
		case STATE_BOUND:
		case STATE_RENEWING:
		case STATE_REBINDING:
		  state = STATE_RENEW_REQUESTED;
		  break;
		case STATE_RENEW_REQUESTED:
		case STATE_REQUESTING:
		case STATE_RELEASED:
		  state = STATE_INIT;
		  break;
		}

	      timeout = 0;
	      xid = 0;
	      break;

	    case SIGHUP:
	      if (state == STATE_BOUND || state == STATE_RENEWING
		  || state == STATE_REBINDING)
		{
		  logger (LOG_INFO, "received SIGHUP, releasing lease");
		  SOCKET_MODE (SOCKET_OPEN);
		  xid = random_xid ();
		  if ((open_socket (iface, false)) >= 0)
		    SEND_MESSAGE (DHCP_RELEASE);
		  SOCKET_MODE (SOCKET_CLOSED);
		  unlink (iface->infofile);
		}
	      else
		logger (LOG_ERR,
			"receieved SIGUP, but no we have lease to release");
	      retval = 0;
	      goto eexit;

	    default:
	      logger (LOG_ERR,
		      "received signal %d, but don't know what to do with it",
		      sig);
	    }
	}
      else if (retval == 0) /* timed out */
	{
	  switch (state)
	    {
	    case STATE_INIT:
	      if (iface->previous_address.s_addr != 0)
		{
		  logger (LOG_ERR, "lost lease");
		  xid = 0;
		  SOCKET_MODE (SOCKET_CLOSED);
		  if (! options->persistent)
		    {
		      free_dhcp (dhcp);
		      memset (dhcp, 0, sizeof (dhcp_t));
		      configure (options, iface, dhcp);
		    }
		  if (! daemonised)
		    {
		      retval = -1;
		      goto eexit;
		    }
		  break;
		}

	      if (xid == 0)
		xid = random_xid ();
	      else
		{
		  logger (LOG_ERR, "timed out");
		  if (! daemonised)
		    {
		      retval = -1;
		      goto eexit;
		    }
		}

	      SOCKET_MODE (SOCKET_OPEN);
	      timeout = options->timeout;
	      iface->start_uptime = uptime ();
	      if (dhcp->address.s_addr == 0)
		{
		  logger (LOG_INFO, "broadcasting for a lease");
		  SEND_MESSAGE (DHCP_DISCOVER);
		}
	      else
		{
		  logger (LOG_INFO, "broadcasting for a lease of %s",
			  inet_ntoa (dhcp->address));
		  SEND_MESSAGE (DHCP_REQUEST);
		  state = STATE_REQUESTING;
		}

	      break;
	    case STATE_BOUND:
	    case STATE_RENEW_REQUESTED:
	      state = STATE_RENEWING;
	      xid = random_xid ();
	    case STATE_RENEWING:
	      iface->start_uptime = uptime ();
	      logger (LOG_INFO, "renewing lease of %s", inet_ntoa
		      (dhcp->address));
	      SOCKET_MODE (SOCKET_OPEN);
	      SEND_MESSAGE (DHCP_REQUEST);
	      timeout = dhcp->rebindtime - dhcp->renewaltime;
	      state = STATE_REBINDING;
	      break;
	    case STATE_REBINDING:
	      logger (LOG_ERR, "lost lease, attemping to rebind");
	      SOCKET_MODE (SOCKET_OPEN);
	      SEND_MESSAGE (DHCP_DISCOVER);
	      timeout = dhcp->leasetime - dhcp->rebindtime;
	      state = STATE_INIT;
	      break;
	    case STATE_REQUESTING:
	      logger (LOG_ERR, "timed out");
	      if (! daemonised)
		goto eexit;

	      state = STATE_INIT;
	      SOCKET_MODE (SOCKET_CLOSED);
	      timeout = 0;
	      xid = 0;
	      free_dhcp (dhcp);
	      memset (dhcp, 0, sizeof (dhcp_t));
	      break;

	    case STATE_RELEASED:
	      dhcp->leasetime = -1;
	      break;
	    }
	}
      else if (retval > 0 && mode != SOCKET_CLOSED && FD_ISSET(iface->fd, &rset))
	{

	  /* Allocate our buffer space for BPF.
	     We cannot do this until we have opened our socket as we don't
	     know how much of a buffer we need until then. */
	  if (! buffer)
	    buffer = xmalloc (iface->buffer_length);
	  buffer_len = iface->buffer_length;
	  buffer_pos = -1;

	  /* We loop through until our buffer is empty.
	     The benefit is that if we get >1 DHCP packet in our buffer and
	     the first one fails for any reason, we can use the next. */

	  memset (&message, 0, sizeof (struct dhcpmessage_t));
	  int valid = 0;
	  struct dhcp_t *new_dhcp;
	  new_dhcp = xmalloc (sizeof (dhcp_t));

	  while (buffer_pos != 0)
	    {
	      if (get_packet (iface, (unsigned char *) &message, buffer,
			      &buffer_len, &buffer_pos) < 0)
		break;

	      if (xid != message.xid)
		{
		  logger (LOG_ERR,
			  "ignoring packet with xid %d as it's not ours (%d)",
			  message.xid, xid);
		  continue;
		}

	      logger (LOG_DEBUG, "got a packet with xid %d", message.xid);
	      memset (new_dhcp, 0, sizeof (dhcp_t));
	      if ((type = parse_dhcpmessage (new_dhcp, &message)) < 0)
		{
		  logger (LOG_ERR, "failed to parse packet");
		  free_dhcp (new_dhcp);
		  continue;
		}

	      /* If we got here then the DHCP packet is valid and appears to
		 be for us, so let's clear the buffer as we don't care about
		 any more DHCP packets at this point. */
	      valid = 1;
	      break;
	    }

	  /* No packets for us, so wait until we get one */
	  if (! valid)
	    {
	      free (new_dhcp);
	      continue;
	    }

	  /* new_dhcp is now our master DHCP message */
	  free_dhcp (dhcp);
	  free (dhcp);
	  dhcp = new_dhcp;
	  new_dhcp = NULL;

	  /* We should restart on a NAK */
	  if (type == DHCP_NAK)
	    {
	      logger (LOG_INFO, "received NAK: %s", dhcp->message);
	      state = STATE_INIT;
	      timeout = 0;
	      xid = 0;
	      free_dhcp (dhcp);
	      memset (dhcp, 0, sizeof (dhcp_t));
	      configure (options, iface, dhcp);
	      continue;
	    }

	  switch (state)
	    {
	    case STATE_INIT:
	      if (type == DHCP_OFFER)
		{
		  logger (LOG_INFO, "offered lease of %s",
			  inet_ntoa (dhcp->address));

		  SEND_MESSAGE (DHCP_REQUEST);
		  state = STATE_REQUESTING;
		}
	      break;

	    case STATE_RENEW_REQUESTED:
	    case STATE_REQUESTING:
	    case STATE_RENEWING:
	    case STATE_REBINDING:
	      if (type == DHCP_ACK)
		{
		  SOCKET_MODE (SOCKET_CLOSED);
		  if (options->doarp && iface->previous_address.s_addr !=
		      dhcp->address.s_addr)
		    {
		      if (arp_check (iface, dhcp->address))
			{
			  SOCKET_MODE (SOCKET_OPEN);
			  SEND_MESSAGE (DHCP_DECLINE);
			  SOCKET_MODE (SOCKET_CLOSED);
			  free_dhcp (dhcp);
			  memset (dhcp, 0, sizeof (dhcp));
			  if (daemonised)
			    configure (options, iface, dhcp);

			  xid = 0;
			  state = STATE_INIT;
			  /* RFC 2131 says that we should wait for 10 seconds
			     before doing anything else */
			  sleep (10);
			  continue;
			}
		    }

		  if (! dhcp->leasetime)
		    {
		      dhcp->leasetime = DEFAULT_TIMEOUT;
		      logger(LOG_INFO,
			     "no lease time supplied, assuming %d seconds",
			     dhcp->leasetime);
		    }

		  if (! dhcp->renewaltime) 
		    {
		      dhcp->renewaltime = dhcp->leasetime / 2;
		      logger (LOG_INFO,
			      "no renewal time supplied, assuming %d seconds",
			      dhcp->renewaltime);
		    }

		  if (! dhcp->rebindtime)
		    {
		      dhcp->rebindtime = (dhcp->leasetime * 0x7) >> 3;
		      logger (LOG_INFO,
			      "no rebind time supplied, assuming %d seconds",
			      dhcp->rebindtime);
		    }

		  if (dhcp->leasetime == -1)
		    logger (LOG_INFO, "leased %s for infinity",
			    inet_ntoa (dhcp->address));
		  else
		    logger (LOG_INFO, "leased %s for %u seconds",
			    inet_ntoa (dhcp->address),
			    dhcp->leasetime, dhcp->renewaltime);

		  state = STATE_BOUND;
		  timeout = dhcp->renewaltime;
		  xid = 0;

		  if (configure (options, iface, dhcp) < 0 && ! daemonised)
		    {
		      retval = -1;
		      goto eexit;
		    }

		  if (! daemonised)
		    {
		      if ((daemonise (options->pidfile)) < 0 )
			{
			  retval = -1;
			  goto eexit;
			}
		      daemonised = true;
		    }
		}
	      else if (type == DHCP_OFFER)
		logger (LOG_INFO, "got subsequent offer of %s, ignoring ",
			inet_ntoa (dhcp->address));
	      else
		logger (LOG_ERR,
			"no idea what to do with DHCP type %d at this point",
			type);
	      break;
	    }
int wget_main(int argc UNUSED_PARAM, char **argv)
{
	char buf[512];
	struct host_info server, target;
	len_and_sockaddr *lsa;
	unsigned opt;
	int redir_limit;
	char *proxy = NULL;
	char *dir_prefix = NULL;
#if ENABLE_FEATURE_WGET_LONG_OPTIONS
	char *post_data;
	char *extra_headers = NULL;
	llist_t *headers_llist = NULL;
#endif
	FILE *sfp;                      /* socket to web/ftp server         */
	FILE *dfp;                      /* socket to ftp server (data)      */
	char *fname_out;                /* where to direct output (-O)      */
	int output_fd = -1;
	bool use_proxy;                 /* Use proxies if env vars are set  */
	const char *proxy_flag = "on";  /* Use proxies if env vars are set  */
	const char *user_agent = "Wget";/* "User-Agent" header field        */

	static const char keywords[] ALIGN1 =
		"content-length\0""transfer-encoding\0""chunked\0""location\0";
	enum {
		KEY_content_length = 1, KEY_transfer_encoding, KEY_chunked, KEY_location
	};
#if ENABLE_FEATURE_WGET_LONG_OPTIONS
	static const char wget_longopts[] ALIGN1 =
		/* name, has_arg, val */
		"continue\0"         No_argument       "c"
		"spider\0"           No_argument       "s"
		"quiet\0"            No_argument       "q"
		"output-document\0"  Required_argument "O"
		"directory-prefix\0" Required_argument "P"
		"proxy\0"            Required_argument "Y"
		"user-agent\0"       Required_argument "U"
		/* Ignored: */
		// "tries\0"            Required_argument "t"
		// "timeout\0"          Required_argument "T"
		/* Ignored (we always use PASV): */
		"passive-ftp\0"      No_argument       "\xff"
		"header\0"           Required_argument "\xfe"
		"post-data\0"        Required_argument "\xfd"
		;
#endif

	INIT_G();

#if ENABLE_FEATURE_WGET_LONG_OPTIONS
	applet_long_options = wget_longopts;
#endif
	/* server.allocated = target.allocated = NULL; */
	opt_complementary = "-1" IF_FEATURE_WGET_LONG_OPTIONS(":\xfe::");
	opt = getopt32(argv, "csqO:P:Y:U:" /*ignored:*/ "t:T:",
				&fname_out, &dir_prefix,
				&proxy_flag, &user_agent,
				NULL, /* -t RETRIES */
				NULL /* -T NETWORK_READ_TIMEOUT */
				IF_FEATURE_WGET_LONG_OPTIONS(, &headers_llist)
				IF_FEATURE_WGET_LONG_OPTIONS(, &post_data)
				);
#if ENABLE_FEATURE_WGET_LONG_OPTIONS
	if (headers_llist) {
		int size = 1;
		char *cp;
		llist_t *ll = headers_llist;
		while (ll) {
			size += strlen(ll->data) + 2;
			ll = ll->link;
		}
		extra_headers = cp = xmalloc(size);
		while (headers_llist) {
			cp += sprintf(cp, "%s\r\n", (char*)llist_pop(&headers_llist));
		}
	}
#endif

	/* TODO: compat issue: should handle "wget URL1 URL2..." */

	target.user = NULL;
	parse_url(argv[optind], &target);

	/* Use the proxy if necessary */
	use_proxy = (strcmp(proxy_flag, "off") != 0);
	if (use_proxy) {
		proxy = getenv(target.is_ftp ? "ftp_proxy" : "http_proxy");
		if (proxy && proxy[0]) {
			parse_url(proxy, &server);
		} else {
			use_proxy = 0;
		}
	}
	if (!use_proxy) {
		server.port = target.port;
		if (ENABLE_FEATURE_IPV6) {
			server.host = xstrdup(target.host);
		} else {
			server.host = target.host;
		}
	}

	if (ENABLE_FEATURE_IPV6)
		strip_ipv6_scope_id(target.host);

	/* Guess an output filename, if there was no -O FILE */
	if (!(opt & WGET_OPT_OUTNAME)) {
		fname_out = bb_get_last_path_component_nostrip(target.path);
		/* handle "wget http://kernel.org//" */
		if (fname_out[0] == '/' || !fname_out[0])
			fname_out = (char*)"index.html";
		/* -P DIR is considered only if there was no -O FILE */
		if (dir_prefix)
			fname_out = concat_path_file(dir_prefix, fname_out);
	} else {
		if (LONE_DASH(fname_out)) {
			/* -O - */
			output_fd = 1;
			opt &= ~WGET_OPT_CONTINUE;
		}
	}
#if ENABLE_FEATURE_WGET_STATUSBAR
	G.curfile = bb_get_last_path_component_nostrip(fname_out);
#endif

	/* Impossible?
	if ((opt & WGET_OPT_CONTINUE) && !fname_out)
		bb_error_msg_and_die("can't specify continue (-c) without a filename (-O)");
	*/

	/* Determine where to start transfer */
	if (opt & WGET_OPT_CONTINUE) {
		output_fd = open(fname_out, O_WRONLY);
		if (output_fd >= 0) {
			G.beg_range = xlseek(output_fd, 0, SEEK_END);
		}
		/* File doesn't exist. We do not create file here yet.
		 * We are not sure it exists on remove side */
	}

	redir_limit = 5;
 resolve_lsa:
	lsa = xhost2sockaddr(server.host, server.port);
	if (!(opt & WGET_OPT_QUIET)) {
		char *s = xmalloc_sockaddr2dotted(&lsa->u.sa);
		fprintf(stderr, "Connecting to %s (%s)\n", server.host, s);
		free(s);
	}
 establish_session:
	if (use_proxy || !target.is_ftp) {
		/*
		 *  HTTP session
		 */
		char *str;
		int status;

		/* Open socket to http server */
		sfp = open_socket(lsa);

		/* Send HTTP request */
		if (use_proxy) {
			fprintf(sfp, "GET %stp://%s/%s HTTP/1.1\r\n",
				target.is_ftp ? "f" : "ht", target.host,
				target.path);
		} else {
			if (opt & WGET_OPT_POST_DATA)
				fprintf(sfp, "POST /%s HTTP/1.1\r\n", target.path);
			else
				fprintf(sfp, "GET /%s HTTP/1.1\r\n", target.path);
		}

		fprintf(sfp, "Host: %s\r\nUser-Agent: %s\r\n",
			target.host, user_agent);

#if ENABLE_FEATURE_WGET_AUTHENTICATION
		if (target.user) {
			fprintf(sfp, "Proxy-Authorization: Basic %s\r\n"+6,
				base64enc_512(buf, target.user));
		}
		if (use_proxy && server.user) {
			fprintf(sfp, "Proxy-Authorization: Basic %s\r\n",
				base64enc_512(buf, server.user));
		}
#endif

		if (G.beg_range)
			fprintf(sfp, "Range: bytes=%"OFF_FMT"u-\r\n", G.beg_range);
#if ENABLE_FEATURE_WGET_LONG_OPTIONS
		if (extra_headers)
			fputs(extra_headers, sfp);

		if (opt & WGET_OPT_POST_DATA) {
			char *estr = URL_escape(post_data);
			fprintf(sfp, "Content-Type: application/x-www-form-urlencoded\r\n");
			fprintf(sfp, "Content-Length: %u\r\n" "\r\n" "%s",
					(int) strlen(estr), estr);
			/*fprintf(sfp, "Connection: Keep-Alive\r\n\r\n");*/
			/*fprintf(sfp, "%s\r\n", estr);*/
			free(estr);
		} else
#endif
		{ /* If "Connection:" is needed, document why */
			fprintf(sfp, /* "Connection: close\r\n" */ "\r\n");
		}

		/*
		 * Retrieve HTTP response line and check for "200" status code.
		 */
 read_response:
		if (fgets(buf, sizeof(buf), sfp) == NULL)
			bb_error_msg_and_die("no response from server");

		str = buf;
		str = skip_non_whitespace(str);
		str = skip_whitespace(str);
		// FIXME: no error check
		// xatou wouldn't work: "200 OK"
		status = atoi(str);
		switch (status) {
		case 0:
		case 100:
			while (gethdr(buf, sizeof(buf), sfp /*, &n*/) != NULL)
				/* eat all remaining headers */;
			goto read_response;
		case 200:
/*
Response 204 doesn't say "null file", it says "metadata
has changed but data didn't":

"10.2.5 204 No Content
The server has fulfilled the request but does not need to return
an entity-body, and might want to return updated metainformation.
The response MAY include new or updated metainformation in the form
of entity-headers, which if present SHOULD be associated with
the requested variant.

If the client is a user agent, it SHOULD NOT change its document
view from that which caused the request to be sent. This response
is primarily intended to allow input for actions to take place
without causing a change to the user agent's active document view,
although any new or updated metainformation SHOULD be applied
to the document currently in the user agent's active view.

The 204 response MUST NOT include a message-body, and thus
is always terminated by the first empty line after the header fields."

However, in real world it was observed that some web servers
(e.g. Boa/0.94.14rc21) simply use code 204 when file size is zero.
*/
		case 204:
			break;
		case 300:	/* redirection */
		case 301:
		case 302:
		case 303:
			break;
		case 206:
			if (G.beg_range)
				break;
			/* fall through */
		default:
			bb_error_msg_and_die("server returned error: %s", sanitize_string(buf));
		}

		/*
		 * Retrieve HTTP headers.
		 */
		while ((str = gethdr(buf, sizeof(buf), sfp /*, &n*/)) != NULL) {
			/* gethdr converted "FOO:" string to lowercase */
			smalluint key;
			/* strip trailing whitespace */
			char *s = strchrnul(str, '\0') - 1;
			while (s >= str && (*s == ' ' || *s == '\t')) {
				*s = '\0';
				s--;
			}
			key = index_in_strings(keywords, buf) + 1;
			if (key == KEY_content_length) {
				G.content_len = BB_STRTOOFF(str, NULL, 10);
				if (G.content_len < 0 || errno) {
					bb_error_msg_and_die("content-length %s is garbage", sanitize_string(str));
				}
				G.got_clen = 1;
				continue;
			}
			if (key == KEY_transfer_encoding) {
				if (index_in_strings(keywords, str_tolower(str)) + 1 != KEY_chunked)
					bb_error_msg_and_die("transfer encoding '%s' is not supported", sanitize_string(str));
				G.chunked = G.got_clen = 1;
			}
			if (key == KEY_location && status >= 300) {
				if (--redir_limit == 0)
					bb_error_msg_and_die("too many redirections");
				fclose(sfp);
				G.got_clen = 0;
				G.chunked = 0;
				if (str[0] == '/')
					/* free(target.allocated); */
					target.path = /* target.allocated = */ xstrdup(str+1);
					/* lsa stays the same: it's on the same server */
				else {
					parse_url(str, &target);
					if (!use_proxy) {
						server.host = target.host;
						/* strip_ipv6_scope_id(target.host); - no! */
						/* we assume remote never gives us IPv6 addr with scope id */
						server.port = target.port;
						free(lsa);
						goto resolve_lsa;
					} /* else: lsa stays the same: we use proxy */
				}
				goto establish_session;
			}
		}
//		if (status >= 300)
//			bb_error_msg_and_die("bad redirection (no Location: header from server)");

		/* For HTTP, data is pumped over the same connection */
		dfp = sfp;

	} else {
		/*
		 *  FTP session
		 */
		sfp = prepare_ftp_session(&dfp, &target, lsa);
	}

	if (opt & WGET_OPT_SPIDER) {
		if (ENABLE_FEATURE_CLEAN_UP)
			fclose(sfp);
		return EXIT_SUCCESS;
	}

	if (output_fd < 0) {
		int o_flags = O_WRONLY | O_CREAT | O_TRUNC | O_EXCL;
		/* compat with wget: -O FILE can overwrite */
		if (opt & WGET_OPT_OUTNAME)
			o_flags = O_WRONLY | O_CREAT | O_TRUNC;
		output_fd = xopen(fname_out, o_flags);
	}

	retrieve_file_data(dfp, output_fd);
	xclose(output_fd);

	if (dfp != sfp) {
		/* It's ftp. Close it properly */
		fclose(dfp);
		if (ftpcmd(NULL, NULL, sfp, buf) != 226)
			bb_error_msg_and_die("ftp error: %s", sanitize_string(buf+4));
		/* ftpcmd("QUIT", NULL, sfp, buf); - why bother? */
	}

	return EXIT_SUCCESS;
}
Exemple #28
0
int zmq::tcp_listener_t::set_address (const char *addr_)
{
    //  Convert the textual address into address structure.
    int rc = address.resolve (addr_, true, options.ipv4only ? true : false);
    if (rc != 0)
        return -1;

    //  Create a listening socket.
    s = open_socket (address.family (), SOCK_STREAM, IPPROTO_TCP);
#ifdef ZMQ_HAVE_WINDOWS
    if (s == INVALID_SOCKET)
        errno = wsa_error_to_errno (WSAGetLastError ());
#endif

    //  IPv6 address family not supported, try automatic downgrade to IPv4.
    if (address.family () == AF_INET6 && errno == EAFNOSUPPORT &&
          !options.ipv4only) {
        rc = address.resolve (addr_, true, true);
        if (rc != 0)
            return rc;
        s = ::socket (address.family (), SOCK_STREAM, IPPROTO_TCP);
    }

#ifdef ZMQ_HAVE_WINDOWS
    if (s == INVALID_SOCKET) {
        errno = wsa_error_to_errno (WSAGetLastError ());
        return -1;
    }
    //  On Windows, preventing sockets to be inherited by child processes.
    BOOL brc = SetHandleInformation ((HANDLE) s, HANDLE_FLAG_INHERIT, 0);
    win_assert (brc);
#else
    if (s == -1)
        return -1;
#endif

    //  On some systems, IPv4 mapping in IPv6 sockets is disabled by default.
    //  Switch it on in such cases.
    if (address.family () == AF_INET6)
        enable_ipv4_mapping (s);

    //  Allow reusing of the address.
    int flag = 1;
#ifdef ZMQ_HAVE_WINDOWS
    rc = setsockopt (s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE,
        (const char*) &flag, sizeof (int));
    wsa_assert (rc != SOCKET_ERROR);
#else
    rc = setsockopt (s, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof (int));
    errno_assert (rc == 0);
#endif

    address.to_string (endpoint);

    //  Bind the socket to the network interface and port.
    rc = bind (s, address.addr (), address.addrlen ());
#ifdef ZMQ_HAVE_WINDOWS
    if (rc == SOCKET_ERROR) {
        errno = wsa_error_to_errno (WSAGetLastError ());
        return -1;
    }
#else
    if (rc != 0)
        return -1;
#endif

    //  Listen for incomming connections.
    rc = listen (s, options.backlog);
#ifdef ZMQ_HAVE_WINDOWS
    if (rc == SOCKET_ERROR) {
        errno = wsa_error_to_errno (WSAGetLastError ());
        return -1;
    }
#else
    if (rc != 0)
        return -1;
#endif

    socket->monitor_event (ZMQ_EVENT_LISTENING, addr_, s);
    return 0;
}
Exemple #29
0
SOCKET sbbs_t::ftp_data_sock(csi_t* csi, SOCKET ctrl_sock, SOCKADDR_IN* addr)
{
	char		cmd[512];
	char		rsp[512];
	char*		p;
	socklen_t	addr_len;
	SOCKET		data_sock;
	int			ip_b[4];
	int			port_b[2];
	union {
		DWORD	dw;
		BYTE	b[sizeof(DWORD)];
	} ip_addr;
	union {
		WORD	w;
		BYTE	b[sizeof(WORD)];
	} port;

	if(csi->ftp_mode&CS_FTP_ASCII)
		strcpy(cmd,"TYPE A");
	else	/* BINARY */
		strcpy(cmd,"TYPE I");
	if(!ftp_cmd(csi,ctrl_sock,cmd,rsp) 
		|| atoi(rsp)!=200) {
		return(INVALID_SOCKET);
	}

	if((data_sock=open_socket(SOCK_STREAM, "ftp"))==INVALID_SOCKET) {
		csi->socket_error=ERROR_VALUE;
		return(INVALID_SOCKET);
	}

	memset(addr,0,sizeof(SOCKADDR_IN));
	addr->sin_addr.s_addr = htonl(startup->outgoing4.s_addr);
	addr->sin_family = AF_INET;

	if(bind(data_sock, (struct sockaddr *)addr,xp_sockaddr_len(addr))!= 0) {
		csi->socket_error=ERROR_VALUE;
		close_socket(data_sock);
		return(INVALID_SOCKET);
	}
	
	if(csi->ftp_mode&CS_FTP_PASV) {

		if(!ftp_cmd(csi,ctrl_sock,"PASV",rsp) 
			|| atoi(rsp)!=227 /* PASV response */) {
			bprintf("ftp: failure, line %d",__LINE__);
			close_socket(data_sock);
			return(INVALID_SOCKET);
		}

		p=strchr(rsp,'(');
		if(p==NULL) {
			bprintf("ftp: failure, line %d",__LINE__);
			close_socket(data_sock);
			return(INVALID_SOCKET);
		}
		p++;
		if(sscanf(p,"%u,%u,%u,%u,%u,%u"
			,&ip_b[0],&ip_b[1],&ip_b[2],&ip_b[3]
			,&port_b[0],&port_b[1])!=6) {
			bprintf("ftp: failure, line %d",__LINE__);
			close_socket(data_sock);
			return(INVALID_SOCKET);
		}

		ip_addr.b[0]=ip_b[0];	ip_addr.b[1]=ip_b[1];
		ip_addr.b[2]=ip_b[2];	ip_addr.b[3]=ip_b[3];
		port.b[0]=port_b[0];	port.b[1]=port_b[1];

		addr->sin_addr.s_addr=ip_addr.dw;
		addr->sin_port=port.w;

	} else {	/* Normal (Active) FTP */

		addr_len=sizeof(SOCKADDR_IN);
		if(getsockname(data_sock, (struct sockaddr *)addr,&addr_len)!=0) {
			csi->socket_error=ERROR_VALUE;
			close_socket(data_sock);
			return(INVALID_SOCKET);
		} 

		SOCKADDR_IN ctrl_addr;
		addr_len=sizeof(ctrl_addr);
		if(getsockname(ctrl_sock, (struct sockaddr *)&ctrl_addr,&addr_len)!=0) {
			csi->socket_error=ERROR_VALUE;
			close_socket(data_sock);
			return(INVALID_SOCKET);
		} 

		if(listen(data_sock, 1)!= 0) {
			csi->socket_error=ERROR_VALUE;
			close_socket(data_sock);
			return(INVALID_SOCKET);
		}

		ip_addr.dw=ntohl(ctrl_addr.sin_addr.s_addr);
		port.w=ntohs(addr->sin_port);
		sprintf(cmd,"PORT %u,%u,%u,%u,%u,%u"
			,ip_addr.b[3]
			,ip_addr.b[2]
			,ip_addr.b[1]
			,ip_addr.b[0]
			,port.b[1]
			,port.b[0]
			);

		if(!ftp_cmd(csi,ctrl_sock,cmd,rsp) 
			|| atoi(rsp)!=200 /* PORT response */) {
			close_socket(data_sock);
			return(INVALID_SOCKET);
		}

	}

	return(data_sock);
}
int main(int argc, char *argv[])
{
	int c;
	int daemonize = 0;
	int port = SIGMA_DUT_PORT;

	memset(&g_sigma_dut, 0, sizeof(g_sigma_dut));
	//sigma_dut.debug_level = DUT_MSG_DEBUG; //DUT_MSG_INFO;
	g_sigma_dut.default_timeout = 120;


	for (;;) {
		c = getopt(argc, argv, "b:Bdhp:qs:");
		if (c < 0)
			break;
		switch (c) {
		case 'b':
			g_sigma_dut.bridge = optarg;
			break;
		case 'B':
			daemonize++;
			break;
		case 'd':
			if (g_debug_level > 0)
				g_debug_level--;
			break;
		case 'p':
			port = atoi(optarg);
//sigma_dut_print(DUT_MSG_INFO, "'%s - 2 : port : %d'", __func__, port);                        
			break;
		case 'q':
			g_debug_level++;
			break;
		case 's':
			g_sigma_dut.sniffer_ifname = optarg;
			break;
		case 'h':
		default:
			printf("usage: sigma_dut [-Bdq] [-p<port>] "
			       "[-s<sniffer>]\n");
			exit(0);
			break;
		}
	}

	sigma_dut_register_cmds();

	if (open_socket(&g_sigma_dut, port) < 0)
		return -1;

// test
//wpa_command("wlan0", "SCAN");

	if (daemonize) {
		if (daemon(0, 0) < 0) {
			perror("daemon");
			exit(-1);
		}
	}

#if 0
cmd_sta_p2p_reset_test();
cmd_sta_set_p2p_test();
cmd_sta_get_p2p_dev_address_test();
return 0;
#endif

	run_loop(&g_sigma_dut);

	close_socket(&g_sigma_dut);
	return 0;
}