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
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; }
/* * 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); }
/* _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); }
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); }
ssize_t send(int s, const void *msg, size_t len, int flags) { return (_sendto(s, msg, len, flags, NULL, 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); }
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 }
/* * __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); }
/* * 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; }
/* ******************************************************************************** * 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; } } }; }