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

📄 ipx.c

📁 Libnet is a cross-platform library aimed at game developers. It has an abstract high level API, whic
💻 C
📖 第 1 页 / 共 2 页
字号:
/*---------------------------------------------------------------- * ipx.c - IPX network driver for libnet *---------------------------------------------------------------- *  libnet is (c) Copyright Chad Catlett and George Foot 1997-1999 * *  Please look in `docs' for details, documentation and *  distribution conditions. */#include "platdefs.h"/* If this platform supports Dos style IPX use them. Otherwise use * a dummy driver */#ifdef __USE_REAL_IPX_DOS__/* ugh, I really hate the nearptr hack... */#include <sys/nearptr.h>#define DPMI_real_segment(P) ((((uint)(P)-(uint)(__djgpp_conventional_base)) >> 4) & 0xffff)#define DPMI_real_offset(P) (((uint)(P)-(uint)(__djgpp_conventional_base)) & 0xf)#include <crt0.h>#include <mem.h>#include <string.h>#include <go32.h>#include <dpmi.h>#include <dos.h>#include <stdio.h>#include <stdlib.h>#include <assert.h>#include "libnet.h"#include "internal.h"#include "config.h"#include "types.h"static int ipx_init( int socket_number, int show_address, int detectonly );static void ipx_close(void);static int ipx_change_default_socket( ushort socket_number );static ubyte *ipx_get_my_local_address(void);static ubyte *ipx_get_my_server_address(void);static void ipx_get_local_target( ubyte * server, ubyte * node, ubyte * local_target );static int ipx_get_packet_data( ubyte * data, int detectonly, int maxsize, int channel );static void ipx_send_packet_data( ubyte * data, int datasize, ubyte *network, ubyte *address, ubyte *immediate_address );static void ipx_send_internetwork_packet_data( ubyte * data, int datasize, ubyte * server, ubyte *address );typedef struct PORTstruct PORT, *PORTp;typedef struct PORTstruct               /* link structure */{  PORTp next;                          /* linked list next node */  PORTp prev;                          /* linked list previous node */  int port;} PORTstruct;static int add_port(int port);static void kill_port(int port);static PORTp findport(int port);static PORTp top_nodel, bottom_nodel;   /* nodes in linked list */static int next_port=1;static DWORD ipx_network = 0;static ubyte ipx_myy_node[6];static ubyte ipx_from_node[6], ipx_from_server[4];static char dosipx_desc[80] = "IPX network driver";static int add_port(int port){  PORTp objp;  objp=findport(port);  if(objp!=NULL)    return 0;  objp=malloc(sizeof(PORT));  objp->port=port;  if (bottom_nodel==(PORTp)NULL)  {    bottom_nodel=objp;    objp->prev=(PORTp)NULL;  }  else  {    objp->prev=top_nodel;    objp->prev->next=objp;  }  top_nodel=objp;  objp->next=(PORTp)NULL;  return 1;}static void kill_port(int port){  PORTp node, objp;  objp=findport(port);  if(objp==NULL)    return;  node=objp;  if (node==bottom_nodel)  {    bottom_nodel=node->next;    if (bottom_nodel!=(PORTp)NULL) bottom_nodel->prev=(PORTp)NULL;  }  else if (node==top_nodel)  {    top_nodel=node->prev;    top_nodel->next=(PORTp)NULL;  }  else  {    node->prev->next=node->next;    node->next->prev=node->prev;  }  free(node);}static PORTp findport(int port){  PORTp nodel;  PORTp next_nodel;  if(bottom_nodel!=NULL)  {    for (nodel=bottom_nodel;nodel!=(PORTp)NULL;nodel=next_nodel)    {      next_nodel=nodel->next;      if(port==nodel->port)        return nodel;    }   }  return NULL;}/* disable_driver: set by the config loader to disable this driver */static int disable_driver = 0;/* detect: *  This function returns one of the following: * *  - NET_DETECT_YES    (if the network driver can definitely work) *  - NET_DETECT_NO     (if the network driver definitely cannot work) */static int dosipx_detect (void){   if (disable_driver) return NET_DETECT_NO;  if(ipx_init(0,0,1)!=0)    return NET_DETECT_NO;  return NET_DETECT_YES;}/* init: *  Initialises the driver.  Return zero if successful, non-zero if not. */static int dosipx_init (void) {  top_nodel=NULL;  bottom_nodel=NULL;  return ipx_init(0x869d,0,0); }static int dosipx_exit (void) {  PORTp nodel;  PORTp next_nodel;  ipx_close();  if(bottom_nodel!=NULL)  {    for (nodel=bottom_nodel;nodel!=(PORTp)NULL;nodel=next_nodel)    {      next_nodel=nodel->next;      kill_port(nodel->port);    }   }  return 0; }static int dosipx_init_channel    (NET_CHANNEL *chan, const char *addr) {  ubyte *ipx_real_buffer, *ipx_real_bufferx;  ubyte broadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };  int port;  char buffer[80];  if (!(chan->data = malloc(20))) return -1;  /* binding specifies a channel # for the channel   * "" is default port 0   * NULL is next avalible port   * :port is port   */  if(addr==NULL)  {    do    {      port=next_port;      next_port+=1;    } while (findport(port)!=NULL);    next_port=1;  }  else  {    if (strcmp(addr,"")==0)    {      port=0;    }    else    {      if(addr[0]==':')      {        port=atoi(addr+1);      }      else      {        return 1;      }    }  }  if(add_port(port)==0)    return 1;  ipx_real_buffer=(ubyte *)&ipx_network;  ipx_real_bufferx=(ubyte *)&ipx_myy_node;  sprintf(chan->local_addr,"%02X%02X%02X%02X/%02X%02X%02X%02X%02X%02X:",ipx_real_buffer[0],ipx_real_buffer[1],ipx_real_buffer[2],ipx_real_buffer[3],ipx_real_bufferx[0],ipx_real_bufferx[1],ipx_real_bufferx[2],ipx_real_bufferx[3],ipx_real_bufferx[4],ipx_real_bufferx[5] );  itoa(port,buffer,10);  strcat(chan->local_addr,buffer);  memcpy(chan->data,ipx_real_buffer,4); // send to local network  memcpy(chan->data+4,broadcast,6);     // broadcast to all  memcpy(chan->data+10,&port,4); // your channel  memset(chan->data+14,0,4); // channel to send to  return 0; }static int dosipx_destroy_channel (NET_CHANNEL *chan) {   int port;  memcpy(&port,chan->data+10,4);  kill_port(port);  free(chan->data);  return 0;}static int dosipx_update_target   (NET_CHANNEL *chan) {  char *data, rad[3], **stop_at=NULL;  ubyte tmpadr[14];  int i, offset;  ubyte *ipx_real_buffer;  data=chan->target_addr;  if(strlen(data)<12)    return 1;  offset=0;  ipx_real_buffer=(ubyte *)&ipx_network;  memcpy(chan->data,ipx_real_buffer,4);  if(data[8]=='/')  {    rad[2]=0;    for(i=0;i<4;i++)    {      strncpy(rad,(data+(i*2)),2);      tmpadr[i] = (ubyte)strtol(rad,stop_at,16);    }    memcpy(chan->data,tmpadr,4);    offset=9;  }  rad[2]=0;  for(i=0;i<6;i++)  {    strncpy(rad,(data+(i*2)+offset),2);    tmpadr[i] = (ubyte)strtol(rad,stop_at,16);  }  memcpy(chan->data+4,tmpadr,6);  memset(chan->data+14,0,4);  if(data[offset+12]==':')  {    i=atoi(data+offset+13);    memcpy((chan->data+14),&i,4);  }  return 0; }static int dosipx_send (NET_CHANNEL *chan, const void *buf, int size) {  ubyte *packet;  packet=malloc(size+8);  memcpy(packet,(chan->data+10),8);  memcpy((packet+8),buf,size);  ipx_send_internetwork_packet_data(packet, size+8, chan->data, (chan->data+4));  free(packet);  return 0; }static int dosipx_recv (NET_CHANNEL *chan, void *buf, int size, char *from) {  int datasize;  ubyte *ipx_real_buffer, *ipx_real_bufferx;  ubyte *packet;  int channel;  char buffer[80];  packet=malloc(size+8);  memcpy(&channel,(chan->data+10),4);  datasize=ipx_get_packet_data(packet, 0, size+8, channel);  if(datasize==0)  {    free(packet);    return 0;  }  memcpy(buf,(packet+8),datasize-8);  if(from!=NULL)  {    ipx_real_buffer=(ubyte *)&ipx_from_server;    ipx_real_bufferx=(ubyte *)&ipx_from_node;    sprintf(from,"%02X%02X%02X%02X/%02X%02X%02X%02X%02X%02X:",ipx_real_buffer[0],ipx_real_buffer[1],ipx_real_buffer[2],ipx_real_buffer[3],ipx_real_bufferx[0],ipx_real_bufferx[1],ipx_real_bufferx[2],ipx_real_bufferx[3],ipx_real_bufferx[4],ipx_real_bufferx[5] );    memcpy(&channel,packet,4);    itoa(channel,buffer,10);    strcat(from,buffer);  }  free(packet);  return (datasize-8); }/* query: *  Returns non-zero if there is data waiting to be read from the channel. */static int dosipx_query (NET_CHANNEL *chan){  int channel;  memcpy(&channel,(chan->data+10),4);  return (ipx_get_packet_data(NULL,1,0,channel));}/* load_config: *  This will be called once when the library is initialised, inviting the *  driver to load configuration information from the passed text file. */static void dosipx_load_config (NET_DRIVER *drv, FILE *fp) {   char *option, *value, **stop_at=NULL;  int x;  if (__libnet_internal__seek_section (fp, "ipx")) return;    while (__libnet_internal__get_setting (fp, &option, &value) == 0) {        if (!strcmp (option, "socket")) {      x = strtol (value,stop_at,0);      ipx_change_default_socket((ushort)x);    } else if (!strcmp (option, "disable")) {      disable_driver = (atoi (value) || (value[0] == 'y'));    }  }    if (drv->load_conn_config) drv->load_conn_config (drv, fp, "ipx");}NET_DRIVER net_driver_ipx_dos = {	"IPX", 	dosipx_desc,	NET_CLASS_IPX,	dosipx_detect,	dosipx_init,	dosipx_exit,	NULL, NULL,	dosipx_init_channel,	dosipx_destroy_channel,	dosipx_update_target,	dosipx_send,	dosipx_recv,	dosipx_query,	NULL, NULL,	NULL, NULL, NULL, NULL,	NULL, NULL, NULL, NULL, NULL,	dosipx_load_config,	NULL, NULL};#define IPX_MAX_DATA_SIZE (1024)		static inline unsigned int swap_short( unsigned int sshort ) {	asm("xchgb %h0,%b0"         : "=q" (sshort)          : "0" (sshort));	return sshort;}typedef struct local_address {	ubyte address[6];} __pack__ local_address;typedef struct net_address {	BYTE		network_id[4];				local_address	node_id;	WORD		socket_id;} __pack__ net_address;typedef struct ipx_header {	WORD		checksum;	WORD		length;	BYTE		transport_control;	BYTE		packet_type;	net_address	destination;	net_address	source;} __pack__ ipx_header;typedef struct ecb_header {	WORD		link[2];	WORD		esr_address[2];	volatile BYTE	in_use;	BYTE		completion_code;	WORD		socket_id;	BYTE		ipx_reserved[14];        	WORD		connection_id;	local_address   immediate_address;	WORD    	fragment_count;	WORD		fragment_pointer[2];	WORD		fragment_size;} __pack__ ecb_header;typedef struct packet_data {	int		packetnum;        ubyte           ipx_from_node[6];        ubyte           ipx_from_server[4];	byte		data[IPX_MAX_DATA_SIZE];} __pack__ packet_data;typedef struct ipx_packet {	ecb_header	ecb;	ipx_header	ipx;	packet_data	pd;} __pack__ ipx_packet;typedef struct user_address {	ubyte network[4];	ubyte node[6];	ubyte address[6];} __pack__ user_address;typedef struct {	ubyte 	network[4];	ubyte	node[6];	ubyte	local_target[6];} __pack__ net_xlat_info;#define MAX_NETWORKS 64static int Ipx_num_networks = 0;static uint Ipx_networks[MAX_NETWORKS];static int ipx_packetnum = 0;#define MAX_PACKETS 64static packet_data packet_buffers[MAX_PACKETS];static short packet_free_list[MAX_PACKETS];static int num_packets = 0;static int largest_packet_index = 0;static short packet_size[MAX_PACKETS];static WORD ipx_socket=0;static ubyte ipx_installed=0;

⌨️ 快捷键说明

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