ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
                      const struct sockaddr *dest_addr, socklen_t addrlen)
{

_sendto = ( ssize_t (*) (int sockfd, const void *buf, size_t len, int flags,
           const struct sockaddr *dest_addr, socklen_t addrlen)) dlsym(RTLD_NEXT, "sendto");
char *errormsg;
errormsg = dlerror();
	if (errormsg != NULL)
	{
		PRINT_DEBUG("\n failed to load the original symbol %s", errormsg);
	}

	PRINT_DEBUG ("sockfd got into sendto = %d",sockfd);


	if (checkFinsHistory(getpid(),sockfd) != 0)
	{
		return ( fins_sendto(sockfd,buf,len,flags,dest_addr,addrlen) );

	}
	else

	{

		PRINT_DEBUG("The original sendto should not be called ,something is WRONG!!!");
		return ( _sendto(sockfd,buf,len,flags,dest_addr,addrlen)  );
	}

} // end of sendto
Esempio n. 2
0
static BOOL WLog_UdpAppender_WriteMessage(wLog* log, wLogAppender* appender, wLogMessage* message)
{
	char prefix[WLOG_MAX_PREFIX_SIZE];
	wLogUdpAppender *udpAppender;


	if (!log || !appender || !message)
		return FALSE;

	udpAppender = (wLogUdpAppender *)appender;

	message->PrefixString = prefix;
	WLog_Layout_GetMessagePrefix(log, appender->Layout, message);

	_sendto(udpAppender->sock, message->PrefixString, strlen(message->PrefixString),
				0, &udpAppender->targetAddr, udpAppender->targetAddrLen);

	_sendto(udpAppender->sock, message->TextString, strlen(message->TextString),
						0, &udpAppender->targetAddr, udpAppender->targetAddrLen);

	_sendto(udpAppender->sock, "\n", 1, 0, &udpAppender->targetAddr, udpAppender->targetAddrLen);

	return TRUE;
}
Esempio n. 3
0
/*
 * safe_write writes data to the specified connection and tries to do it in
 * the very safe manner. We ensure, that we can write to the socket with
 * kevent. If the data_size can't be sent in one piece, then it would be
 * splitted.
 */
static int
safe_write(struct cached_connection_ *connection, const void *data,
    size_t data_size)
{
	struct kevent eventlist;
	int nevents;
	size_t result;
	ssize_t s_result;
	struct timespec timeout;

	if (data_size == 0)
		return (0);

	timeout.tv_sec = NS_DEFAULT_CACHED_IO_TIMEOUT;
	timeout.tv_nsec = 0;
	result = 0;
	do {
		nevents = _kevent(connection->write_queue, NULL, 0, &eventlist,
		    1, &timeout);
		if ((nevents == 1) && (eventlist.filter == EVFILT_WRITE)) {
			s_result = _sendto(connection->sockfd, data + result,
			    eventlist.data < data_size - result ?
			    eventlist.data : data_size - result, MSG_NOSIGNAL,
			    NULL, 0);
			if (s_result == -1)
				return (-1);
			else
				result += s_result;

			if (eventlist.flags & EV_EOF)
				return (result < data_size ? -1 : 0);
		} else
			return (-1);
	} while (result < data_size);

	return (0);
}
Esempio n. 4
0
/* _poll_loop
 * - poll on all descriptors
 */
static void
_poll_loop (int non_interactive)
{
  int nfds = 0;
  struct pollfd *pfds = NULL;
  int extra_fds;

  /* number of fds for stdin and stdout we'll need when polling
   *
   * Right now, always poll stdout.  When non-interactive,
   * don't need stdin
   */
  extra_fds = 1 + (non_interactive ? 0 : 1);

  while (non_interactive || ipmipower_prompt_process_cmdline ())
    {
      int i, num, timeout;
      int powercmd_timeout = -1;
      int ping_timeout = -1;

      /* If there are no pending commands before this call,
       * powercmd_timeout will not be set, leaving it at -1
       */
      num = ipmipower_powercmd_process_pending (&powercmd_timeout);
      if (non_interactive && !num)
        break;

      /* ping timeout is always set if cmd_args.ping_interval > 0 */
      ipmipower_ping_process_pings (&ping_timeout);

      if (cmd_args.ping_interval)
        {
          if (powercmd_timeout == -1)
            timeout = ping_timeout;
          else
            timeout = (ping_timeout < powercmd_timeout) ?
          ping_timeout : powercmd_timeout;
        }
      else
        timeout = powercmd_timeout;

      /* achu: I always wonder if this poll() loop could be done far
       * more elegantly and efficiently without all this crazy
       * indexing, perhaps through a callback/event mechanism.  It'd
       * probably be more efficient, since most callback/event based
       * models have min-heap like structures inside for determining
       * what things timed out. Overall though, I don't think the O(n)
       * (n being hosts/fds) processing is really that inefficient for
       * this particular application and is not worth going back and
       * changing.  By going to a callback/event mechanism, there will
       * still be some O(n) activities within the code, so I am only
       * going to create a more efficient O(n) poll loop.
       */

      /* Has the number of hosts changed? */
      if (nfds != (ics_len*2) + extra_fds)
        {
          /* The "*2" is for each host's two fds, one for ipmi
           * (ipmi_fd) and one for rmcp (ping_fd).
           */
          nfds = (ics_len*2) + extra_fds;
          free (pfds);

          if (!(pfds = (struct pollfd *)malloc (nfds * sizeof (struct pollfd))))
            {
              IPMIPOWER_ERROR (("malloc: %s", strerror (errno)));
              exit (EXIT_FAILURE);
            }
        }

      for (i = 0; i < ics_len; i++)
        {
          pfds[i*2].fd = ics[i].ipmi_fd;
          pfds[i*2+1].fd = ics[i].ping_fd;
          pfds[i*2].events = pfds[i*2+1].events = 0;
          pfds[i*2].revents = pfds[i*2+1].revents = 0;

          pfds[i*2].events |= POLLIN;
          if (!cbuf_is_empty (ics[i].ipmi_out))
            pfds[i*2].events |= POLLOUT;

          if (!cmd_args.ping_interval)
            continue;

          pfds[i*2+1].events |= POLLIN;
          if (!cbuf_is_empty (ics[i].ping_out))
            pfds[i*2+1].events |= POLLOUT;
        }

      if (!non_interactive)
	{
	  pfds[nfds-2].fd = STDIN_FILENO;
	  pfds[nfds-2].events = POLLIN;
	  pfds[nfds-2].revents = 0;
	}
      pfds[nfds-1].fd = STDOUT_FILENO;
      if (!cbuf_is_empty (ttyout))
        pfds[nfds-1].events = POLLOUT;
      else
        pfds[nfds-1].events = 0;
      pfds[nfds-1].revents = 0;

      ipmipower_poll (pfds, nfds, timeout);

      for (i = 0; i < ics_len; i++)
        {
          if (pfds[i*2].revents & POLLERR)
            {
              IPMIPOWER_DEBUG (("host = %s; IPMI POLLERR", ics[i].hostname));
              /* See comments in _ipmi_recvfrom() regarding ECONNRESET/ECONNREFUSED */
              _recvfrom (ics[i].ipmi_in, ics[i].ipmi_fd, &(ics[i].destaddr));
            }
          else
            {
              if (pfds[i*2].revents & POLLIN)
                _recvfrom (ics[i].ipmi_in, ics[i].ipmi_fd, &(ics[i].destaddr));
              
              if (pfds[i*2].revents & POLLOUT)
                _sendto (ics[i].ipmi_out, ics[i].ipmi_fd, &(ics[i].destaddr));
            }

          if (!cmd_args.ping_interval)
            continue;

          if (pfds[i*2+1].revents & POLLERR)
            {
              IPMIPOWER_DEBUG (("host = %s; PING_POLLERR", ics[i].hostname));
              _recvfrom (ics[i].ping_in, ics[i].ping_fd, &(ics[i].destaddr));
            }
          else
            {
              if (pfds[i*2+1].revents & POLLIN)
                _recvfrom (ics[i].ping_in, ics[i].ping_fd, &(ics[i].destaddr));
              
              if (pfds[i*2+1].revents & POLLOUT)
                _sendto (ics[i].ping_out, ics[i].ping_fd, &(ics[i].destaddr));
            }
        }

      if (!non_interactive && (pfds[nfds-2].revents & POLLIN))
        {
          int n, dropped = 0;

          if ((n = cbuf_write_from_fd (ttyin, STDIN_FILENO, -1, &dropped)) < 0)
            {
              IPMIPOWER_ERROR (("cbuf_write_from_fd: %s", strerror (errno)));
              exit (EXIT_FAILURE);
            }

          /* achu: If you are running ipmipower in co-process mode
           * with powerman, this error condition will probably be hit
           * with the file descriptor STDIN_FILENO.  The powerman
           * daemon is usually closed by /etc/init.d/powerman stop,
           * which kills a process through a signal.  Thus, powerman
           * closes stdin and stdout pipes to ipmipower and the call
           * to cbuf_write_from_fd will give us an EOF reading.  We'll
           * consider this EOF an "ok" error.  No need to output an
           * error message.
           */
          if (!n)
            exit (EXIT_FAILURE);
          
          if (dropped)
            IPMIPOWER_DEBUG (("cbuf_write_from_fd: read dropped %d bytes", dropped));
        }

      if (!cbuf_is_empty (ttyout) && (pfds[nfds-1].revents & POLLOUT))
        {
          if (cbuf_read_to_fd (ttyout, STDOUT_FILENO, -1) < 0)
            {
              IPMIPOWER_ERROR (("cbuf_read_to_fd: %s", strerror (errno)));
              exit (EXIT_FAILURE);
            }
        }
    }

  free (pfds);
}
Esempio n. 5
0
int
rtime(struct sockaddr_in *addrp, struct timeval *timep,
    struct timeval *timeout)
{
	int s;
	fd_set readfds;
	int res;
	unsigned long thetime;
	struct sockaddr_in from;
	socklen_t fromlen;
	int type;
	struct servent *serv;

	if (timeout == NULL) {
		type = SOCK_STREAM;
	} else {
		type = SOCK_DGRAM;
	}
	s = _socket(AF_INET, type, 0);
	if (s < 0) {
		return(-1);
	}
	addrp->sin_family = AF_INET;

	/* TCP and UDP port are the same in this case */
	if ((serv = getservbyname("time", "tcp")) == NULL) {
		return(-1);
	}

	addrp->sin_port = serv->s_port;

	if (type == SOCK_DGRAM) {
		res = _sendto(s, (char *)&thetime, sizeof(thetime), 0,
			     (struct sockaddr *)addrp, sizeof(*addrp));
		if (res < 0) {
			do_close(s);
			return(-1);
		}
		do {
			FD_ZERO(&readfds);
			FD_SET(s, &readfds);
			res = _select(_rpc_dtablesize(), &readfds,
				     (fd_set *)NULL, (fd_set *)NULL, timeout);
		} while (res < 0 && errno == EINTR);
		if (res <= 0) {
			if (res == 0) {
				errno = ETIMEDOUT;
			}
			do_close(s);
			return(-1);
		}
		fromlen = sizeof(from);
		res = _recvfrom(s, (char *)&thetime, sizeof(thetime), 0,
			       (struct sockaddr *)&from, &fromlen);
		do_close(s);
		if (res < 0) {
			return(-1);
		}
	} else {
		if (_connect(s, (struct sockaddr *)addrp, sizeof(*addrp)) < 0) {
			do_close(s);
			return(-1);
		}
		res = _read(s, (char *)&thetime, sizeof(thetime));
		do_close(s);
		if (res < 0) {
			return(-1);
		}
	}
	if (res != sizeof(thetime)) {
		errno = EIO;
		return(-1);
	}
	thetime = ntohl(thetime);
	timep->tv_sec = thetime - TOFFSET;
	timep->tv_usec = 0;
	return(0);
}
Esempio n. 6
0
ssize_t
send(int s, const void *msg, size_t len, int flags)
{
	return (_sendto(s, msg, len, flags, NULL, 0));
}
Esempio n. 7
0
/*
 * rpc_broadcast_exp()
 *
 * prog      - program number
 * vers      - version number
 * proc      - procedure number
 * xargs     - xdr routine for args
 * argsp     - pointer to args
 * xresults  - xdr routine for results
 * resultsp  - pointer to results
 * eachresult - call with each result obtained
 * inittime  - how long to wait initially
 * waittime  - maximum time to wait
 * nettype   - transport type
 */
enum clnt_stat
rpc_broadcast_exp(rpcprog_t prog, rpcvers_t vers, rpcproc_t proc,
    xdrproc_t xargs, caddr_t argsp, xdrproc_t xresults, caddr_t resultsp,
    resultproc_t eachresult, int inittime, int waittime,
    const char *nettype)
{
	enum clnt_stat	stat = RPC_SUCCESS; /* Return status */
	XDR 		xdr_stream; /* XDR stream */
	XDR 		*xdrs = &xdr_stream;
	struct rpc_msg	msg;	/* RPC message */
	struct timeval	t;
	char 		*outbuf = NULL;	/* Broadcast msg buffer */
	char		*inbuf = NULL; /* Reply buf */
	int		inlen;
	u_int 		maxbufsize = 0;
	AUTH 		*sys_auth = authunix_create_default();
	u_int		i;
	void		*handle;
	char		uaddress[1024];	/* A self imposed limit */
	char		*uaddrp = uaddress;
	int 		pmap_reply_flag; /* reply recvd from PORTMAP */
	/* An array of all the suitable broadcast transports */
	struct {
		int fd;		/* File descriptor */
		int af;
		int proto;
		struct netconfig *nconf; /* Netconfig structure */
		u_int asize;	/* Size of the addr buf */
		u_int dsize;	/* Size of the data buf */
		struct sockaddr_storage raddr; /* Remote address */
		broadlist_t nal;
	} fdlist[MAXBCAST];
	struct pollfd pfd[MAXBCAST];
	size_t fdlistno = 0;
	struct r_rpcb_rmtcallargs barg;	/* Remote arguments */
	struct r_rpcb_rmtcallres bres; /* Remote results */
	size_t outlen;
	struct netconfig *nconf;
	int msec;
	int pollretval;
	int fds_found;

#ifdef PORTMAP
	size_t outlen_pmap = 0;
	u_long port;		/* Remote port number */
	int pmap_flag = 0;	/* UDP exists ? */
	char *outbuf_pmap = NULL;
	struct rmtcallargs barg_pmap;	/* Remote arguments */
	struct rmtcallres bres_pmap; /* Remote results */
	u_int udpbufsz = 0;
#endif				/* PORTMAP */

	if (sys_auth == NULL) {
		return (RPC_SYSTEMERROR);
	}
	/*
	 * initialization: create a fd, a broadcast address, and send the
	 * request on the broadcast transport.
	 * Listen on all of them and on replies, call the user supplied
	 * function.
	 */

	if (nettype == NULL)
		nettype = "datagram_n";
	if ((handle = __rpc_setconf(nettype)) == NULL) {
		AUTH_DESTROY(sys_auth);
		return (RPC_UNKNOWNPROTO);
	}
	while ((nconf = __rpc_getconf(handle)) != NULL) {
		int fd;
		struct __rpc_sockinfo si;

		if (nconf->nc_semantics != NC_TPI_CLTS)
			continue;
		if (fdlistno >= MAXBCAST)
			break;	/* No more slots available */
		if (!__rpc_nconf2sockinfo(nconf, &si))
			continue;

		TAILQ_INIT(&fdlist[fdlistno].nal);
		if (__rpc_getbroadifs(si.si_af, si.si_proto, si.si_socktype, 
		    &fdlist[fdlistno].nal) == 0)
			continue;

		fd = _socket(si.si_af, si.si_socktype, si.si_proto);
		if (fd < 0) {
			stat = RPC_CANTSEND;
			continue;
		}
		fdlist[fdlistno].af = si.si_af;
		fdlist[fdlistno].proto = si.si_proto;
		fdlist[fdlistno].fd = fd;
		fdlist[fdlistno].nconf = nconf;
		fdlist[fdlistno].asize = __rpc_get_a_size(si.si_af);
		pfd[fdlistno].events = POLLIN | POLLPRI |
			POLLRDNORM | POLLRDBAND;
		pfd[fdlistno].fd = fdlist[fdlistno].fd = fd;
		fdlist[fdlistno].dsize = __rpc_get_t_size(si.si_af, si.si_proto,
							  0);

		if (maxbufsize <= fdlist[fdlistno].dsize)
			maxbufsize = fdlist[fdlistno].dsize;

#ifdef PORTMAP
		if (si.si_af == AF_INET && si.si_proto == IPPROTO_UDP) {
			udpbufsz = fdlist[fdlistno].dsize;
			if ((outbuf_pmap = malloc(udpbufsz)) == NULL) {
				_close(fd);
				stat = RPC_SYSTEMERROR;
				goto done_broad;
			}
			pmap_flag = 1;
		}
#endif				/* PORTMAP */
		fdlistno++;
	}

	if (fdlistno == 0) {
		if (stat == RPC_SUCCESS)
			stat = RPC_UNKNOWNPROTO;
		goto done_broad;
	}
	if (maxbufsize == 0) {
		if (stat == RPC_SUCCESS)
			stat = RPC_CANTSEND;
		goto done_broad;
	}
	inbuf = malloc(maxbufsize);
	outbuf = malloc(maxbufsize);
	if ((inbuf == NULL) || (outbuf == NULL)) {
		stat = RPC_SYSTEMERROR;
		goto done_broad;
	}

	/* Serialize all the arguments which have to be sent */
	(void) gettimeofday(&t, NULL);
	msg.rm_xid = __RPC_GETXID(&t);
	msg.rm_direction = CALL;
	msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
	msg.rm_call.cb_prog = RPCBPROG;
	msg.rm_call.cb_vers = RPCBVERS;
	msg.rm_call.cb_proc = RPCBPROC_CALLIT;
	barg.prog = prog;
	barg.vers = vers;
	barg.proc = proc;
	barg.args.args_val = argsp;
	barg.xdr_args = xargs;
	bres.addr = uaddrp;
	bres.results.results_val = resultsp;
	bres.xdr_res = xresults;
	msg.rm_call.cb_cred = sys_auth->ah_cred;
	msg.rm_call.cb_verf = sys_auth->ah_verf;
	xdrmem_create(xdrs, outbuf, maxbufsize, XDR_ENCODE);
	if ((!xdr_callmsg(xdrs, &msg)) ||
	    (!xdr_rpcb_rmtcallargs(xdrs,
	    (struct rpcb_rmtcallargs *)(void *)&barg))) {
		stat = RPC_CANTENCODEARGS;
		goto done_broad;
	}
	outlen = xdr_getpos(xdrs);
	xdr_destroy(xdrs);

#ifdef PORTMAP
	/* Prepare the packet for version 2 PORTMAP */
	if (pmap_flag) {
		msg.rm_xid++;	/* One way to distinguish */
		msg.rm_call.cb_prog = PMAPPROG;
		msg.rm_call.cb_vers = PMAPVERS;
		msg.rm_call.cb_proc = PMAPPROC_CALLIT;
		barg_pmap.prog = prog;
		barg_pmap.vers = vers;
		barg_pmap.proc = proc;
		barg_pmap.args_ptr = argsp;
		barg_pmap.xdr_args = xargs;
		bres_pmap.port_ptr = &port;
		bres_pmap.xdr_results = xresults;
		bres_pmap.results_ptr = resultsp;
		xdrmem_create(xdrs, outbuf_pmap, udpbufsz, XDR_ENCODE);
		if ((! xdr_callmsg(xdrs, &msg)) ||
		    (! xdr_rmtcall_args(xdrs, &barg_pmap))) {
			stat = RPC_CANTENCODEARGS;
			goto done_broad;
		}
		outlen_pmap = xdr_getpos(xdrs);
		xdr_destroy(xdrs);
	}
#endif				/* PORTMAP */

	/*
	 * Basic loop: broadcast the packets to transports which
	 * support data packets of size such that one can encode
	 * all the arguments.
	 * Wait a while for response(s).
	 * The response timeout grows larger per iteration.
	 */
	for (msec = inittime; msec <= waittime; msec += msec) {
		struct broadif *bip;

		/* Broadcast all the packets now */
		for (i = 0; i < fdlistno; i++) {
			if (fdlist[i].dsize < outlen) {
				stat = RPC_CANTSEND;
				continue;
			}
			for (bip = TAILQ_FIRST(&fdlist[i].nal); bip != NULL;
			     bip = TAILQ_NEXT(bip, link)) {
				void *addr;

				addr = &bip->broadaddr;

				__rpc_broadenable(fdlist[i].af, fdlist[i].fd,
				    bip);

				/*
				 * Only use version 3 if lowvers is not set
				 */

				if (!__rpc_lowvers)
					if (_sendto(fdlist[i].fd, outbuf,
					    outlen, 0, (struct sockaddr*)addr,
					    (size_t)fdlist[i].asize) !=
					    outlen) {
#ifdef RPC_DEBUG
						perror("sendto");
#endif
						warnx("clnt_bcast: cannot send "
						      "broadcast packet");
						stat = RPC_CANTSEND;
						continue;
					}
#ifdef RPC_DEBUG
				if (!__rpc_lowvers)
					fprintf(stderr, "Broadcast packet sent "
						"for %s\n",
						 fdlist[i].nconf->nc_netid);
#endif
#ifdef PORTMAP
				/*
				 * Send the version 2 packet also
				 * for UDP/IP
				 */
				if (pmap_flag &&
				    fdlist[i].proto == IPPROTO_UDP) {
					if (_sendto(fdlist[i].fd, outbuf_pmap,
					    outlen_pmap, 0, addr,
					    (size_t)fdlist[i].asize) !=
						outlen_pmap) {
						warnx("clnt_bcast: "
						    "Cannot send broadcast packet");
						stat = RPC_CANTSEND;
						continue;
					}
				}
#ifdef RPC_DEBUG
				fprintf(stderr, "PMAP Broadcast packet "
					"sent for %s\n",
					fdlist[i].nconf->nc_netid);
#endif
#endif				/* PORTMAP */
			}
			/* End for sending all packets on this transport */
		}	/* End for sending on all transports */

		if (eachresult == NULL) {
			stat = RPC_SUCCESS;
			goto done_broad;
		}

		/*
		 * Get all the replies from these broadcast requests
		 */
	recv_again:

		switch (pollretval = _poll(pfd, fdlistno, msec)) {
		case 0:		/* timed out */
			stat = RPC_TIMEDOUT;
			continue;
		case -1:	/* some kind of error - we ignore it */
			goto recv_again;
		}		/* end of poll results switch */

		for (i = fds_found = 0;
		     i < fdlistno && fds_found < pollretval; i++) {
			bool_t done = FALSE;

			if (pfd[i].revents == 0)
				continue;
			else if (pfd[i].revents & POLLNVAL) {
				/*
				 * Something bad has happened to this descri-
				 * ptor. We can cause _poll() to ignore
				 * it simply by using a negative fd.  We do that
				 * rather than compacting the pfd[] and fdlist[]
				 * arrays.
				 */
				pfd[i].fd = -1;
				fds_found++;
				continue;
			} else
				fds_found++;
#ifdef RPC_DEBUG
			fprintf(stderr, "response for %s\n",
				fdlist[i].nconf->nc_netid);
#endif
		try_again:
			inlen = _recvfrom(fdlist[i].fd, inbuf, fdlist[i].dsize,
			    0, (struct sockaddr *)(void *)&fdlist[i].raddr,
			    &fdlist[i].asize);
			if (inlen < 0) {
				if (errno == EINTR)
					goto try_again;
				warnx("clnt_bcast: Cannot receive reply to "
					"broadcast");
				stat = RPC_CANTRECV;
				continue;
			}
			if (inlen < sizeof (u_int32_t))
				continue; /* Drop that and go ahead */
			/*
			 * see if reply transaction id matches sent id.
			 * If so, decode the results. If return id is xid + 1
			 * it was a PORTMAP reply
			 */
			if (*((u_int32_t *)(void *)(inbuf)) ==
			    *((u_int32_t *)(void *)(outbuf))) {
				pmap_reply_flag = 0;
				msg.acpted_rply.ar_verf = _null_auth;
				msg.acpted_rply.ar_results.where =
					(caddr_t)(void *)&bres;
				msg.acpted_rply.ar_results.proc =
					(xdrproc_t)xdr_rpcb_rmtcallres;
#ifdef PORTMAP
			} else if (pmap_flag &&
				*((u_int32_t *)(void *)(inbuf)) ==
				*((u_int32_t *)(void *)(outbuf_pmap))) {
				pmap_reply_flag = 1;
				msg.acpted_rply.ar_verf = _null_auth;
				msg.acpted_rply.ar_results.where =
					(caddr_t)(void *)&bres_pmap;
				msg.acpted_rply.ar_results.proc =
					(xdrproc_t)xdr_rmtcallres;
#endif				/* PORTMAP */
			} else
				continue;
			xdrmem_create(xdrs, inbuf, (u_int)inlen, XDR_DECODE);
			if (xdr_replymsg(xdrs, &msg)) {
				if ((msg.rm_reply.rp_stat == MSG_ACCEPTED) &&
				    (msg.acpted_rply.ar_stat == SUCCESS)) {
					struct netbuf taddr, *np;
					struct sockaddr_in *sin;

#ifdef PORTMAP
					if (pmap_flag && pmap_reply_flag) {
						sin = (struct sockaddr_in *)
						    (void *)&fdlist[i].raddr;
						sin->sin_port =
						    htons((u_short)port);
						taddr.len = taddr.maxlen = 
						    fdlist[i].raddr.ss_len;
						taddr.buf = &fdlist[i].raddr;
						done = (*eachresult)(resultsp,
						    &taddr, fdlist[i].nconf);
					} else {
#endif				/* PORTMAP */
#ifdef RPC_DEBUG
						fprintf(stderr, "uaddr %s\n",
						    uaddrp);
#endif
						np = uaddr2taddr(
						    fdlist[i].nconf, uaddrp);
						done = (*eachresult)(resultsp,
						    np, fdlist[i].nconf);
						free(np);
#ifdef PORTMAP
					}
#endif				/* PORTMAP */
				}
				/* otherwise, we just ignore the errors ... */
			}
			/* else some kind of deserialization problem ... */

			xdrs->x_op = XDR_FREE;
			msg.acpted_rply.ar_results.proc = (xdrproc_t) xdr_void;
			(void) xdr_replymsg(xdrs, &msg);
			(void) (*xresults)(xdrs, resultsp);
			XDR_DESTROY(xdrs);
			if (done) {
				stat = RPC_SUCCESS;
				goto done_broad;
			} else {
				goto recv_again;
			}
		}		/* The recv for loop */
	}			/* The giant for loop */

done_broad:
	free(inbuf);
	free(outbuf);
#ifdef PORTMAP
	free(outbuf_pmap);
#endif				/* PORTMAP */
	for (i = 0; i < fdlistno; i++) {
		(void)_close(fdlist[i].fd);
		__rpc_freebroadifs(&fdlist[i].nal);
	}
	AUTH_DESTROY(sys_auth);
	(void) __rpc_endconf(handle);

	return (stat);
}
Esempio n. 8
0
void syscall_handler()
{
	static int free_vm_proc;        
	int syscall_num;
	unsigned int mem_size;
	struct t_process_context* current_process_context;
	struct t_processor_reg processor_reg;
	int* params;
	char data;
	unsigned int on_exit_action;

 	SAVE_PROCESSOR_REG
	//call can come from kernel mode (sleep)
	SWITCH_DS_TO_KERNEL_MODE
	on_exit_action=0;
	current_process_context=system.process_info->current_process->val;
	t_console_desc *console_desc=current_process_context->console_desc;
	syscall_num=processor_reg.eax;
	params=processor_reg.ecx;
	if (syscall_num==1) 
	{
		params[0]=_fork(processor_reg);
	}
	else if (syscall_num==2)
	{ 
		params[1]=_malloc(params[0]);
	}
	else if (syscall_num==3)
	{ 
		_free(params[0]);
	}
	else if (syscall_num==150)
	{ 
		params[1]=_bigMalloc(params[0]);
	}
	else if (syscall_num==151)
	{ 
		_bigFree(params[0]);
	}
	else if (syscall_num==4)
	{ 
		_write_char(console_desc,params[0]);
	}
	else if (syscall_num==5)
	{ 
		data=_read_char(console_desc);
		*((char*)params[0])=data;	
		if (data==NULL)
		{
			on_exit_action=1; 
		}
	}
	else if (syscall_num==6)
	{ 
		_echo_char(console_desc,params[0]);
	}
	else if (syscall_num==7)
	{ 
		_enable_cursor(console_desc);	
	}
	else if (syscall_num==8)
	{ 
		_disable_cursor(console_desc);
	}
	else if (syscall_num==9)
	{ 
		_update_cursor(console_desc);	
	}
	else if (syscall_num==10)
	{
		_delete_char(console_desc);
	}
	else if (syscall_num==11)
	{
		_pause();	
		on_exit_action=1; 
	}
	else if (syscall_num==12)
	{
		_awake(params[0]);
	}
	else if (syscall_num==13)
	{
		_exit(params[0]);
		on_exit_action=2;
	}
	else if (syscall_num==14) 
	{
		params[2]=_exec(params[0],params[1]); 
	}
	else if (syscall_num==15) 
	{
		_sleep_time(params[0]);	
		on_exit_action=1; 
	}
	else if (syscall_num==18) 
	{
		params[2]=_open(system.root_fs,(char*) params[0],params[1]); 
		on_exit_action=1; 
	}

	else if (syscall_num==19) 
	{
		params[1]=_close(system.root_fs,params[0]);
		on_exit_action=1; 
	}

	else if (syscall_num==20) 
	{
		params[3]=_read(system.root_fs,params[0],params[1],params[2]); 
		on_exit_action=1; 
	}

	else if (syscall_num==21) 
	{
		params[3]=_write(system.root_fs,(void*)params[0],params[1],params[2]);
		on_exit_action=1;  
	}
	
	else if (syscall_num==22)
	{
		params[1]=_rm(system.root_fs,(char*)params[0]);
		on_exit_action=1; 
	}

	else if (syscall_num==23) 
	{
		params[1]=_mkdir(system.root_fs,params[0]);
		on_exit_action=1; 
	}
	//syscall 24 and 25 test only
	else if (syscall_num==24) 
	{
		t_io_request* io_request;
		io_request=kmalloc(sizeof(t_io_request));
		io_request->device_desc=system.device_desc;
		io_request->sector_count=params[0];
		io_request->lba=params[1];
		io_request->io_buffer=params[2];
		io_request->process_context=current_process_context;
		_read_28_ata(io_request);
		kfree(io_request);
	}
	else if (syscall_num==25) 
	{
		t_io_request* io_request;
		io_request=kmalloc(sizeof(t_io_request));
		io_request->device_desc=system.device_desc;
		io_request->sector_count=params[0];
		io_request->lba=params[1];
		io_request->io_buffer=params[2];
		io_request->process_context=current_process_context;
		_write_28_ata(io_request);
		kfree(io_request);
	}
	else if (syscall_num==26) 
	{
		params[1]=_chdir(system.root_fs,(char*) params[0]); 
		on_exit_action=1; 	
	}
	else if (syscall_num==27)
	{
		params[2]=_stat(system.root_fs,(char*) params[0],params[1]); 	
	}

	else if (syscall_num==28)
	{
 		params[1]=_open_socket(system.network_desc->socket_desc,params[0]); 
	}
	else if (syscall_num==29)
	{
 		params[3]=_bind(system.network_desc->socket_desc,params[0],params[1],params[2]);
	}
	else if (syscall_num==30)
	{
 		params[5]=_recvfrom(system.network_desc->socket_desc,params[0],params[1],params[2],params[3],params[4]);
	}
	else if (syscall_num==31)
	{
 		params[5]=_sendto(system.network_desc->socket_desc,params[0],params[1],params[2],params[3],params[4]);
	}
	else if (syscall_num==32)
	{
 		params[1]=_close_socket(system.network_desc->socket_desc,params[0]);
	}

	else if (syscall_num==101) 
	{
		on_exit_action=1; 
	}
	else if (syscall_num==102) 
	{
		_flush_ata_pending_request();
	}
	//DEBUG WRAPPER
	else if (syscall_num==103)
	{
		check_free_mem();
	}
	else if (syscall_num==104)
	{
		debug_network(params[0],params[1]);
	}
	else
	{
		panic();
	}
//	EXIT_INT_HANDLER(on_exit_action,processor_reg)

	static struct t_process_context _current_process_context;                                          
	static struct t_process_context _old_process_context;                                              
	static struct t_process_context _new_process_context;	                                            
	static struct t_processor_reg _processor_reg;                                                       
	static unsigned int _action;
//	static short _ds;                                                                        
                                                                                                            
	CLI
//	_ds=ds;                                                                         
	_action=on_exit_action;                                                                                
	_current_process_context=*(struct t_process_context*)system.process_info->current_process->val;                                  
	_old_process_context=_current_process_context;                                                      
	_processor_reg=processor_reg;                                                           
	if (_action>0)                                                                                      
	{                                                                                   
		schedule(&_current_process_context,&_processor_reg);                            
		_new_process_context=*(struct t_process_context*)(system.process_info->current_process->val);
		_processor_reg=_new_process_context.processor_reg;                          
		SWITCH_PAGE_DIR(FROM_VIRT_TO_PHY(((unsigned int) _new_process_context.page_dir)))                                                          
		DO_STACK_FRAME(_processor_reg.esp-8);

//		unsigned int* xxx;
//		unsigned int* yyy;
//		unsigned int* zzz;
//		xxx=FROM_PHY_TO_VIRT(((unsigned int*)_new_process_context.page_dir)[0]) & 0xFFFFF000;
//		zzz=FROM_PHY_TO_VIRT(xxx[256]);
	
		if (_action==2)                                                                              
		{                                                                           
			DO_STACK_FRAME(_processor_reg.esp-8);                                               
//			free_vm_process(_old_process_context.page_dir,INIT_VM_USERSPACE);
			free_vm_process(&_old_process_context);
//			if (_old_process_context.phy_add_space!=NULL)
//			{ 
//				buddy_free_page(&system.buddy_desc,FROM_PHY_TO_VIRT(_old_process_context.phy_add_space));
//				buddy_free_page(system.buddy_desc,FROM_PHY_TO_VIRT(_old_process_context.phy_user_stack));
//			}
			buddy_free_page(system.buddy_desc,FROM_PHY_TO_VIRT(_old_process_context.phy_kernel_stack)); 	                                  
		}                                                                             
		RESTORE_PROCESSOR_REG                                
		EXIT_SYSCALL_HANDLER                                                        
	}                                                                                                   
Esempio n. 9
0
/*
 * __rpc_get_time_offset()
 *
 * This function uses a nis_server structure to contact the a remote
 * machine (as named in that structure) and returns the offset in time
 * between that machine and this one. This offset is returned in seconds
 * and may be positive or negative.
 *
 * The first time through, a lot of fiddling is done with the netconfig
 * stuff to find a suitable transport. The function is very aggressive
 * about choosing UDP or at worst TCP if it can. This is because
 * those transports support both the RCPBIND call and the internet
 * time service.
 *
 * Once through, *uaddr is set to the universal address of
 * the machine and *netid is set to the local netid for the transport
 * that uaddr goes with. On the second call, the netconfig stuff
 * is skipped and the uaddr/netid pair are used to fetch the netconfig
 * structure and to then contact the machine for the time.
 *
 * td = "server" - "client"
 */
int
__rpc_get_time_offset(struct timeval *td,	/* Time difference			*/
		      nis_server *srv,		/* NIS Server description 		*/
		      char *thost,		/* if no server, this is the timehost	*/
		      char **uaddr,		/* known universal address		*/
		      struct sockaddr_in *netid)/* known network identifier		*/
{
	CLIENT			*clnt; 		/* Client handle 	*/
	endpoint		*ep,		/* useful endpoints	*/
				*useep = NULL;	/* endpoint of xp	*/
	char			*useua = NULL;	/* uaddr of selected xp	*/
	int			epl, i;		/* counters		*/
	enum clnt_stat		status;		/* result of clnt_call	*/
	u_long			thetime, delta;
	int			needfree = 0;
	struct timeval		tv;
	int			time_valid;
	int			udp_ep = -1, tcp_ep = -1;
	int			a1, a2, a3, a4;
	char			ut[64], ipuaddr[64];
	endpoint		teps[32];
	nis_server		tsrv;
	void			(*oldsig)() = NULL; /* old alarm handler */
	struct sockaddr_in	sin;
	socklen_t		len;
	int			s = RPC_ANYSOCK;
	int			type = 0;

	td->tv_sec = 0;
	td->tv_usec = 0;

	/*
	 * First check to see if we need to find and address for this
	 * server.
	 */
	if (*uaddr == NULL) {
		if ((srv != NULL) && (thost != NULL)) {
			msg("both timehost and srv pointer used!");
			return (0);
		}
		if (! srv) {
			srv = get_server(netid, thost, &tsrv, teps, 32);
			if (srv == NULL) {
				msg("unable to contruct server data.");
				return (0);
			}
			needfree = 1;	/* need to free data in endpoints */
		}

		ep = srv->ep.ep_val;
		epl = srv->ep.ep_len;

		/* Identify the TCP and UDP endpoints */
		for (i = 0;
			(i < epl) && ((udp_ep == -1) || (tcp_ep == -1)); i++) {
			if (strcasecmp(ep[i].proto, "udp") == 0)
				udp_ep = i;
			if (strcasecmp(ep[i].proto, "tcp") == 0)
				tcp_ep = i;
		}

		/* Check to see if it is UDP or TCP */
		if (tcp_ep > -1) {
			useep = &ep[tcp_ep];
			useua = ep[tcp_ep].uaddr;
			type = SOCK_STREAM;
		} else if (udp_ep > -1) {
			useep = &ep[udp_ep];
			useua = ep[udp_ep].uaddr;
			type = SOCK_DGRAM;
		}

		if (useep == NULL) {
			msg("no acceptable transport endpoints.");
			if (needfree)
				free_eps(teps, tsrv.ep.ep_len);
			return (0);
		}
	}

	/*
	 * Create a sockaddr from the uaddr.
	 */
	if (*uaddr != NULL)
		useua = *uaddr;

	/* Fixup test for NIS+ */
	sscanf(useua, "%d.%d.%d.%d.", &a1, &a2, &a3, &a4);
	sprintf(ipuaddr, "%d.%d.%d.%d.0.111", a1, a2, a3, a4);
	useua = &ipuaddr[0];

	bzero((char *)&sin, sizeof(sin));
	if (uaddr_to_sockaddr(useua, &sin)) {
		msg("unable to translate uaddr to sockaddr.");
		if (needfree)
			free_eps(teps, tsrv.ep.ep_len);
		return (0);
	}

	/*
	 * Create the client handle to rpcbind. Note we always try
	 * version 3 since that is the earliest version that supports
	 * the RPCB_GETTIME call. Also it is the version that comes
	 * standard with SVR4. Since most everyone supports TCP/IP
	 * we could consider trying the rtime call first.
	 */
	clnt = clnttcp_create(&sin, RPCBPROG, RPCBVERS, &s, 0, 0);
	if (clnt == NULL) {
		msg("unable to create client handle to rpcbind.");
		if (needfree)
			free_eps(teps, tsrv.ep.ep_len);
		return (0);
	}

	tv.tv_sec = 5;
	tv.tv_usec = 0;
	time_valid = 0;
	status = clnt_call(clnt, RPCBPROC_GETTIME, (xdrproc_t)xdr_void, NULL,
					(xdrproc_t)xdr_u_long, &thetime, tv);
	/*
	 * The only error we check for is anything but success. In
	 * fact we could have seen PROGMISMATCH if talking to a 4.1
	 * machine (pmap v2) or TIMEDOUT if the net was busy.
	 */
	if (status == RPC_SUCCESS)
		time_valid = 1;
	else {
		int save;

		/* Blow away possible stale CLNT handle. */
		if (clnt != NULL) {
			clnt_destroy(clnt);
			clnt = NULL;
		}

		/*
		 * Convert PMAP address into timeservice address
		 * We take advantage of the fact that we "know" what
		 * the universal address looks like for inet transports.
		 *
		 * We also know that the internet timeservice is always
		 * listening on port 37.
		 */
		sscanf(useua, "%d.%d.%d.%d.", &a1, &a2, &a3, &a4);
		sprintf(ut, "%d.%d.%d.%d.0.37", a1, a2, a3, a4);

		if (uaddr_to_sockaddr(ut, &sin)) {
			msg("cannot convert timeservice uaddr to sockaddr.");
			goto error;
		}

		s = _socket(AF_INET, type, 0);
		if (s == -1) {
			msg("unable to open fd to network.");
			goto error;
		}

		/*
		 * Now depending on whether or not we're talking to
		 * UDP we set a timeout or not.
		 */
		if (type == SOCK_DGRAM) {
			struct timeval timeout = { 20, 0 };
			struct sockaddr_in from;
			fd_set readfds;
			int res;

			if (_sendto(s, &thetime, sizeof(thetime), 0,
				(struct sockaddr *)&sin, sizeof(sin)) == -1) {
				msg("udp : sendto failed.");
				goto error;
			}
			do {
				FD_ZERO(&readfds);
				FD_SET(s, &readfds);
				res = _select(_rpc_dtablesize(), &readfds,
				     NULL, NULL, &timeout);
			} while (res < 0 && errno == EINTR);
			if (res <= 0)
				goto error;
			len = sizeof(from);
			res = _recvfrom(s, (char *)&thetime, sizeof(thetime), 0,
				       (struct sockaddr *)&from, &len);
			if (res == -1) {
				msg("recvfrom failed on udp transport.");
				goto error;
			}
			time_valid = 1;
		} else {
			int res;

			oldsig = (void (*)())signal(SIGALRM, alarm_hndler);
			saw_alarm = 0; /* global tracking the alarm */
			alarm(20); /* only wait 20 seconds */
			res = _connect(s, (struct sockaddr *)&sin, sizeof(sin));
			if (res == -1) {
				msg("failed to connect to tcp endpoint.");
				goto error;
			}
			if (saw_alarm) {
				msg("alarm caught it, must be unreachable.");
				goto error;
			}
			res = _read(s, (char *)&thetime, sizeof(thetime));
			if (res != sizeof(thetime)) {
				if (saw_alarm)
					msg("timed out TCP call.");
				else
					msg("wrong size of results returned");

				goto error;
			}
			time_valid = 1;
		}
		save = errno;
		_close(s);
		errno = save;
		s = RPC_ANYSOCK;

		if (time_valid) {
			thetime = ntohl(thetime);
			thetime = thetime - TOFFSET; /* adjust to UNIX time */
		} else
			thetime = 0;
	}

	gettimeofday(&tv, 0);

error:
	/*
	 * clean up our allocated data structures.
	 */

	if (s != RPC_ANYSOCK)
		_close(s);

	if (clnt != NULL)
		clnt_destroy(clnt);

	alarm(0);	/* reset that alarm if its outstanding */
	if (oldsig) {
		signal(SIGALRM, oldsig);
	}

	/*
	 * note, don't free uaddr strings until after we've made a
	 * copy of them.
	 */
	if (time_valid) {
		if (*uaddr == NULL)
			*uaddr = strdup(useua);

		/* Round to the nearest second */
		tv.tv_sec += (tv.tv_sec > 500000) ? 1 : 0;
		delta = (thetime > tv.tv_sec) ? thetime - tv.tv_sec :
						tv.tv_sec - thetime;
		td->tv_sec = (thetime < tv.tv_sec) ? - delta : delta;
		td->tv_usec = 0;
	} else {
		msg("unable to get the server's time.");
	}

	if (needfree)
		free_eps(teps, tsrv.ep.ep_len);

	return (time_valid);
}
Esempio n. 10
0
/*
 * tftp发送
 * 如果fname为目录, 将发送"ls -l fname"的内容
 */
int send_file(char *fname, struct sockaddr_in *peer)
{
	FILE *fp = NULL;
	int sd;
	TFTP_DAT dat;
	TFTP_ERR *err;
	TFTP_ACK *ack;
	char buff[512];
	int ret, len;
	u_int16_t blkno;
	u_int16_t opcode;
	struct stat st;

	LOGPRINT("send file:%s\n", fname);

	sd = socket(PF_INET, SOCK_DGRAM, 0);
	if(sd == -1)
	{
		LOGPRINT("sockdt:%s\n", errstr());
		return -1;
	}

	if( stat(fname, &st) == 0)
	{
		if( S_ISDIR(st.st_mode) )
		{
			sprintf(buff, "ls -l '%s'", fname);
			fp = popen(buff, "r");
			fgets(buff, sizeof(buff), fp);	//第一行为"总计 xxx",去掉
		}
		else
		{
			sprintf(buff, "%s", fname);
			fp = fopen(buff, "r");
		}
	}

	if(fp == NULL)
	{
		err = (TFTP_ERR*)buff;
		err->opcode = htons(TFTP_ERROR);
		err->err_no = htons(TFTP_FILE_NOT_FOUND);
		strcpy(err->errstr, errstr());
		
		sendto(sd, err, strlen(err->errstr)+1+4, 0,
			(struct sockaddr*)peer, sizeof(struct sockaddr_in));	

		close(sd);
		return 0;
	}

	blkno = 1;
	dat.blkno = 0;
	while(1)
	{
		if(dat.blkno != htons(blkno) )
		{
			dat.blkno = htons(blkno);
			dat.opcode = htons(TFTP_FILEDATA);

			len = fread(dat.dat, 1, sizeof(dat.dat), fp);
		}

		ret = _sendto(sd, &dat, len+4, peer);
		if( ret == -1)
		{
			LOGPRINT("timeout\n");
			ret = -1;
			goto quit;
		}

		recvfrom(sd, buff, ret, 0, NULL, NULL);

		opcode = ntohs( *(u_int16_t*)buff );
		switch(opcode)
		{
		case TFTP_DATACK:
			ack = (TFTP_ACK*)buff;
			ack->blkno = ntohs(ack->blkno);
			if(ack->blkno == blkno)
			{
				blkno += 1;
			}
			break;

		case TFTP_ERROR:
			err = (TFTP_ERR*)buff;
			err->err_no = ntohs(err->err_no);
			LOGPRINT("Error[%d]:%s\n", err->err_no, err->errstr);
			ret =  -err->err_no;
			goto quit;

		default:
			LOGPRINT("未知包[%d]\n", opcode);
			ret = -1;
			goto quit;
		}

		if(len < 512) 
			break;
	}

	ret = 0;
quit:
	close(sd);
	if( S_ISDIR(st.st_mode) ) pclose(fp);
	else fclose(fp);

	LOGPRINT("send block:%d\n", blkno);
	return ret;
}
Esempio n. 11
0
/*
********************************************************************************
*              MAKE DNS QUERY AND PARSE THE REPLY
*
* Description : This function makes DNS query message and parses the reply from DNS server.
* Arguments   : name - is a pointer to the domain name.
* Returns     : if succeeds : 1, fails : -1
* Note        :
********************************************************************************
*/
int DNS::query(char *name)
{
    int state;
    static uint32_t dns_wait_time = 0;
    struct dhdr dhp;
    uint8_t ip[4];
    uint16_t len, port;
    uint8_t dns_server_ip[4];
    uint8_t BUFPUB[100];

    get_local_dns(dns_server_ip);
    len = makequery(0, (uint8_t *)name, BUFPUB, MAX_DNS_BUF_SIZE);
    DNS_DBG("ÓòÃû:[%s]\r\n", name);
    DNS_DBG("ÓòÃû½âÎöÖÐ...\r\n");

    while(1)
    {
        state = socket_status(s);
        if(state == SOCK_CLOSED)
        {
            DNS_DBG("dns's socket closed!,socket: %d\r\n", s);
            DNS_DBG("openning dns's socket... !\r\n");
            if(_socket(s, Sn_MR_UDP, port, 0) == 1)
                DNS_DBG("open dns's socket seccusse!\r\n");
        }

        if(state == SOCK_UDP)
        {
            DNS_DBG("sending query cmd...\r\n");
            if(_sendto(s, BUFPUB, len, dns_server_ip, IPPORT_DOMAIN) > 0)
                DNS_DBG("send dns cmd ok!\r\n");

            if ((len = recv_available(s)) > 0)
            {
                if (len > MAX_DNS_BUF_SIZE)
                {
                    len = MAX_DNS_BUF_SIZE;
                }
                len = _recvfrom(s, BUFPUB, len, ip, &port);
                DNS_DBG("receiv dns's date ok!datelen:%d\r\n", len);
                if(parseMSG(&dhp, BUFPUB))
                {
                    _close(s);
                    DNS_DBG("query is ok!\r\n");
                    return 1;
                }
                else
                {
                    DNS_DBG("dns's date is bad!\r\n");
                    return -1;
                }
            }
            else
            {
                DNS_DBG("wait dns's date...!\r\n");
                delay_ms(1000);
                dns_wait_time++;
            }
            if(dns_wait_time >= 3)
            {
                _close(s);
                return -2;
            }
        }
    };
}