version 1.1 | | version 1.2 |
---|
| | |
* Routines for IPX communications. | | * Routines for IPX communications. |
* | | * |
* $Log$ | | * $Log$ |
* Revision 1.1 1999/06/14 21:58:22 donut | | * Revision 1.2 2000/02/07 10:26:05 donut |
* Initial revision | | * new ipx code structure reduces some redundancy and gives all arches multi netcode ability |
| | * |
| | * Revision 1.1.1.1 1999/06/14 21:58:22 donut |
| | * Import of d1x 1.37 source. |
* | | * |
* Revision 2.10 1995/03/29 17:27:55 john | | * Revision 2.10 1995/03/29 17:27:55 john |
* Added code to not duplicate broadcasts. | | * Added code to not duplicate broadcasts. |
| | |
#include "error.h" | | #include "error.h" |
#include "u_dpmi.h" | | #include "u_dpmi.h" |
#include "key.h" | | #include "key.h" |
| | #include "ipx_drv.h" |
| | |
typedef unsigned char BYTE; | | typedef unsigned char BYTE; |
typedef unsigned short WORD; | | typedef unsigned short WORD; |
| | |
packet_data pd; | | packet_data pd; |
} __pack__ ipx_packet; | | } __pack__ ipx_packet; |
| | |
typedef struct user_address { | | static int ipx_packetnum = 0; |
ubyte network[4]; | | |
ubyte node[6]; | | |
ubyte address[6]; | | |
} __pack__ user_address; | | |
| | |
#define MAX_USERS 64 | | |
int Ipx_num_users = 0; | | |
user_address Ipx_users[MAX_USERS]; | | |
| | |
#define MAX_NETWORKS 64 | | |
int Ipx_num_networks = 0; | | |
uint Ipx_networks[MAX_NETWORKS]; | | |
| | |
int ipx_packetnum = 0; | | |
| | |
#define MAX_PACKETS 64 | | #define MAX_PACKETS 64 |
| | |
| | |
static short packet_size[MAX_PACKETS]; | | static short packet_size[MAX_PACKETS]; |
| | |
WORD ipx_socket=0; | | WORD ipx_socket=0; |
ubyte ipx_installed=0; | | static ubyte ipx_installed=0; |
WORD ipx_vector_segment; | | WORD ipx_vector_segment; |
WORD ipx_vector_offset; | | WORD ipx_vector_offset; |
ubyte ipx_socket_life = 0; // 0=closed at prog termination, 0xff=closed when requested. | | ubyte ipx_socket_life = 0; // 0=closed at prog termination, 0xff=closed when requested. |
DWORD ipx_network = 0; | | //DWORD ipx_network = 0; |
local_address ipx_my_node; | | //local_address ipx_my_node; |
| | #define ipx_my_node (ipx_MyAddress+4) |
WORD ipx_num_packets=32; // 32 Ipx packets | | WORD ipx_num_packets=32; // 32 Ipx packets |
ipx_packet * packets; | | ipx_packet * packets; |
int neterrors = 0; | | int neterrors = 0; |
| | |
ecb_header * last_ecb=NULL; | | ecb_header * last_ecb=NULL; |
int lastlen=0; | | int lastlen=0; |
| | |
void got_new_packet( ecb_header * ecb ); | | static void got_new_packet( ecb_header * ecb ); |
void ipx_listen_for_packet(ecb_header * ecb ); | | static void ipx_listen_for_packet(ecb_header * ecb ); |
| | |
void free_packet( int id ) | | static void free_packet( int id ) |
{ | | { |
packet_buffers[id].packetnum = -1; | | packet_buffers[id].packetnum = -1; |
packet_free_list[ --num_packets ] = id; | | packet_free_list[ --num_packets ] = id; |
| | |
while ((--largest_packet_index>0) && (packet_buffers[largest_packet_index].packetnum == -1 )); | | while ((--largest_packet_index>0) && (packet_buffers[largest_packet_index].packetnum == -1 )); |
} | | } |
| | |
int ipx_get_packet_data( ubyte * data ) | | static int ipx_dos_get_packet_data( ubyte * data ) |
{ | | { |
int i, n, best, best_id, size; | | int i, n, best, best_id, size; |
| | |
| | |
} | | } |
#endif | | #endif |
| | |
void got_new_packet( ecb_header * ecb ) | | static void got_new_packet( ecb_header * ecb ) |
{ | | { |
ipx_packet * p; | | ipx_packet * p; |
int id; | | int id; |
| | |
| | |
// Error( "Recieve error %d for completion code", p->ecb.completion_code ); | | // Error( "Recieve error %d for completion code", p->ecb.completion_code ); |
| | |
if ( memcmp( &p->ipx.source.node_id, &ipx_my_node, 6 ) ) { | | if ( memcmp( &p->ipx.source.node_id, ipx_my_node, 6 ) ) { |
datasize=swap_short(p->ipx.length); | | datasize=swap_short(p->ipx.length); |
lastlen=datasize; | | lastlen=datasize; |
datasize -= sizeof(ipx_header); | | datasize -= sizeof(ipx_header); |
| | |
//ipx_listen_for_packet(&p->ecb); | | //ipx_listen_for_packet(&p->ecb); |
} | | } |
| | |
ubyte * ipx_get_my_local_address() | | /*ubyte * ipx_get_my_local_address() |
{ | | { |
return ipx_my_node.address; | | return ipx_my_node.address; |
} | | } |
| | |
ubyte * ipx_get_my_server_address() | | ubyte * ipx_get_my_server_address() |
{ | | { |
return (ubyte *)&ipx_network; | | return (ubyte *)&ipx_network; |
} | | }*/ |
| | |
void ipx_listen_for_packet(ecb_header * ecb ) | | static void ipx_listen_for_packet(ecb_header * ecb ) |
{ | | { |
dpmi_real_regs rregs; | | dpmi_real_regs rregs; |
ecb->in_use = 0x1d; | | ecb->in_use = 0x1d; |
| | |
dpmi_real_int386x( 0x7A, &rregs ); | | dpmi_real_int386x( 0x7A, &rregs ); |
} | | } |
| | |
void ipx_cancel_listen_for_packet(ecb_header * ecb ) | | static void ipx_cancel_listen_for_packet(ecb_header * ecb ) |
{ | | { |
dpmi_real_regs rregs; | | dpmi_real_regs rregs; |
memset(&rregs,0,sizeof(dpmi_real_regs)); | | memset(&rregs,0,sizeof(dpmi_real_regs)); |
| | |
} | | } |
| | |
| | |
void ipx_send_packet(ecb_header * ecb ) | | static void ipx_send_packet(ecb_header * ecb ) |
{ | | { |
dpmi_real_regs rregs; | | dpmi_real_regs rregs; |
memset(&rregs,0,sizeof(dpmi_real_regs)); | | memset(&rregs,0,sizeof(dpmi_real_regs)); |
| | |
ubyte local_target[6]; | | ubyte local_target[6]; |
} __pack__ net_xlat_info; | | } __pack__ net_xlat_info; |
| | |
void ipx_get_local_target( ubyte * server, ubyte * node, ubyte * local_target ) | | static void ipx_dos_get_local_target( ubyte * server, ubyte * node, ubyte * local_target ) |
{ | | { |
net_xlat_info * info; | | net_xlat_info * info; |
dpmi_real_regs rregs; | | dpmi_real_regs rregs; |
| | |
memcpy( local_target, info->local_target, 6 ); | | memcpy( local_target, info->local_target, 6 ); |
} | | } |
| | |
void ipx_close() | | static void ipx_dos_close() |
{ | | { |
dpmi_real_regs rregs; | | dpmi_real_regs rregs; |
if ( ipx_installed ) { | | if ( ipx_installed ) { |
| | |
// -4 if couldn't allocate low dos memory | | // -4 if couldn't allocate low dos memory |
// -5 if error with getting internetwork address | | // -5 if error with getting internetwork address |
| | |
int ipx_init( int socket_number, int show_address ) | | static int ipx_dos_init( int socket_number ) |
{ | | { |
| | int show_address=0; |
dpmi_real_regs rregs; | | dpmi_real_regs rregs; |
ubyte *ipx_real_buffer; | | ubyte *ipx_real_buffer; |
int i; | | int i; |
| | |
atexit(ipx_close); | | // atexit(ipx_close); |
| | |
ipx_packetnum = 0; | | ipx_packetnum = 0; |
| | |
| | |
return -2; | | return -2; |
} | | } |
| | |
memcpy( &ipx_network, ipx_real_buffer, 4 ); | | /* memcpy( &ipx_network, ipx_real_buffer, 4 ); |
memcpy( &ipx_my_node, &ipx_real_buffer[4], 6 ); | | memcpy( ipx_my_node, &ipx_real_buffer[4], 6 );*/ |
| | memcpy(ipx_MyAddress,ipx_real_buffer,10); |
Ipx_num_networks = 0; | | |
memcpy( &Ipx_networks[Ipx_num_networks++], &ipx_network, 4 ); | | |
| | |
if ( show_address ) { | | if ( show_address ) { |
printf( "My IPX addresss is " ); | | printf( "My IPX addresss is " ); |
| | |
return 0; | | return 0; |
} | | } |
| | |
void ipx_send_packet_data( ubyte * data, int datasize, ubyte *network, ubyte *address, ubyte *immediate_address ) | | static void ipx_dos_send_packet_data( ubyte * data, int datasize, ubyte *network, ubyte *address, ubyte *immediate_address ) |
{ | | { |
assert(ipx_installed); | | assert(ipx_installed); |
| | |
| | |
| | |
} | | } |
| | |
void ipx_send_broadcast_packet_data( ubyte * data, int datasize ) | | /*static int ipx_change_default_socket( ushort socket_number ) |
{ | | |
int i, j; | | |
ubyte broadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; | | |
ubyte local_address[6]; | | |
| | |
// Set to all networks besides mine | | |
for (i=0; i<Ipx_num_networks; i++ ) { | | |
if ( memcmp( &Ipx_networks[i], &ipx_network, 4 ) ) { | | |
ipx_get_local_target( (ubyte *)&Ipx_networks[i], broadcast, local_address ); | | |
ipx_send_packet_data( data, datasize, (ubyte *)&Ipx_networks[i], broadcast, local_address ); | | |
} else { | | |
ipx_send_packet_data( data, datasize, (ubyte *)&Ipx_networks[i], broadcast, broadcast ); | | |
} | | |
} | | |
| | |
//OLDipx_send_packet_data( data, datasize, (ubyte *)&ipx_network, broadcast, broadcast ); | | |
| | |
// Send directly to all users not on my network or in the network list. | | |
for (i=0; i<Ipx_num_users; i++ ) { | | |
if ( memcmp( Ipx_users[i].network, &ipx_network, 4 ) ) { | | |
for (j=0; j<Ipx_num_networks; j++ ) { | | |
if (!memcmp( Ipx_users[i].network, &Ipx_networks[j], 4 )) | | |
goto SkipUser; | | |
} | | |
ipx_send_packet_data( data, datasize, Ipx_users[i].network, Ipx_users[i].node, Ipx_users[i].address ); | | |
SkipUser: | | |
j = 0; | | |
} | | |
} | | |
} | | |
| | |
// Sends a non-localized packet... needs 4 byte server, 6 byte address | | |
void ipx_send_internetwork_packet_data( ubyte * data, int datasize, ubyte * server, ubyte *address ) | | |
{ | | |
ubyte local_address[6]; | | |
| | |
if ( (*(uint *)server) != 0 ) { | | |
ipx_get_local_target( server, address, local_address ); | | |
ipx_send_packet_data( data, datasize, server, address, local_address ); | | |
} else { | | |
// Old method, no server info. | | |
ipx_send_packet_data( data, datasize, server, address, address ); | | |
} | | |
} | | |
| | |
int ipx_change_default_socket( ushort socket_number ) | | |
{ | | { |
int i; | | int i; |
WORD new_ipx_socket; | | WORD new_ipx_socket; |
| | |
| | |
return 0; | | return 0; |
} | | } |
| | */ |
| | |
void ipx_read_user_file(char * filename) | | struct ipx_driver ipx_dos = { |
{ | | // NULL, |
FILE * fp; | | ipx_dos_init, |
user_address tmp; | | ipx_dos_close, |
char temp_line[132], *p1; | | NULL, |
int n, ln=0; | | NULL, |
| | NULL, |
if (!filename) return; | | NULL, |
| | 1, |
Ipx_num_users = 0; | | ipx_dos_get_local_target, |
| | ipx_dos_get_packet_data, |
fp = fopen( filename, "rt" ); | | ipx_dos_send_packet_data |
if ( !fp ) return; | | }; |
| | |
printf( "Broadcast Users:\n" ); | | |
| | |
while (fgets(temp_line, 132, fp)) { | | |
ln++; | | |
p1 = strchr(temp_line,'\n'); if (p1) *p1 = '\0'; | | |
p1 = strchr(temp_line,';'); if (p1) *p1 = '\0'; | | |
n = sscanf( temp_line, "%2x%2x%2x%2x/%2x%2x%2x%2x%2x%2x",(unsigned int *)&tmp.network[0],(unsigned int *) &tmp.network[1],(unsigned int *) &tmp.network[2],(unsigned int *) &tmp.network[3],(unsigned int *) &tmp.node[0],(unsigned int *) &tmp.node[1],(unsigned int *) &tmp.node[2],(unsigned int *)&tmp.node[3],(unsigned int *) &tmp.node[4],(unsigned int *) &tmp.node[5] ); | | |
if ( n != 10 ) continue; | | |
if ( Ipx_num_users < MAX_USERS ) { | | |
ubyte * ipx_real_buffer = (ubyte *)&tmp; | | |
ipx_get_local_target( tmp.network, tmp.node, tmp.address ); | | |
Ipx_users[Ipx_num_users++] = tmp; | | |
printf( "%02X%02X%02X%02X/", ipx_real_buffer[0],ipx_real_buffer[1],ipx_real_buffer[2],ipx_real_buffer[3] ); | | |
printf( "%02X%02X%02X%02X%02X%02X\n", ipx_real_buffer[4],ipx_real_buffer[5],ipx_real_buffer[6],ipx_real_buffer[7],ipx_real_buffer[8],ipx_real_buffer[9] ); | | |
} else { | | |
printf( "Too many addresses in %s! (Limit of %d)\n", filename, MAX_USERS ); | | |
fclose(fp); | | |
return; | | |
} | | |
} | | |
fclose(fp); | | |
} | | |
| | |
| | |
void ipx_read_network_file(char * filename) | | struct ipx_driver * arch_ipx_set_driver(char *arg) |
{ | | { |
FILE * fp; | | return &ipx_dos; |
user_address tmp; | | |
char temp_line[132], *p1; | | |
int i, n, ln=0; | | |
| | |
if (!filename) return; | | |
| | |
fp = fopen( filename, "rt" ); | | |
if ( !fp ) return; | | |
| | |
printf( "Using Networks:\n" ); | | |
for (i=0; i<Ipx_num_networks; i++ ) { | | |
ubyte * n1 = (ubyte *)&Ipx_networks[i]; | | |
printf("* %02x%02x%02x%02x\n", n1[0], n1[1], n1[2], n1[3] ); | | |
} | | |
| | |
while (fgets(temp_line, 132, fp)) { | | |
ln++; | | |
p1 = strchr(temp_line,'\n'); if (p1) *p1 = '\0'; | | |
p1 = strchr(temp_line,';'); if (p1) *p1 = '\0'; | | |
n = sscanf( temp_line, "%2x%2x%2x%2x",(unsigned int *) &tmp.network[0],(unsigned int *) &tmp.network[1],(unsigned int *) &tmp.network[2],(unsigned int *) &tmp.network[3] ); | | |
if ( n != 4 ) continue; | | |
if ( Ipx_num_networks < MAX_NETWORKS ) { | | |
int j; | | |
for (j=0; j<Ipx_num_networks; j++ ) | | |
if ( !memcmp( &Ipx_networks[j], tmp.network, 4 ) ) | | |
break; | | |
if ( j >= Ipx_num_networks ) { | | |
memcpy( &Ipx_networks[Ipx_num_networks++], tmp.network, 4 ); | | |
printf(" %02x%02x%02x%02x\n", tmp.network[0], tmp.network[1], tmp.network[2], tmp.network[3] ); | | |
} | | } |
} else { | | |
printf( "Too many networks in %s! (Limit of %d)\n", filename, MAX_NETWORKS ); | | |
fclose(fp); | | |
return; | | |
} | | |
} | | |
fclose(fp); | | |
| | |
} | | |
| | |
//---typedef struct rip_entry { | | //---typedef struct rip_entry { |
//--- uint network; | | //--- uint network; |