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