|
|
1.1 root 1: /****************************************************************************\
2: * dgsend.c -- sample program demonstrating NWLink.
3: *
4: * Microsoft Developer Support
5: * Copyright (c) 1992, 1993 Microsoft Corporation
6: *
7: * This program is a simple example of opening a socket,
8: * binding to the socket, and sending a packet repeatedly.
9: *
10: ****************************************************************************/
11: #include <windows.h>
12: #include <winsock.h>
13: #include <stdio.h>
14: #include <stdlib.h>
15: #include <string.h>
16: #include <malloc.h>
17: #include <wsipx.h>
18: #include <wsnwlink.h>
19: #include "..\testlib\testlib.h"
20:
21: /*
22: * Sockaddr structures
23: */
24:
25: SOCKADDR_IPX addr;
26: SOCKADDR_IPX baddr;
27: SOCKADDR_IPX saddr;
28:
29: /*
30: * Data for sending
31: */
32:
33: char send_data[] = "This is an IPX packet from NT";
34:
35: /*
36: * Function Prototypes
37: */
38: extern int main(int, char **);
39: extern int net_init(SOCKET *);
40: extern int enable_broadcasts(SOCKET);
41: extern void build_dest_addr(SOCKET, PSOCKADDR_IPX);
42: extern int dg_send(SOCKET);
43:
44: /****************************************************************************
45: *
46: * FUNCTION: main( int argc, char **argv )
47: *
48: * PURPOSE: This is the main entry for the program
49: *
50: *
51: * ARGUMENTS: argc = Number of arguments
52: * argv = Array of ptrs to cmd line args
53: *
54: *
55: * RETURNS: Exit code for the program
56: *
57: *\***************************************************************************/
58: int main(int argc, char **argv)
59: {
60: SOCKET s;
61:
62: /*
63: * Fill in any default values before checking the command line
64: */
65:
66: *Remote_Socket_Number = 0x06;
67: *(Remote_Socket_Number+1) = 0x00;
68: Sleep_Time = 500;
69:
70: /*
71: * Parse the command line to set up any command line options
72: */
73:
74: parse_cmd_line(argc, argv);
75:
76: if (net_init(&s))
77: return 1;
78:
79: if (!No_Broadcast) {
80: if (enable_broadcasts(s))
81: return 1;
82: }
83:
84: build_dest_addr(s, &saddr);
85:
86: /*
87: * Send some datagrams
88: */
89:
90: dg_send(s);
91:
92: /*
93: * All Done - Close up the socket and exit
94: */
95:
96: if (verbose)
97: printf("Calling closesocket()\n");
98:
99: closesocket(s);
100: return 0;
101: }
102:
103: /****************************************************************************
104: *
105: * FUNCTION: net_init( SOCKET *skt )
106: *
107: * PURPOSE: Initializes the WinSock stuff and sets up our socket.
108: *
109: *
110: * ARGUMENTS: SOCKET * => struct to receive our socket info
111: *
112: * RETURNS: 0 if ok
113: * 1 if error
114: *
115: *\***************************************************************************/
116: int net_init(SOCKET *skt)
117: {
118: SOCKET s;
119: WSADATA wsdata;
120: WORD wVersionRequested;
121:
122:
123: int rc, addrlen = 16;
124:
125: if (verbose)
126: printf("Calling WSAStartup(), ");
127:
128: /*
129: * Initialize with the WINSOCK library
130: */
131:
132: wVersionRequested = MAKEWORD(1,1);
133: rc = WSAStartup(wVersionRequested, &wsdata);
134:
135: if (verbose)
136: printf("return = 0x%X (%d)\n", rc, rc);
137:
138: if (rc) {
139: printf("WSAStartup failed: error code = %d\n", rc);
140: return 1;
141: }
142:
143: if (verbose) {
144: printf("Contents of wsadata struct:\n");
145: print_wsa(&wsdata);
146: }
147:
148: /*
149: * Open a DATAGRAM socket with IPX
150: */
151:
152: if (verbose)
153: printf("Calling socket(address family = %d, socket type = %d, protocol = %d)\n", Local_Address_Family, Socket_Type, Protocol);
154:
155: s = socket(Local_Address_Family, Socket_Type, Protocol);
156:
157: if (verbose)
158: printf("socket() returned 0x%X (%d)\n", s, s);
159:
160: if (s == INVALID_SOCKET) {
161: dos_net_perror("Socket call failed");
162: exit(1);
163: }
164:
165: /*
166: * Bind to a socket. We dont care what socket we bind to,
167: * so we will send down all 0's
168: */
169:
170: addr.sa_family = Local_Address_Family;
171:
172: memcpy(&addr.sa_netnum, Local_Network_Number, 4);
173: memcpy(&addr.sa_nodenum, Local_Node_Number, 6);
174: memcpy(&addr.sa_socket, Local_Socket_Number, 2);
175:
176: if (verbose) {
177: printf("calling bind(), local address =\n ");
178: print_saddr(&addr);
179: }
180:
181: rc = bind(s, (const struct sockaddr *) &addr, 16);
182:
183: if (verbose)
184: printf("\nbind() returned 0x%X (%d)\n", rc, rc);
185:
186: if (rc == SOCKET_ERROR) {
187: dos_net_perror("Error binding to socket");
188: printf("Socket = 0x%lx\n", s);
189: closesocket(s);
190: return 1;
191: }
192:
193: /*
194: * Get the address we bound to and print it out
195: */
196:
197: if (verbose)
198: printf("calling getsockname(socket = %d), ", s);
199:
200: rc = getsockname(s, (struct sockaddr *) &baddr, &addrlen);
201:
202: if (verbose)
203: printf("return = 0x%lX (%d)\n", rc, rc);
204:
205: if (rc == SOCKET_ERROR) {
206: dos_net_perror("Error getting socket name");
207: closesocket(s);
208: return 1;
209: }
210:
211: /*
212: * Set the packet type for this socket
213: */
214:
215: if (verbose)
216: printf("Calling setsockopt for packet type %d\n", Local_Packet_Type);
217:
218: rc = setsockopt(s, NSPROTO_IPX, IPX_PTYPE, (const char *) &Local_Packet_Type, 4);
219:
220: if (rc == SOCKET_ERROR)
221: dos_net_perror("setsockopt() call failed");
222:
223: /*
224: * Print out the network address
225: */
226:
227: if (verbose) {
228: printf("addrlen = %d\n", addrlen);
229: print_netaddr(baddr.sa_netnum, " Bound to address ", "\n");
230: }
231:
232: *skt = s;
233:
234: return 0;
235: }
236:
237: /****************************************************************************
238: *
239: * FUNCTION: enable_broadcasts( SOCKET s )
240: *
241: * PURPOSE: Sets the socket option to enable broadcast sends on it.
242: *
243: *
244: * ARGUMENTS: SOCKET socket to enable
245: *
246: * RETURNS: 0 if ok
247: * 1 if error
248: *
249: *\***************************************************************************/
250: int enable_broadcasts(SOCKET s)
251: {
252: int rc;
253: BOOL optval = TRUE;
254:
255: /*
256: * Enable sending of broadcasts
257: */
258:
259: /*
260: * NOTE: This only needs to be done if you want to SEND
261: * broadcast packets. Reception of broadcast
262: * packets will happen automatically.
263: */
264:
265: if (verbose)
266: printf("Setting socket option to broadcast, ");
267: rc = setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char *)&optval, sizeof(int));
268: if (verbose)
269: printf("return = 0x%X (%d)\n", rc, rc);
270:
271: if (rc == SOCKET_ERROR) {
272: dos_net_perror("Error enabling broadcast address");
273: closesocket(s);
274: return 1;
275: }
276:
277: return 0;
278: }
279:
280: /****************************************************************************
281: *
282: * FUNCTION: build_dest_addr( SOCKET s )
283: *
284: * PURPOSE: Fills in the destination address fields and sets the packet type.
285: *
286: *
287: * ARGUMENTS: SOCKET socket to set packet type for
288: * PSOCKADDR_NS => address struct to fill in
289: *
290: * RETURNS: 0 if ok
291: * 1 if error
292: *
293: *\***************************************************************************/
294: void build_dest_addr(SOCKET s, PSOCKADDR_IPX psaddr)
295: {
296: int rc;
297:
298: /*
299: * Build the dest. address
300: */
301:
302: psaddr->sa_family = Remote_Address_Family;
303:
304: /*
305: * Set dest. network number
306: */
307:
308: memcpy(&psaddr->sa_netnum, Remote_Network_Number, 4);
309:
310: /*
311: * Set dest. node address
312: */
313:
314: memcpy(&psaddr->sa_nodenum, Remote_Node_Number, 6);
315:
316: /*
317: * Set the dest. socket number
318: */
319:
320: memcpy(&psaddr->sa_socket, Remote_Socket_Number, 2);
321:
322:
323: /*
324: * Set the packet type for this socket
325: */
326:
327: if (verbose)
328: printf("Calling setsockopt for packet type %d\n", Send_Packet_Type);
329:
330: rc = setsockopt(s, NSPROTO_IPX, IPX_PTYPE, (const char *) &Send_Packet_Type, sizeof(int));
331:
332: if (rc == SOCKET_ERROR)
333: dos_net_perror("setsockopt() call failed");
334:
335: return;
336: }
337:
338: /****************************************************************************
339: *
340: * FUNCTION: dg_send( SOCKET s )
341: *
342: * PURPOSE: Receives datagrams.
343: *
344: * ARGUMENTS: SOCKET socket to transmit on
345: *
346: * RETURNS: 0 if ok
347: * 1 if error
348: *
349: *\***************************************************************************/
350: int dg_send(SOCKET s)
351: {
352: LPSTR sendbuf;
353: int rc, errflag = 0;
354: UINT dgrms = 0;
355:
356: if (verbose)
357: printf("allocating %d bytes for send buffer\n", Send_Length);
358:
359: /*
360: * Set up the data buffer to send
361: */
362:
363: sendbuf = (LPSTR)malloc(Send_Length);
364:
365: if (!sendbuf) {
366: printf("Error allocating %d bytes for send buffer\n", Send_Length);
367: return 1;
368: }
369:
370: /*
371: * Zero the buffer and copy as much of our data to it as possible
372: */
373:
374: memset(sendbuf, 0, Send_Length);
375: strncpy(sendbuf, send_data, Send_Length);
376:
377: while (1) {
378: if (verbose) {
379: printf("calling sendto(socket = %d, length = %d),\n", s, Send_Length);
380: printf("destination address:\n ");
381: print_saddr(&saddr);
382: }
383:
384: /*
385: * Send a packet to everybody
386: */
387:
388: rc = sendto(s, sendbuf, Send_Length, 0, (const struct sockaddr *) &saddr, 16);
389:
390: if (verbose)
391: printf("\nsendto() returned %d\n", rc);
392:
393: if (rc == SOCKET_ERROR) {
394: dos_net_perror("Sendto() failed");
395: errflag++;
396: break;
397: }
398: else {
399: printf("\rSent datagram %d, length = %d bytes", ++dgrms, rc);
400: if (verbose)
401: printf("\n");
402: }
403:
404: /*
405: * If we are to send only one, break out
406: */
407:
408: if (No_Loop)
409: break;
410:
411: /*
412: * Sleep for a little while so we don't bombard the network
413: */
414:
415: Sleep(Sleep_Time);
416: }
417:
418: if (verbose)
419: printf("Freeing send buffer\n");
420:
421: free(sendbuf);
422:
423: return errflag;
424: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.