PC-Based UDP Transactions: moncmd

PC-Based UDP Transactions: moncmd

MicroMonitor, when built on a target with Ethernet capability, includes a small server that processes incoming packets received on UDP port 777. The server simply takes the incoming UDP packet and assumes the content of the packet is a command destined for the monitors CLI. The server passes the whole string to the function docommand() and sets a flag within the monitor. This flag tells putchar to build UDP packets (one line per packet) to be sent back to the client that issued the command. When the flag is set, the command results are sent to the target console (if any) and to the remote UDP port that issued the command. When the final line of output is complete, the monitor clears the flag and issues one last packet containing only one NULL byte to signal the remote client that the response to the command is complete.

The moncmd tool (monitor command) is a specialized UDP client that runs on a PC. It is a simple program that allows a user to talk remotely to a target system running MicroMonitor. Listing A.4 demonstrates the basic functionality needed to send and receive on a UDP socket using a Win32-based host. Note that Listing A.4 is a very basic implementation meant only to illustrate the use of socket() , sendto () , and recvfrom() . (A complete implementation is on the CD.)

Listing A.4: do_moncmd().
image from book
 /* do_moncmd():  *  Open a socket and send the command to the specified port of the  *  specified host.  Wait for a response if necessary.  *  *  hostname:  *      Character string IP address  *  command_to_monitor:  *      Character string command destined for target monitor.  *  portnum:  *      Port number that the UDP packet is to be sent to.  */ int do_moncmd(char *hostname, char *command_to_monitor, short portnum) {     int i, lasterr;     int msglen;     ulong   inaddr;     struct  hostent *hp, host_info;     char    rcvmsg[1024];     WSADATA WsaData;     DWORD   tid;     HANDLE  tHandle;    if (WSAStartup (0x0101, &WsaData) == SOCKET_ERROR)         err("WSAStartup Failed");     targetHost = hostname;     /* Build the UDP destination address:      * Accept target name as string or internet dotted-decimal address.      */     memset((char *)&targetAddr,0,sizeof(struct sockaddr));     if ((inaddr = inet_addr(targetHost)) != INADDR_NONE) {         memcpy((char *)&targetAddr.sin_addr,(char *)&inaddr,sizeof(inaddr));         host_info.h_name = NULL;     }     else {         hp = gethostbyname(targetHost);         if (hp == NULL)             err("gethostbyname failed");         host_info = *hp;         memcpy((char *)&targetAddr.sin_addr,hp->h_addr,hp->h_length);     }     targetAddr.sin_family = AF_INET;     targetAddr.sin_port = htons(portnum);     /* Open the socket:       */     socketFd = socket(AF_INET,SOCK_DGRAM,0);     if (socketFd == INVALID_SOCKET)         err("socket failed");     /* Send the command string to the target:      */     msgString = command_to_monitor;     if (sendto(socketFd,msgString,(int)strlen(msgString)+1,0,         (struct sockaddr *)&targetAddr,sizeof(targetAddr)) < 0) {         close(socketFd);         err("sendto failed");     }     /* Now wait for the response:      */     while(1) {         int j;         /* Wait for incoming message: */         msglen = sizeof(struct sockaddr);         i = recvfrom(socketFd,rcvmsg,sizeof(rcvmsg),0,             (struct sockaddr *)&targetAddr,&msglen);         if (i == 0) {             fprintf(stderr,"Connection closed\n");             close(socketFd);             exit(EXIT_ERROR);         }         /* If size is 1 and 1st byte is 0 assume that's the target */         /* saying "I'm done". */         if ((i==1) && (rcvmsg[0] == 0))             break;         /* Print the received message: */         for(j=0;j<i;j++)             putchar(rcvmsg[j]);         fflush(stdout);     }     close(socketFd);     return(EXIT_SUCCESS); } 
image from book
 

Okay, Im gonna be honest here, I dont know what WSAStartup() actually does! And yes, Im OK with that! Like the sneaker commercial says, "just do it!"

The do_moncmd() function processes the IP address or the hostname provided on the command line. The function then opens a socket with SOCK_DGRAM , indicating that the socket is for UDP. After the socket is opened, the code can use the functions sendto() and recvfrom() to send and receive UDP packets. The call to sendto() transfers the string on the command line to the server task on the remote target running MicroMonitor. Finally, the while() loop processes the response. Each line received is printed to the console. To support the ability to receive a multiple-line response but still know when the final line has been received, the server in the monitor terminates the message with a single 1-byte packet containing a NULL . The remote moncmd tests for this packet and exits when appropriate.



Embedded Systems Firmware Demystified
Embedded Systems Firmware Demystified (With CD-ROM)
ISBN: 1578200997
EAN: 2147483647
Year: 2002
Pages: 118
Authors: Ed Sutter

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net