|
|
1.1 root 1: /*=====================================================================
2: P I N G . C
3:
4: This is the DOS side ping program. It uses Novell's IPX/SPX APIs,
5: requiring their SDK. It will send/receive 1-n IPX packets.
6: ======================================================================*/
7: #include <stdio.h>
8: #include <stdlib.h>
9: #include <string.h>
10: #include <conio.h>
11: #include <nxtdos.h>
12:
13: #define TIMER (unsigned long far *) 0x0000046cL
14:
15: char *progname;
16: IPXHeader *ipx;
17: int send_socket=0;
18: int recv_socket;
19: int datasize = 1;
20: ECB send_ecb;
21: ECB recv_ecb[10];
22: char mynodeaddr[6];
23: char sendb[2048];
24: char recvb[2048];
25:
26: int ptype = 4;
27: int niters = 1;
28:
29: /**
30: This is the address we try to send to. When
31: we find a server, this address is replaced by the address
32: of the exact server. The address is made up of:
33: bytes 1-4 = network number
34: bytes 5-10 = node number
35: bytes 11-12 = socket address
36:
37: **/
38:
39: char destaddr[12] = {
40: 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x30, 0x00
41: };
42:
43: /** Function Prototypes **/
44:
45: void hang_recvs(void);
46: void cancel_recvs(void);
47: void do_recv(int);
48: int get_recv(void);
49: void find_a_server(void);
50: void print_address(char *);
51: void print_network(char *);
52: void print_nodeaddr(char *);
53: void parse_cmd_line(int, char **);
54: void swap_dwf(char *);
55: char * get_node_number(char * cmd);
56: char * get_network_number(char * cmd);
57: /********************************************************************
58: m a i n
59: *********************************************************************/
60: int main(int argc, char **argv)
61: {
62: char *p;
63: unsigned long start = *TIMER;
64: unsigned long end;
65: int cnt = 0;
66: long sendpkt = 0L;
67: long recvpkt = 0L;
68: int ttime;
69: float total = 0;
70:
71: progname = *argv;
72: for (p = progname; *p; p++) {
73: if (*p == '\\')
74: progname = p + 1;
75: }
76:
77: /** Make sure IPX is loaded **/
78:
79: if (IPXInitialize()) {
80: printf("%s: IPX IS NOT LOADED\n", progname);
81: exit(1);
82: }
83: recv_socket = *(short *)(destaddr + 10);
84: parse_cmd_line(argc, argv);
85: print_network(destaddr);
86: print_nodeaddr(destaddr + 4);
87: printf("packet type: %d\n",ptype);
88: printf("datasize: %d\n", datasize);
89: printf("n iterations: %d\n", niters);
90:
91:
92:
93: if (IPXOpenSocket(&send_socket, 0)) {
94: printf("%s: ERROR: unable to open socket\n", progname);
95: exit(1);
96: }
97: recv_socket = send_socket;
98: if (IPXGetLocalTarget(destaddr, send_ecb.immediateAddress, &ttime)) {
99: printf("%s: ERROR: unable to get local target\n", progname);
100: exit(1);
101: }
102:
103: memcpy(mynodeaddr, send_ecb.immediateAddress, 6);
104:
105: /** Go find a server **/
106:
107: find_a_server();
108: hang_recvs();
109:
110:
111: /** Do # iterations (default = 1) **/
112: while (cnt < niters) {
113: int rcv;
114: /** send a packet **/
115: *(sendb + 5) = ptype;
116: memcpy(sendb + 6, destaddr, 12);
117: memcpy(send_ecb.immediateAddress, mynodeaddr, 6);
118: send_ecb.socketNumber = send_socket;
119: send_ecb.fragmentCount = 1;
120: send_ecb.fragmentDescriptor[0].address = sendb;
121: send_ecb.fragmentDescriptor[0].size = 30 + datasize;
122:
123: IPXSendPacket(&send_ecb);
124:
125: while (send_ecb.inUseFlag) /* wait for it to finish */
126: ;
127:
128: if (send_ecb.completionCode) {
129: cancel_recvs();
130: IPXCloseSocket(send_socket);
131: printf("%s: Error sending packet: %d\n", progname, send_ecb.completionCode);
132: exit(1);
133: }
134:
135: sendpkt++;
136: total += 30 + datasize; /* Count the bytes */
137: printf("\rSend packet Number %d ", sendpkt);
138:
139: if ((rcv = get_recv()) == -1)
140: goto EXIT;
141:
142: do_recv(rcv);
143: total += 30 + datasize; /* Count the bytes */
144:
145: cnt++;
146: recvpkt++;
147: printf(": Recv packet Number %d ", recvpkt);
148: }
149:
150: /** We did 1000 packets - print KB per second **/
151: EXIT:
152: end = *TIMER;
153: end = (end - start) / 18.2; /* Num seconds it took */
154:
155: total = (float)((total / 1024.0) / end);
156:
157: /** All done - cancel recvs and exit **/
158: cancel_recvs();
159: IPXCloseSocket(send_socket);
160: printf("\n%ld packets \n", recvpkt);
161: if (recvpkt)
162: printf("Average time per iteration: %5.3f\n",total/recvpkt);
163: exit(0);
164: }
165:
166: /*page**************************************************************
167: h a n g _ r e c v s
168:
169: Arguments - None
170:
171: Returns - nothing
172: *******************************************************************/
173: void hang_recvs(void)
174: {
175: int i;
176:
177: for (i = 0; i < 10; i++) {
178:
179: /** Don't hang recv on one that is already hung **/
180:
181: if (recv_ecb[i].inUseFlag)
182: continue;
183:
184: /** Hang a recv **/
185:
186: memset(&recv_ecb[i], 0, sizeof(ECB));
187: recv_ecb[i].socketNumber = recv_socket;
188: recv_ecb[i].fragmentCount = 1;
189: recv_ecb[i].fragmentDescriptor[0].address = recvb;
190: recv_ecb[i].fragmentDescriptor[0].size = 2048;
191: IPXListenForPacket(&recv_ecb[i]);
192: }
193:
194: /** All done **/
195:
196: return;
197: }
198:
199: /*page**************************************************************
200: c a n c e l _ r e c v s
201:
202: Arguments - None
203:
204: Returns - nothing
205: *******************************************************************/
206: void cancel_recvs(void)
207: {
208: int i;
209:
210: for (i = 0; i < 10; i++) {
211:
212: /** If recv not in use - skip it **/
213:
214: if (!recv_ecb[i].inUseFlag)
215: continue;
216:
217: /** Cancel the recv **/
218:
219: IPXCancelEvent(&recv_ecb[i]);
220: }
221:
222: /** All done **/
223:
224: return;
225: }
226:
227: /*page**************************************************************
228: d o _ r e c v
229:
230: Arguments - i = recv index to hang
231:
232: Returns - nothing
233: *******************************************************************/
234: void do_recv(int i)
235: {
236: memset(&recv_ecb[i], 0, sizeof(ECB));
237: recv_ecb[i].socketNumber = recv_socket;
238: recv_ecb[i].fragmentCount = 1;
239: recv_ecb[i].fragmentDescriptor[0].address = recvb;
240: recv_ecb[i].fragmentDescriptor[0].size = 2048;
241: IPXListenForPacket(&recv_ecb[i]);
242: return;
243: }
244:
245: /*page**************************************************************
246: g e t _ r e c v
247:
248: Arguments - none
249:
250: Returns - -1 = User hit a key
251: else = recv index that was hit
252: *******************************************************************/
253: int get_recv(void)
254: {
255: int i;
256:
257: /** **/
258:
259: while (!kbhit()) {
260: for (i = 0; i < 10; i++) {
261: if (!recv_ecb[i].inUseFlag)
262: return i;
263: }
264: // try resending the bugger...maybe we be out of synch?..bug,bug,bug???
265: IPXSendPacket(&send_ecb);
266: }
267:
268: /** Return that user hit a key **/
269:
270: return -1;
271: }
272:
273: /*******************************************************************
274: function name: f i n d _ a _ s e r v e r
275: Description: make sure can find the machine we want to send to
276: Arguments: none
277: Returns: none
278: *********************************************************************/
279: void find_a_server(void)
280: {
281: long start;
282: long end;
283: ECB send_ecb;
284: ECB recv_ecb;
285:
286: /** Setup the recv ecb and listen for a packet **/
287:
288: memset(&recv_ecb, 0, sizeof(ECB));
289: recv_ecb.socketNumber = recv_socket;
290: recv_ecb.fragmentCount = 1;
291: recv_ecb.fragmentDescriptor[0].address = recvb;
292: recv_ecb.fragmentDescriptor[0].size = 31;
293: IPXListenForPacket(&recv_ecb);
294:
295: memset(&send_ecb, 0, sizeof(ECB));
296: memcpy(sendb + 6, destaddr, 12);
297: send_ecb.socketNumber = send_socket;
298: memcpy(send_ecb.immediateAddress, mynodeaddr, 6);
299: send_ecb.fragmentCount = 1;
300: send_ecb.fragmentDescriptor[0].address = sendb;
301: send_ecb.fragmentDescriptor[0].size = 31;
302:
303: IPXSendPacket(&send_ecb);
304:
305: while (send_ecb.inUseFlag && !kbhit())
306: ;
307:
308: if (send_ecb.completionCode) {
309: printf("%s: ERROR: send completion code 0x%02x\n", progname, send_ecb.completionCode);
310: exit(1);
311: }
312:
313: /** Wait awhile for the recv to pay off **/
314:
315: start = *TIMER;
316:
317: while (recv_ecb.inUseFlag && !kbhit() && (*TIMER - start) < 180L)
318: ;
319: end = *TIMER;
320:
321: /** If we timed out - then we couldn't find a server **/
322:
323: if (end - start >= 180L) {
324: IPXCancelEvent(&recv_ecb);
325: IPXCloseSocket(send_socket);
326: printf("%s: Unable to find a server\n", progname);
327: exit(1);
328: }
329:
330: /** If recv still in use - error **/
331:
332: if (recv_ecb.inUseFlag) {
333: IPXCancelEvent(&recv_ecb);
334: IPXCloseSocket(send_socket);
335: printf("%s: Program terminated by a keystroke\n", progname);
336: exit(1);
337: }
338:
339: /** If recv error - clean up and exit **/
340:
341: if (recv_ecb.completionCode) {
342: IPXCancelEvent(&recv_ecb);
343: IPXCloseSocket(send_socket);
344: printf("%s: Error receiving packet: %d\n", progname, recv_ecb.completionCode);
345: exit(1);
346: }
347:
348: /** Get the server address and print it out **/
349:
350: memcpy(destaddr, recvb + 18, 12); /* Set the address to send to */
351: memcpy(mynodeaddr, recv_ecb.immediateAddress, 6);
352: printf("Found server: ");
353: print_address(destaddr);
354:
355: /** All done **/
356:
357: return;
358: }
359:
360: /********************************************************************
361: p r i n t _ a d d r e s s
362:
363: Arguments - netaddr = ptr to 14 bytes address to print
364:
365: Returns - nothing
366: *********************************************************************/
367: void print_address(char *netaddr)
368: {
369: int i;
370:
371: for (i = 0; i < 12; i++) {
372: if ((i == 4) || (i == 10))
373: printf(" ");
374: printf("%02X", (unsigned char) *(netaddr + i));
375: }
376: printf("\n");
377: return;
378: }
379:
380: void print_network(char *p)
381: {
382: int i;
383: printf("Network Number: ");
384: for (i = 0; i < 4; i++)
385: printf("%02X", (unsigned char) *p++);
386: printf("\n");
387: return;
388: }
389:
390: void print_nodeaddr(char *p)
391: {
392: int i;
393:
394: printf("Node Address: ");
395: for (i = 0; i < 6; i++)
396: printf("%02X", (unsigned char) *p++);
397: printf("\n");
398: return;
399: }
400:
401: /*-----------------------------------------------------------------
402: function name: parse_cmd_line
403: Description:
404: Parse the command line for the parameters and host name.
405: Arguments:
406: -i <number of iterations>
407: -p <packet type>
408: -d <data size>
409: NOTE: must be < frame size - 14 (MAC length) - 30 (IPX header)
410: -n <network number>
411: NOTE: you can ignore this if on the same subnet. Must be 4 hex
412: bytes
413: -a <destination address>
414: NOTE: must be 6 hex bytes representing the physical NIC address of
415: the remote machine.
416: -s <socket>
417: Two byte socket number
418: Returns: Nothing
419: ----------------------------------------------------------------------*/
420: void parse_cmd_line(int argc, char **argv)
421: {
422: short socket;
423:
424: argv++; /* skip to first arg */
425: while (--argc) { /* do all args */
426: if (**argv == '-') {
427: ++(*argv);
428: switch(tolower(**argv)) {
429: case 'i':
430: niters = atoi(++(*argv));
431: if (niters < 0)
432: niters = 1;
433: break;
434: case 'p':
435: ptype = atoi(++(*argv));
436: if (ptype < 0 || ptype > 255) {
437: ptype = 4;
438: printf("%s: Invalid packet type. Setting to default = %d\n",
439: progname,ptype);
440: }
441: break;
442: case 'd': /*amount of data to send in a frame */
443: datasize = atoi(++(*argv));
444: if (!datasize) {
445: datasize = 1;
446: printf("%s: Datasize cannot be zero. Setting to default = 1\n", progname);
447: }
448: break;
449: case 's': /* socket number, default = 0x3000 */
450: socket = (short)strtol(++(*argv), NULL, 16);
451: printf("New socket = 0x%x\n", socket);
452: *(short *)(destaddr + 10) = socket;
453: swap_dwf(destaddr + 10);
454: break;
455: case 'n': /* network number, default = local net (= 0) */
456: ++(*argv);
457: memcpy(destaddr, get_network_number(*argv),4);
458: if (destaddr[0] == 'X') {
459: printf("\n****!\n%s is an incorrect net number.\n****!\n", *argv);
460: printf("%s E.G.: -nAABBCCDD (I.E.: 8 hex digits)\n");
461: exit(1);
462: }
463: break;
464: case 'a': /* remote address, have to know this */
465: ++(*argv);
466: memcpy(destaddr+4, get_node_number(*argv), 6);
467: if (*(destaddr+4) == 'X') {
468: printf("\n****!\n%s is an incorrect Node address.\n****!\n", *argv);
469: printf("\n E.G.: -a 023C8DAADDCC (12 hex digits)\n");
470: exit(1);
471: }
472: break;
473: default:
474: printf("%s [-p] [-d] [-nxxxxxxxx] [-axxxxxxxxxxxx] [-sx]\n", progname);
475: printf(" -p - packet type\n");
476: printf(" -d - data size\n");
477: printf(" -n - network number (in hex)\n");
478: printf(" -a - address (in hex)\n");
479: printf(" -s - socket number (in hex)\n");
480: exit(0);
481: }
482: argv++;
483: }
484: }
485: return;
486: }
487: /**********************************************************************
488: g e t _ h e x _ b y t e
489:
490: Converts the character passed in to a hexadecimal nibble.
491:
492: Arguments: char character to convert
493:
494: Returns: UCHAR hex nibble
495: **************************************************************************/
496: char get_hex_byte(char ch)
497: {
498: if (ch >= '0' && ch <= '9')
499: return (ch - '0');
500:
501: if (ch >= 'A' && ch <= 'F')
502: return ((ch - 'A') + 0x0A);
503:
504: return -1;
505: }
506: /**********************************************************************
507: g e t _ h e x _ s t r i n g
508:
509: Reads in a character string containing hex digits and converts
510: it to a hexadecimal number.
511:
512: Arguments: src => source string to convert
513: dest => destination for hex number
514: num => number of chars to convert
515:
516: Returns: nothing
517: **************************************************************************/
518: char get_hex_string(char * src, char * dest, int num)
519: {
520: char * q = src;
521: char hexbyte1,hexbyte2;
522:
523: strupr(q);
524: while (num--)
525: {hexbyte1 = get_hex_byte(*q++);
526: hexbyte2 = get_hex_byte(*q++);
527: if ( (hexbyte1 < 0) || (hexbyte2 < 0) )
528: return -1;
529: *dest++ = (hexbyte1 << 4) + hexbyte2;
530: }
531:
532: return(0);
533: }
534: /*************************************************************************
535: g e t _ n o d e _ n u m b e r
536:
537: Reads a node number from the given string.
538:
539: Arguments: cmd => string to read from
540:
541: Returns: hex node number
542: **************************************************************************/
543: char * get_node_number(char * cmd)
544: {
545: static char hex_num[6];
546:
547: memset(hex_num, 0, 6);
548:
549: if (strlen(cmd) != 12){
550: hex_num[0] = 'X';
551: return hex_num;
552: }
553:
554: if (get_hex_string(cmd, hex_num, 6) < 0)
555: hex_num[0] = 'X';
556: return hex_num;
557: }
558: /**************************************************************************
559: g e t _ n e t w o k _ n u m b e r
560:
561: Reads a network number from the given string.
562:
563: Arguments: cmd string to read from
564:
565: Returns: hex network number
566: **************************************************************************/
567: char * get_network_number(char * cmd)
568: {
569: static char hex_num[4];
570:
571: memset(hex_num, 0, 4);
572:
573: if (strlen(cmd) != 8) {
574: hex_num[0] = 'X';
575: return(hex_num);
576: }
577:
578: if (get_hex_string(cmd, hex_num, 4) < 0)
579: hex_num[0] = 'X';
580:
581: return hex_num;
582: }
583: /*******************************************************************
584: s w a p _ d w f
585:
586: Swap the bytes pointed to by p.
587:
588: Arguments - p = ptr to word to swap
589:
590: Returns - nothing
591: ********************************************************************/
592: void swap_dwf(char *p)
593: {
594: char tmp;
595:
596: tmp = *p;
597: *p = *(p + 1);
598: *(p + 1) = tmp;
599: return;
600: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.