⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ipx.c

📁 Libnet is a cross-platform library aimed at game developers. It has an abstract high level API, whic
💻 C
📖 第 1 页 / 共 2 页
字号:
static WORD ipx_vector_segment;static WORD ipx_vector_offset;static ubyte ipx_socket_life = 0; 	// 0=closed at prog termination, 0xff=closed when requested.static local_address ipx_my_node;static WORD ipx_num_packets=32;		// 32 Ipx packetsstatic ipx_packet * packets;static int neterrors = 0;static int ipx_packets_selector;static ecb_header * last_ecb=NULL;static int lastlen=0;static void got_new_packet( ecb_header * ecb );static void ipx_listen_for_packet(ecb_header * ecb );static void free_packet( int id );static void ipx_cancel_listen_for_packet(ecb_header * ecb );static void ipx_send_packet(ecb_header * ecb );static void free_packet( int id ){  packet_buffers[id].packetnum = -1;  packet_free_list[ --num_packets ] = id;  if (largest_packet_index==id)	    while ((--largest_packet_index>0) && (packet_buffers[largest_packet_index].packetnum == -1 ));}static int ipx_get_packet_data( ubyte * data, int detectonly, int maxsize, int channel ){  int i, best, best_id, size;  int n0, n1;  for (i=1; i<ipx_num_packets; i++ )  {    if ( !packets[i].ecb.in_use )    {      got_new_packet( &packets[i].ecb );      packets[i].ecb.in_use = 0;      ipx_listen_for_packet(&packets[i].ecb);    }			  }  best = -1;  best_id = -1;  for (i=0; i<=largest_packet_index; i++ )  {    if ( packet_buffers[i].packetnum > -1 )    {      if ( best == -1 || (packet_buffers[i].packetnum<best) )      {        memcpy(&n0,packet_buffers[i].data,4);        memcpy(&n1,(packet_buffers[i].data+4),4);        if(n0==channel && n1==channel && memcmp( &packet_buffers[i].ipx_from_node, &ipx_my_node, 6 )==0)        {          free_packet(i);        }        else        {          if((n0!=channel || memcmp( &packet_buffers[i].ipx_from_node, &ipx_my_node, 6 )) && n1==channel)          {            best = packet_buffers[i].packetnum;            best_id = i;          }        }      }    }			  }  if ( best_id < 0 ) return 0;  if(detectonly==1) return 1;  size = packet_size[best_id];  if(size>maxsize)    size=maxsize;  memcpy( data, packet_buffers[best_id].data, size );  memcpy( &ipx_from_node,&packet_buffers[best_id].ipx_from_node, 6 );  memcpy( &ipx_from_server,&packet_buffers[best_id].ipx_from_server, 4 );  free_packet(best_id);  return size;}static void got_new_packet( ecb_header * ecb ){  ipx_packet * p;  int id;  unsigned short datasize;  datasize = 0;  last_ecb = ecb;  p = (ipx_packet *)ecb;  if ( p->ecb.in_use )   {     neterrors++;    return;   }  if( p->ecb.completion_code )  {     neterrors++;    return;  }  datasize=swap_short(p->ipx.length);  lastlen=datasize;  datasize -= sizeof(ipx_header);  // Find slot to put packet in...  if ( datasize > 0 && datasize <= sizeof(packet_data) )  {    if ( num_packets >= MAX_PACKETS )     {      neterrors++;      return;    }		    id = packet_free_list[ num_packets++ ];    if (id > largest_packet_index ) largest_packet_index = id;    packet_size[id] = datasize-sizeof(int)-(10*sizeof(ubyte));    packet_buffers[id].packetnum =  p->pd.packetnum;    if ( packet_buffers[id].packetnum < 0 )    {      neterrors++;      return;     }    memcpy( &packet_buffers[id].ipx_from_node, &p->ipx.source.node_id, 6 );    memcpy( &packet_buffers[id].ipx_from_server, &p->ipx.source.network_id, 4 );    memcpy( packet_buffers[id].data, p->pd.data, packet_size[id] );  }   else  {    neterrors++;    return;  }  // Repost the ecb  p->ecb.in_use = 0;}static ubyte *ipx_get_my_local_address(void){  return ipx_my_node.address;}static ubyte *ipx_get_my_server_address(void){  return (ubyte *)&ipx_network;}static void ipx_listen_for_packet(ecb_header * ecb )	{	__dpmi_regs regs;	ecb->in_use = 0x1d;	memset(&regs,0,sizeof regs);	regs.d.ebx = 4;	// Listen For Packet function	regs.d.esi = DPMI_real_offset(ecb);	regs.x.es = DPMI_real_segment(ecb);	__dpmi_int( 0x7a, &regs );}static void ipx_cancel_listen_for_packet(ecb_header * ecb )	{	__dpmi_regs regs;	memset(&regs,0,sizeof regs);	regs.d.ebx = 6;	// IPX Cancel event	regs.d.esi = DPMI_real_offset(ecb);	regs.x.es = DPMI_real_segment(ecb);	__dpmi_int( 0x7A, &regs );}static void ipx_send_packet(ecb_header * ecb )	{	__dpmi_regs regs;	memset(&regs,0,sizeof regs);	regs.d.ebx = 3;	// Send Packet function	regs.d.esi = DPMI_real_offset(ecb);	regs.x.es = DPMI_real_segment(ecb);	__dpmi_int( 0x7A, &regs );}static void ipx_get_local_target( ubyte * server, ubyte * node, ubyte * local_target ){	net_xlat_info * info;	__dpmi_regs regs;			// Get dos memory for call...	info = (net_xlat_info *) (((__tb + 15) & ~15) + __djgpp_conventional_base);	assert( info != NULL );	memcpy( info->network, server, 4 );	memcpy( info->node, node, 6 );		memset(&regs,0,sizeof regs);	regs.d.ebx = 2;		// Get Local Target		regs.x.es = DPMI_real_segment(info);	regs.d.esi = DPMI_real_offset(info->network);	regs.d.edi = DPMI_real_offset(info->local_target);	__dpmi_int( 0x7A, &regs );	// Save the local target...	memcpy( local_target, info->local_target, 6 );}static void ipx_close(void){	__dpmi_regs regs;	if ( ipx_installed )	{		// When using VLM's instead of NETX, the sockets don't		// seem to automatically get closed, so we must explicitly		// close them at program termination.		ipx_installed = 0;		memset(&regs,0,sizeof regs);		regs.d.edx = ipx_socket;		regs.d.ebx = 1;	// Close socket		__dpmi_int( 0x7A, &regs );	}}//---------------------------------------------------------------// Initializes all IPX internals. // If socket_number==0, then opens next available socket.// Returns:	0  if successful.//		-1 if socket already open.//		-2 if socket table full.//		-3 if IPX not installed.//		-4 if couldn't allocate low dos memory//		-5 if error with getting internetwork address//              -6 if nearptrs not availablestatic int ipx_init( int socket_number, int show_address, int detectonly ){	__dpmi_regs regs;	ubyte *ipx_real_buffer;	int i;	if (~_crt0_startup_flags & _CRT0_FLAG_NONMOVE_SBRK) return -6;	if (~_crt0_startup_flags & _CRT0_FLAG_NEARPTR)		if (!__djgpp_nearptr_enable()) return -6;	atexit(ipx_close);	ipx_packetnum = 0;	// init packet buffers.	for (i=0; i<MAX_PACKETS; i++ )	{		packet_buffers[i].packetnum = -1;		packet_free_list[i] = i;	}	num_packets = 0;	largest_packet_index = 0;	// Get the IPX vector	memset(&regs,0,sizeof regs);	regs.d.eax=0x00007a00;	__dpmi_int( 0x2f, &regs );	if ( (regs.d.eax & 0xFF) != 0xFF )	{		return 3;   	}        if(detectonly==1) return 0;	ipx_vector_offset = regs.d.edi & 0xFFFF;	ipx_vector_segment = regs.x.es;	// Open a socket for IPX	memset(&regs,0,sizeof regs);	swab( (char *)&socket_number,(char *)&ipx_socket, 2 );	regs.d.edx = ipx_socket;	regs.d.eax = ipx_socket_life;	regs.d.ebx = 0;	// Open socket	__dpmi_int( 0x7A, &regs );		ipx_socket = regs.d.edx & 0xFFFF;		if ( regs.d.eax & 0xFF )	{		return -2;	}		ipx_installed = 1;	// Find our internetwork address	ipx_real_buffer =  (void *) (((__tb + 15) & ~15) + __djgpp_conventional_base); /* need 1k */	if ( ipx_real_buffer == NULL )	{		return -4;	}	memset(&regs,0,sizeof regs);	regs.d.ebx = 9;		// Get internetwork address	regs.d.esi = DPMI_real_offset(ipx_real_buffer);	regs.x.es = DPMI_real_segment(ipx_real_buffer);	__dpmi_int( 0x7A, &regs );	if ( regs.d.eax & 0xFF )	{		return -2;	}	memcpy( &ipx_network, ipx_real_buffer, 4 );	memcpy( &ipx_my_node, &ipx_real_buffer[4], 6 );	memcpy( &ipx_myy_node, &ipx_real_buffer[4], 6 );	Ipx_num_networks = 0;	memcpy( &Ipx_networks[Ipx_num_networks++], &ipx_network, 4 );	if ( show_address )	{		printf( "My IPX addresss is " );		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] );		printf( "\n" );	}	{		int result = __dpmi_allocate_dos_memory ((sizeof(ipx_packet)*ipx_num_packets + 15)/16, &ipx_packets_selector);		if (result == -1)			return -4;		packets = (void *) ((result << 4) + __djgpp_conventional_base);	}	memset( packets, 0, sizeof(ipx_packet)*ipx_num_packets );	for (i=1; i<ipx_num_packets; i++ )	{		packets[i].ecb.in_use = 0x1d;		packets[i].ecb.socket_id = ipx_socket;		packets[i].ecb.fragment_count = 1;		packets[i].ecb.fragment_pointer[0] = DPMI_real_offset(&packets[i].ipx);		packets[i].ecb.fragment_pointer[1] = DPMI_real_segment(&packets[i].ipx);		packets[i].ecb.fragment_size = sizeof(ipx_packet)-sizeof(ecb_header);			//-sizeof(ecb_header);		ipx_listen_for_packet(&packets[i].ecb);	}	packets[0].ecb.socket_id = ipx_socket;	packets[0].ecb.fragment_count = 1;	packets[0].ecb.fragment_pointer[0] = DPMI_real_offset(&packets[0].ipx);	packets[0].ecb.fragment_pointer[1] = DPMI_real_segment(&packets[0].ipx);	packets[0].ipx.packet_type = 4;		// IPX packet	packets[0].ipx.destination.socket_id = ipx_socket;	memset( packets[0].ipx.destination.network_id, 0, 4 );	return 0;}static void ipx_send_packet_data( ubyte * data, int datasize, ubyte *network, ubyte *address, ubyte *immediate_address ){  assert(ipx_installed);  if ( datasize >= IPX_MAX_DATA_SIZE )    datasize = IPX_MAX_DATA_SIZE;  if(datasize<1)    return;  // Make sure no one is already sending something  while( packets[0].ecb.in_use )  {  }  if (packets[0].ecb.completion_code)  {    printf( "Send error %d for completion code\n", packets[0].ecb.completion_code );    exit(1);  }	// Fill in destination address	if ( memcmp( network, &ipx_network, 4 ) )		memcpy( packets[0].ipx.destination.network_id, network, 4 );	else		memset( packets[0].ipx.destination.network_id, 0, 4 );	memcpy( packets[0].ipx.destination.node_id.address, address, 6 );	memcpy( packets[0].ecb.immediate_address.address, immediate_address, 6 );	packets[0].pd.packetnum = ipx_packetnum++;	// Fill in data to send	packets[0].ecb.fragment_size = sizeof(ipx_header) + sizeof(int) + 10*sizeof(ubyte) + datasize;	memcpy( packets[0].pd.data, data, datasize );	// Send it	ipx_send_packet( &packets[0].ecb );}// Sends a non-localized packet... needs 4 byte server, 6 byte addressstatic 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 );	}}static int ipx_change_default_socket( ushort socket_number ){	int i;	WORD new_ipx_socket;	__dpmi_regs regs;	if ( !ipx_installed ) return -3;	// Open a new socket		memset(&regs,0,sizeof regs);	swab( (char *)&socket_number,(char *)&new_ipx_socket, 2 );	regs.d.edx = new_ipx_socket;	regs.d.eax = ipx_socket_life;	regs.d.ebx = 0;	// Open socket	__dpmi_int( 0x7A, &regs );		new_ipx_socket = regs.d.edx & 0xFFFF;		if ( regs.d.eax & 0xFF )	{		return -2;	}	for (i=1; i<ipx_num_packets; i++ )	{		ipx_cancel_listen_for_packet(&packets[i].ecb);	}	// Close existing socket...	memset(&regs,0,sizeof regs);	regs.d.edx = ipx_socket;	regs.d.ebx = 1;	// Close socket	__dpmi_int( 0x7A, &regs );	ipx_socket = new_ipx_socket;	// Repost all listen requests on the new socket...		for (i=1; i<ipx_num_packets; i++ )	{		packets[i].ecb.in_use = 0;		packets[i].ecb.socket_id = ipx_socket;		ipx_listen_for_packet(&packets[i].ecb);	}	packets[0].ecb.socket_id = ipx_socket;	packets[0].ipx.destination.socket_id = ipx_socket;	ipx_packetnum = 0;	// init packet buffers.	for (i=0; i<MAX_PACKETS; i++ )	{		packet_buffers[i].packetnum = -1;		packet_free_list[i] = i;	}	num_packets = 0;	largest_packet_index = 0;	return 0;}#else /* __USE_REAL_IPX_DOS__ *//* Can't use the DOS-style IPX on this platform, so put in a dummy * driver. */#include <stdlib.h>#include <stdio.h>#include "libnet.h"#include "internal.h"static int detect (void) { return NET_DETECT_NO; }static void load_config (NET_DRIVER *drv, FILE *fp) { }NET_DRIVER net_driver_ipx_dos = {	"IPX from DOS", "Dummy driver", NET_CLASS_IPX,	detect,	NULL, NULL,	NULL, NULL,	NULL, NULL,	NULL, NULL, NULL, NULL,	NULL, NULL, NULL, NULL, NULL, NULL,	NULL, NULL, NULL, NULL, NULL,	load_config,	NULL, NULL};#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -