| 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; |