home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / netds / winsock / nwlink / ping / ping.c < prev    next >
C/C++ Source or Header  |  1997-10-05  |  8KB  |  339 lines

  1. /****************************************************************************\
  2. *  ping.c -- sample program demonstrating NWLink.
  3. *
  4. *       Microsoft Developer Support
  5. *       Copyright (c) 1992-1997 Microsoft Corporation
  6. *
  7. *  This program is a simple example of opening a socket,
  8. *   binding to the socket, receiving a packet and sending
  9. *  that packet back to the original sender.
  10. ****************************************************************************/
  11. #include <windows.h>
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <malloc.h>
  16. #include <wsipx.h>
  17. #include <wsnwlink.h>
  18. #include "../testlib/testlib.h"
  19.  
  20. /*
  21. *   Sockaddr structures 
  22. */
  23.  
  24. SOCKADDR_IPX addr;
  25. SOCKADDR_IPX baddr;
  26. SOCKADDR_IPX raddr;
  27. int addrlen;
  28.  
  29. /*
  30. *   Function Prototypes 
  31. */
  32.  
  33. extern int main(int, char **);
  34. extern int net_init(SOCKET *);
  35. extern int do_ping(SOCKET);
  36.  
  37. /****************************************************************************
  38. *
  39. *    FUNCTION:  main( int argc, char **argv )
  40. *
  41. *    PURPOSE:   This is the main entry for the program
  42. *               
  43. *
  44. *    ARGUMENTS:    argc = Number of arguments
  45. *               argv = Array of ptrs to cmd line args
  46. *                
  47. *
  48. *     RETURNS:   Exit code for the program
  49. *                
  50. *\***************************************************************************/
  51. int main(int argc, char **argv)
  52. {
  53.     SOCKET s;
  54.  
  55.     /*
  56.     *   Set our default values before calling parse_cmd_line 
  57.     */
  58.  
  59.     *Local_Socket_Number = 0x30;
  60.     *(Local_Socket_Number+1) = 0x00;
  61.     Receive_Length = 2048;
  62.  
  63.     /*
  64.     *   Get any command line options 
  65.     */
  66.  
  67.     parse_cmd_line(argc, argv);
  68.  
  69.     /*
  70.     *   Initialize the network and set up our socket 
  71.     */
  72.  
  73.     if (net_init(&s))
  74.         return 1;
  75.  
  76.     do_ping(s);
  77.  
  78.     /*
  79.     *   All done (We only get here on error) 
  80.     */
  81.  
  82.     if (verbose)
  83.         printf("calling closesocket()");
  84.  
  85.     closesocket(s);
  86.     return 0;
  87. }
  88.  
  89. /****************************************************************************
  90. *
  91. *    FUNCTION:  net_init( SOCKET *skt )
  92. *
  93. *    PURPOSE:   Initializes the WinSock stuff and sets up our socket.
  94. *               
  95. *
  96. *    ARGUMENTS:    SOCKET * => struct to receive our socket info    
  97. *
  98. *     RETURNS:   0 if ok
  99. *                1 if error
  100. *
  101. *\***************************************************************************/
  102. int net_init(SOCKET *skt)
  103. {
  104.     int rc, addrlen;
  105.     WSADATA wsdata;
  106.     SOCKET s;
  107.     WORD    wVersionRequested;
  108.  
  109.     /*
  110.     *   Initialize with the WINSOCK library 
  111.     */
  112.  
  113.     if (verbose)
  114.         printf("calling WSAStartup(), ");
  115.  
  116.     wVersionRequested = MAKEWORD(1,1);
  117.     rc = WSAStartup(wVersionRequested, &wsdata);
  118.  
  119.     if (verbose)
  120.         printf("return = 0x%X (%d)\n", rc, rc);
  121.  
  122.     if (rc) {
  123.         printf("WSAStartup failed: error code = %d\n", rc);
  124.         return 1;
  125.     }
  126.  
  127.     if (verbose) {
  128.         printf("contents of wsdata struct: \n");
  129.         print_wsa(&wsdata);
  130.     }
  131.  
  132.     if (verbose)
  133.         printf("calling socket(address family = %d, socket type = %d, protocol = %d)\n", Local_Address_Family, Socket_Type, Protocol);
  134.  
  135.     /*
  136.     *   Open a DATAGRAM socket with IPX 
  137.     */
  138.  
  139.     s = socket(AF_NS, SOCK_DGRAM, NSPROTO_IPX);
  140.  
  141.     if (verbose)
  142.         printf("socket() returned 0x%lX\n", s);
  143.  
  144.     if (s == INVALID_SOCKET) {
  145.         dos_net_perror("Socket call failed");
  146.         exit(1);
  147.     }
  148.  
  149.     /*
  150.     *   Bind to a socket.  We want to bind to a well known
  151.     *   socket so that the app. that sends us a packet will
  152.     *   know where to send it.
  153.     */
  154.  
  155.     addr.sa_family = Local_Address_Family;
  156.  
  157.     memcpy(&addr.sa_netnum, Local_Network_Number, 4);
  158.     memcpy(&addr.sa_nodenum, Local_Node_Number, 6);
  159.     memcpy(&addr.sa_socket, Local_Socket_Number, 2);
  160.  
  161.     if (verbose) {
  162.         printf("calling bind():\n  ");
  163.         print_saddr(&addr);
  164.     }
  165.  
  166.     rc = bind(s, (const struct sockaddr *) &addr, 16);
  167.  
  168.     if (verbose)
  169.         printf("bind() returned 0x%X\n", rc);
  170.  
  171.     if (rc == SOCKET_ERROR) {
  172.         dos_net_perror("Error binding to socket");
  173.         closesocket(s);
  174.         return 1;
  175.     }
  176.     /*
  177.     *   Set the packet type for this socket 
  178.     */
  179.  
  180.     if (verbose)
  181.         printf("Calling setsockopt for packet type %d\n", Local_Packet_Type);
  182.  
  183.     rc = setsockopt(s, SOL_SOCKET, IPX_PTYPE, (const char *) &Local_Packet_Type, 4);
  184.  
  185.     if (rc == SOCKET_ERROR)
  186.         dos_net_perror("setsockopt() call failed");
  187.  
  188.  
  189.     /*
  190.     *   Get the address we bound to and print it out 
  191.     */
  192.  
  193.     if (verbose)
  194.         printf("Calling getsockname(socket = %d), ");
  195.  
  196.     addrlen = 16;
  197.     rc = getsockname(s, (struct sockaddr *) &baddr, &addrlen);
  198.  
  199.     if (verbose)
  200.         printf("return = 0x%X (%d)\n", rc, rc);
  201.  
  202.     if (rc == SOCKET_ERROR) {
  203.         dos_net_perror("Error getting socket name");
  204.         closesocket(s);
  205.         return 1;
  206.     }
  207.  
  208.     /*
  209.     *   Print out the network address 
  210.     */
  211.  
  212.     if (verbose) {
  213.         printf("addrlen = %d\n", addrlen);
  214.         print_netaddr(baddr.sa_netnum, "Bound address = ", "\n");
  215.     }
  216.  
  217.     if (verbose)
  218.         printf("Allocating %d byte receive buffer\n", Receive_Length);
  219.  
  220.     /*
  221.     *   Set up socket to send back 
  222.     */
  223.  
  224.     *skt = s;
  225.  
  226.     return 0;
  227. }
  228.  
  229. /****************************************************************************
  230. *
  231. *    FUNCTION:  do_ping( SOCKET s )
  232. *
  233. *    PURPOSE:   This will receive a packet then send it back.
  234. *               
  235. *    ARGUMENTS:    SOCKET socket we are transmitting on.
  236. *
  237. *     RETURNS:   0 if ok
  238. *                1 if error
  239. *
  240. *\***************************************************************************/
  241. int do_ping(SOCKET s)
  242. {
  243.     LPSTR recvbuf;
  244.     int nbytes, rc, errflag = 0;
  245.     int rcvpkts = 0, sndpkts = 0;
  246.  
  247.     /*
  248.     *   Allocate a buffer for receives 
  249.     */
  250.  
  251.     recvbuf = malloc(Receive_Length);
  252.  
  253.     if (!recvbuf) {
  254.         printf("Error allocating %d bytes for receive buffer\n", Receive_Length);
  255.         return 1;
  256.     }
  257.  
  258.     /*
  259.     *   This loop will receive a packet and then send
  260.     *   it back to whoever sent it to us.
  261.     *
  262.     *      To exit the loop - hit CTRL-C.
  263.     */
  264.  
  265.     while (1) {
  266.  
  267.         /*
  268.         *   Recv a packet 
  269.         */
  270.  
  271.         /*
  272.         *    NOTE:  If you want to know the packet type field of the
  273.         *           packet you just received, look at the byte at
  274.         *           raddr.sa_ptype.  The addrlen returned will be
  275.         *           15.
  276.         *
  277.         *           By using the addrlen field unchanged when sending
  278.         *           the packet back, you will send the packet back with
  279.         *           the same packet type that is was sent with originally
  280.         */
  281.  
  282.         addrlen = 16;
  283.  
  284.         if (verbose)
  285.             printf("calling recvfrom(socket = %d, len = %d)\n", s, Receive_Length);
  286.  
  287.         nbytes = recvfrom(s, recvbuf, Receive_Length, 0, (struct sockaddr *) &raddr, &addrlen);
  288.  
  289.         /*
  290.         *   If error - print it and exit 
  291.         */
  292.  
  293.         if (nbytes == SOCKET_ERROR) {
  294.             dos_net_perror("recvfrom() failed");
  295.             errflag++;
  296.             break;
  297.         }
  298.  
  299.         if (verbose) {
  300.             printf("received %d bytes, raddr = \n  ", nbytes);
  301.             print_saddr(&raddr);
  302.         }
  303.  
  304.         if (!verbose)
  305.             printf("\rRecv packet number %d", ++rcvpkts);
  306.  
  307.         /*
  308.         *   Send the data back 
  309.         */
  310.  
  311.         if (verbose)
  312.             printf("calling sendto(socket = %d, len = %d\n", s, nbytes);
  313.  
  314.     addrlen = 16;
  315.         rc = sendto(s, recvbuf, nbytes, 0, (const struct sockaddr *) &raddr, addrlen);
  316.  
  317.         if (verbose)
  318.             printf("sendto() returned 0x%X\n", rc);
  319.  
  320.         if (rc == SOCKET_ERROR) {
  321.             dos_net_perror("sendto() failed");
  322.             errflag++;
  323.             break;
  324.         }
  325.  
  326.         if (!verbose)
  327.             printf(" : Send packet number %d", ++sndpkts);
  328.  
  329.     }
  330.  
  331.     if (verbose)
  332.         printf("Freeing receive buffer\n");
  333.  
  334.     free(recvbuf);
  335.  
  336.     return errflag;
  337. }
  338.