Welcome to the Wonderful World of IPX/SPX Packeting Version 0.1 Written by Dennis j. Cox dennis@ponder.csci.unt.edu Copyright (c) 1995 Dennis j. Cox /* * Note: This the First _BETA_ Version of this Document. * Take into account everything will be changed. * During Each revision. The Official release will * be called version 1.0. * I will release the next revision within 3 to 5 days. * Report any bugs to me as soon as possible */ /* This Release Contents: The First Release /* Next Revision will Content: Most _UNDER_CONSTRUCTION_ areas will be filled in and both Interrupt Based and Novell Library based functions will be discussed. A Complete IPX Program will be included. // T a b l e o f C o n t e n t s /////////////////////////////////////// Preface Legal Stuff Acknowledgments Information Basic Information Novell Netware Communication over a Network IPX Introduction Coding Information IPX.H The IPX header file Detecting IPX Opening a Socket Closing a Socket Sending a Packet Receiving a Packet Broadcasting a Packet More Coding Information Getting the local Connection Number Getting remote Connection Numbers Getting the Local Target Address The Event Control Block Related Material Books Internet Stuff CompuServe // P r e f a c e /////////////////////////////////////////////////////////// /* ///////////////////////////////////////////////////////////////// // Legal Stuff ///////////////////////////////////////////////////////////////// Please feel free to distribute this document electronically as much as possible for non-profit use only. This document may not be printed and/or distributed in any fashion in any for-profit manner whether for a newsletter, on-line magazine, or professional publication without the written permission of Dennis j. Cox. /* ///////////////////////////////////////////////////////////////// // Acknowledgments ///////////////////////////////////////////////////////////////// Ralf Brown for his wonderful interrupt list. Send him a thank you letter for saving everybody a lot of time and money. The man is a saint! Also feel free to correct my spelling errors, typo's, bad coding and lack of writing skills. _BUT_ be nice when doing it nasty letters by people who do not contribute to projects like this will just piss me off, and I won't be nice. /* ///////////////////////////////////////////////////////////////// // Information ///////////////////////////////////////////////////////////////// You can reach via Internet: dennis@ponder.csci.unt.edu all questions, comments and observations will be responded to with the utmost happiness. Also about the code in this 'article', all code was 'stolen' out of a few dozen sources. It has all been changed slightly from it's original form. You are more then welcome to steal it from me. BTW, when I mean 'stolen', I mean taken out of books I purchased which unless noted is not really stealing. // B a s i c I n f o r m a t i o n /////////////////////////////////////// /* ///////////////////////////////////////////////////////////////// // Novell Netware ///////////////////////////////////////////////////////////////// Everything I cover in the upcoming article is for version 3.11 or later. I am sure some things will still work prior to version 3.11 but will not guarantee it. Anyway, If you don't know what packeting or IPX/SPX is, this is not the place for you to start. This is for Programmers (mostly 'C') to get and understanding on how to write programs that include network communication. If you want to know about NetBIOS, this is not the place either this is strictly IPX/SPX, sorry. /* ///////////////////////////////////////////////////////////////// // Communication over a Network ///////////////////////////////////////////////////////////////// _UNDER_CONSTRUCTION_ /* ///////////////////////////////////////////////////////////////// // IPX Introduction ///////////////////////////////////////////////////////////////// The Structure of an IPX Packet. The packet contains a 30-byte header which is followed by 0 to 546 bytes of data. Thus making the minimum packet size 30 bytes and to the maximum size of 576 bytes. Good news though the content and structure of the data part is entirely up to YOU! Meaning pass anything you want in any format you want. // C o d i n g I n f o r m a t i o n //////////////////////////////////// /* ///////////////////////////////////////////////////////////////// // IPX.H The IPX Header File ///////////////////////////////////////////////////////////////// Here are the structures of an IPX Header according to Novell. typedef struct IPXAddress { /* unsigned char */ BYTE network[4]; /* high-low */ BYTE node[6]; /* high-low */ BYTE socket[2]; /* high-low */ }IPXAddress; typedef struct IPXHeader { /* unsigned int */ WORD checkSum; /* high-low */ WORD length; /* high-low */ BYTE transportControl; BYTE packetType; IPXAddress destination; IPXAddress source; }IPXHeader; ~IPXHeader~ Your application has to set the packetType and destination fields when sending an packet. IPX will set the remaining fields. checkSum -> contains a dummy check sum of the packet contents and is always set by IPX to 0xFFFF length -> contains the length of the complete IPX packet (30-576 bytes) and is set by IPX transportControl -> Novell uses this to monitor the number of bridges and/or routers that a packet has crossed. The packets are "killed" by the 16th bridge that they encounter. IPX of course sets this field to zero before sending the packet. Hence, Don't try to set this field yourself, and if you do don't make above 15. packetType -> identifies the type of service offered and/or required by the packet. packetType = 0; // Unknown Type packetType = 1; // Routing Information packetType = 2; // Echo packetType = 3; // Error packetType = 4; // IPX packetType = 5; // SPX You should set this to 0 or 4 for IPX. 5 for SPX ~IPXAddress~ network -> identifies the network address of the target or source application node -> contains the 6-byte number that identifies the LAN board within the target or source network station(or node). socket -> the socket address /* ///////////////////////////////////////////////////////////////// // Detecting IPX ///////////////////////////////////////////////////////////////// Okay this is where Ralf Brown's Interrupt list comes in handy. Look in his N section (for network) and you will find out what and were the interrupt is for IPX.COM. Use it. ////////////////////////////////////////////////////////////////// // FUNCTION: int IsIpxThere(void) // Purpose: // To check to see if IPX is available // Input: // None. // Output: // TRUE Yes // FALSE No // Created by Dennis j. Cox 08:09:58pm 04-09-95 //////////////////////////////////////////////////////////////////// int IsIpxThere(void) { void ((far *IpxSpxCallPtr)()); /* From Borland 4.5 Help int int86x(int intno, union REGS *inregs, union REGS *outregs, struct SREGS *segregs); This is the function to call an interrupt. */ /* First we setup our union */ union REGS inregs, outregs; /* In Register, Out Register */ /* Second we setup our SREGS structure */ struct SREGS segregs; /* Third we setup our inregs */ inregs.h.ah = 0x7A; /* AH = AX High */ Inregs.h.al = 0x00; /* AL = AX Low */ /* Then we call the function int86x(paras...) First is the intno which is 0x2F Next our inregs which are 0x7A and 0x00 Next our outregs and Finally the segement reg */ int86x(0x2F, &inregs, &outregs, &segregs); if (outregs.h.al != 0xFF) { /* IPX is not installed */ return FALSE; } else { /* IPX is installed */ printf("\n Call address is ES:DI == %04X:%04X", segregs.es, outregs.x.di); IpxSpxCallPtr = (void far *) ((((long) segregs.es) << 16) + ((long) outregs.x.di)); return TRUE; } } /* ///////////////////////////////////////////////////////////////// // Opening a Socket ///////////////////////////////////////////////////////////////// To send something you must use a socket. To use a socket you must open one. Seems logical enough... ////////////////////////////////////////////////////////////////// // FUNCTION: OpenIPXSocket(WORD socknum) // Purpose: // To open a specific Socket // Input: // The socketnumber to open // Output: // return value // Created by Dennis j. Cox 07:47:13pm 04-10-95 //////////////////////////////////////////////////////////////////// OpenIPXSocket(Word socknum) { BYTE Complete; WORD SwappedNum, AssignNum; printf("\n Trying to open socket number %04X...",socknum); /* swab is located in stdlib.h */ swab((char *)&socknum,SwappedNum, sizeof(WORD)); printf("\n Swapped socket numberis == %04X",SwappedNum); /* Some Assembly */ asm mov AL, 000h /* short lived socket */ asm mov BX, 0x00 /* Open Socket */ asm mov DX, SwappedNum asm push BP IpxSpxCallPtr(); /* complete in AL */ asm pop BP asm mov Complete, AL asm mov AssignNum, DX printf("\n Complete == %02X", CompletionCode); swab((char *)&AssignNum, (char *)&AssignNum, sizeof(WORD)); switch (Complete) { case 0x00 : printf("\nIt Worked"); printf("\n Assigned socket number == %04X", AssignNum); break; case 0xFE : printf("\nDidn't work because the table is full"); break; case 0xFF : printf("\nSocket is open already"); break; default : printf("Unknown complete (%02X)",Complete); break; } return (0); } /* ///////////////////////////////////////////////////////////////// // Closing a Socket ///////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// // FUNCTION: CloseIPXSocket(WORD socknum) // Purpose: // To close an IPX socket // Input: // socket number // Output: // return value // Created by Dennis j. Cox 07:58:01pm 04-10-95 //////////////////////////////////////////////////////////////////// CloseIPXSocket(WORD socknum) { WORD SwappedNum; printf("\nClosing Socket Number %04X...",socknum); swab((char *)&SocketNumber,(char *)&SwappedSocketNumber, sizeof(WORD)); asm mov BX, 0x01 /* close socket */ asm mov DX,SwappedNum asm push BP IpxSpxCallPtr(); asm pop BP return (0); } /* ///////////////////////////////////////////////////////////////// // Sending a Packet ///////////////////////////////////////////////////////////////// _UNDER_CONSTRUCTION_ /* ///////////////////////////////////////////////////////////////// // Receiving a Packet ///////////////////////////////////////////////////////////////// _UNDER_CONSTRUCTION_ /* ///////////////////////////////////////////////////////////////// // Broadcasting a Packet ///////////////////////////////////////////////////////////////// IPX can broadcast packets by specifying the target node address of 0xFFFFFFFFFFFF (12 F's). IPXAddress.node = 0xFFFFFFFFFFFF; // M o r e C o d i n g I n f o r m a t i o n /////////////////////////// /* ///////////////////////////////////////////////////////////////// // Getting the local Connection Number ///////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// // FUNCTION: GetLocalConnectNum(void) // Purpose: // Get the local connection number // Input: // None. // Output: // None. // Created by Dennis j. Cox 11:44:40am 04-11-95 //////////////////////////////////////////////////////////////////// GetLocalConnectNum(void) { union REGS inregs, outregs; inregs.h.ah = '\xDC'; inregs.h.al = 0x00; int86( 0x21,&inregs,&outregs); printf("\n Local Connection Number == %d(0x%1c$1c)", outregs.h.al, outregs.h.cl, outregs.h.ch); return (0); } /* ///////////////////////////////////////////////////////////////// // Getting remote Connection Numbers ///////////////////////////////////////////////////////////////// _UNDER_CONSTRUCTION_ /* ///////////////////////////////////////////////////////////////// // Getting the Local Target Address ///////////////////////////////////////////////////////////////// _UNDER_CONSTRUCTION_ /* ///////////////////////////////////////////////////////////////// // The Event Control Block ///////////////////////////////////////////////////////////////// _UNDER_CONSTRUCTION_ // R e l a t e d M a t e r i a l ///////////////////////////////////////// /* ///////////////////////////////////////////////////////////////// // Books ///////////////////////////////////////////////////////////////// C Programmer's Guide to NetBIOS, IPX and SPX SAMS Publishing W. David Schwaderer ISBN: 0-672-30050-8 Library of Congress: 92-61286 Price: $49.95 USA/$62.95 CAN /* ///////////////////////////////////////////////////////////////// // Internet Related Stuff ///////////////////////////////////////////////////////////////// Ralf Brown's Interrupt List ftp://oak.oakland.edu /* ///////////////////////////////////////////////////////////////// // Other On-line Services ///////////////////////////////////////////////////////////////// CompuServe -> Novell Forum -- Dennis j. Cox * When I die, Hope I'm alseep, WTS Bureau Systems, Inc. * just like grampa Dallas, Texas USA * Not cussing and screaming dennis@ponder.csci.unt.edu * like his passengers...