/****************************************************************************\
* dgsend.c -- sample program demonstrating NWLink.
*
* Microsoft Developer Support
* Copyright 1992 - 1998 Microsoft Corporation
*
* This program is a simple example of opening a socket,
* binding to the socket, and sending a packet repeatedly.
*
****************************************************************************/
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <wsipx.h>
#include <wsnwlink.h>
#include "..\testlib\testlib.h"
/*
* Sockaddr structures
*/
SOCKADDR_IPX addr;
SOCKADDR_IPX baddr;
SOCKADDR_IPX saddr;
/*
* Data for sending
*/
char send_data[] = "This is an IPX packet from NT";
/*
* Function Prototypes
*/
extern int main(int, char **);
extern int net_init(SOCKET *);
extern int enable_broadcasts(SOCKET);
extern void build_dest_addr(SOCKET, PSOCKADDR_IPX);
extern int dg_send(SOCKET);
/****************************************************************************
*
* FUNCTION: main( int argc, char **argv )
*
* PURPOSE: This is the main entry for the program
*
*
* ARGUMENTS:argc = Number of arguments
* argv = Array of ptrs to cmd line args
*
*
* RETURNS: Exit code for the program
*
*\***************************************************************************/
int main(int argc, char **argv)
{
SOCKET s;
/*
* Fill in any default values before checking the command line
*/
*Remote_Socket_Number = 0x06;
*(Remote_Socket_Number+1) = 0x00;
Sleep_Time = 500;
/*
* Parse the command line to set up any command line options
*/
parse_cmd_line(argc, argv);
if (net_init(&s))
return 1;
if (!No_Broadcast) {
if (enable_broadcasts(s))
return 1;
}
build_dest_addr(s, &saddr);
/*
* Send some datagrams
*/
dg_send(s);
/*
* All Done - Close up the socket and exit
*/
if (verbose)
printf("Calling closesocket()\n");
closesocket(s);
return 0;
}
/****************************************************************************
*
* FUNCTION: net_init( SOCKET *skt )
*
* PURPOSE: Initializes the WinSock stuff and sets up our socket.
*
*
* ARGUMENTS:SOCKET * => struct to receive our socket info
*
* RETURNS: 0 if ok
*1 if error
*
*\***************************************************************************/
int net_init(SOCKET *skt)
{
SOCKET s;
WSADATA wsdata;
WORD wVersionRequested;
int rc, addrlen = 16;
if (verbose)
printf("Calling WSAStartup(), ");
/*
* Initialize with the WINSOCK library
*/
wVersionRequested = MAKEWORD(1,1);
rc = WSAStartup(wVersionRequested, &wsdata);
if (verbose)
printf("return = 0x%X (%d)\n", rc, rc);
if (rc) {
printf("WSAStartup failed: error code = %d\n", rc);
return 1;
}
if (verbose) {
printf("Contents of wsadata struct:\n");
print_wsa(&wsdata);
}
/*
* Open a DATAGRAM socket with IPX
*/
if (verbose)
printf("Calling socket(address family = %d, socket type = %d, protocol = %d)\n", Local_Address_Family, Socket_Type, Protocol);
s = socket(Local_Address_Family, Socket_Type, Protocol);
if (verbose)
printf("socket() returned 0x%X (%d)\n", s, s);
if (s == INVALID_SOCKET) {
dos_net_perror("Socket call failed");
exit(1);
}
/*
* Bind to a socket. We dont care what socket we bind to,
* so we will send down all 0's
*/
addr.sa_family = Local_Address_Family;
memcpy(&addr.sa_netnum, Local_Network_Number, 4);
memcpy(&addr.sa_nodenum, Local_Node_Number, 6);
memcpy(&addr.sa_socket, Local_Socket_Number, 2);
if (verbose) {
printf("calling bind(), local address =\n ");
print_saddr(&addr);
}
rc = bind(s, (const struct sockaddr *) &addr, 16);
if (verbose)
printf("\nbind() returned 0x%X (%d)\n", rc, rc);
if (rc == SOCKET_ERROR) {
dos_net_perror("Error binding to socket");
printf("Socket = 0x%lx\n", s);
closesocket(s);
return 1;
}
/*
* Get the address we bound to and print it out
*/
if (verbose)
printf("calling getsockname(socket = %d), ", s);
rc = getsockname(s, (struct sockaddr *) &baddr, &addrlen);
if (verbose)
printf("return = 0x%lX (%d)\n", rc, rc);
if (rc == SOCKET_ERROR) {
dos_net_perror("Error getting socket name");
closesocket(s);
return 1;
}
/*
* Set the packet type for this socket
*/
if (verbose)
printf("Calling setsockopt for packet type %d\n", Local_Packet_Type);
rc = setsockopt(s, NSPROTO_IPX, IPX_PTYPE, (const char *) &Local_Packet_Type, 4);
if (rc == SOCKET_ERROR)
dos_net_perror("setsockopt() call failed");
/*
* Print out the network address
*/
if (verbose) {
printf("addrlen = %d\n", addrlen);
print_netaddr(baddr.sa_netnum, " Bound to address ", "\n");
}
*skt = s;
return 0;
}
/****************************************************************************
*
* FUNCTION: enable_broadcasts( SOCKET s )
*
* PURPOSE: Sets the socket option to enable broadcast sends on it.
*
*
* ARGUMENTS:SOCKET socket to enable
*
* RETURNS: 0 if ok
*1 if error
*
*\***************************************************************************/
int enable_broadcasts(SOCKET s)
{
int rc;
BOOL optval = TRUE;
/*
* Enable sending of broadcasts
*/
/*
* NOTE: This only needs to be done if you want to SEND
* broadcast packets. Reception of broadcast
* packets will happen automatically.
*/
if (verbose)
printf("Setting socket option to broadcast, ");
rc = setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char *)&optval, sizeof(int));
if (verbose)
printf("return = 0x%X (%d)\n", rc, rc);
if (rc == SOCKET_ERROR) {
dos_net_perror("Error enabling broadcast address");
closesocket(s);
return 1;
}
return 0;
}
/****************************************************************************
*
* FUNCTION: build_dest_addr( SOCKET s )
*
* PURPOSE: Fills in the destination address fields and sets the packet type.
*
*
* ARGUMENTS:SOCKET socket to set packet type for
*PSOCKADDR_NS => address struct to fill in
*
* RETURNS: 0 if ok
*1 if error
*
*\***************************************************************************/
void build_dest_addr(SOCKET s, PSOCKADDR_IPX psaddr)
{
int rc;
/*
* Build the dest. address
*/
psaddr->sa_family = Remote_Address_Family;
/*
* Set dest. network number
*/
memcpy(&psaddr->sa_netnum, Remote_Network_Number, 4);
/*
* Set dest. node address
*/
memcpy(&psaddr->sa_nodenum, Remote_Node_Number, 6);
/*
* Set the dest. socket number
*/
memcpy(&psaddr->sa_socket, Remote_Socket_Number, 2);
/*
* Set the packet type for this socket
*/
if (verbose)
printf("Calling setsockopt for packet type %d\n", Send_Packet_Type);
rc = setsockopt(s, NSPROTO_IPX, IPX_PTYPE, (const char *) &Send_Packet_Type, sizeof(int));
if (rc == SOCKET_ERROR)
dos_net_perror("setsockopt() call failed");
return;
}
/****************************************************************************
*
* FUNCTION: dg_send( SOCKET s )
*
* PURPOSE: Receives datagrams.
*
* ARGUMENTS:SOCKET socket to transmit on
*
* RETURNS: 0 if ok
* 1 if error
*
*\***************************************************************************/
int dg_send(SOCKET s)
{
LPSTR sendbuf;
int rc, errflag = 0;
UINT dgrms = 0;
if (verbose)
printf("allocating %d bytes for send buffer\n", Send_Length);
/*
* Set up the data buffer to send
*/
sendbuf = (LPSTR)malloc(Send_Length);
if (!sendbuf) {
printf("Error allocating %d bytes for send buffer\n", Send_Length);
return 1;
}
/*
* Zero the buffer and copy as much of our data to it as possible
*/
memset(sendbuf, 0, Send_Length);
strncpy(sendbuf, send_data, Send_Length);
while (1) {
if (verbose) {
printf("calling sendto(socket = %d, length = %d),\n", s, Send_Length);
printf("destination address:\n ");
print_saddr(&saddr);
}
/*
* Send a packet to everybody
*/
rc = sendto(s, sendbuf, Send_Length, 0, (const struct sockaddr *) &saddr, 16);
if (verbose)
printf("\nsendto() returned %d\n", rc);
if (rc == SOCKET_ERROR) {
dos_net_perror("Sendto() failed");
errflag++;
break;
}
else {
printf("\rSent datagram %d, length = %d bytes", ++dgrms, rc);
if (verbose)
printf("\n");
}
/*
* If we are to send only one, break out
*/
if (No_Loop)
break;
/*
* Sleep for a little while so we don't bombard the network
*/
Sleep(Sleep_Time);
}
if (verbose)
printf("Freeing send buffer\n");
free(sendbuf);
return errflag;
}