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

📄 wsockdos.c

📁 Libnet is a cross-platform library aimed at game developers. It has an abstract high level API, whic
💻 C
📖 第 1 页 / 共 3 页
字号:
	if (ioctlsocket (dns_socket, FIONBIO, (u_long *)&one)) {		closesocket (dns_socket);		return 1;	}	return 0;}static void destroy_socket(void) {	closesocket (dns_socket);}static void send_request (int nameserver, char *hostname) {	int packetid = ++dns_pkt_id;	{		struct done_list_t *ptr1 = done_list;		struct wait_list_t *ptr2 = waiting_list;		while (ptr1->next) {			ptr1 = ptr1->next;			if ((ptr1->nameserver == nameserver) && !stricmp (ptr1->hostname, hostname))				return;     /* already done this query */		}		while (ptr2->next) ptr2 = ptr2->next;		ptr1->next = (struct done_list_t *) malloc (sizeof (struct done_list_t));		if (!ptr1->next) return;		ptr2->next = (struct wait_list_t *) malloc (sizeof (struct wait_list_t));		if (!ptr2->next) {			free (ptr1->next);			return;		}		ptr1->next->next = NULL; 		ptr1 = ptr1->next;		ptr2->next->prev = ptr2;		ptr2->next->next = NULL;		ptr2 = ptr2->next;		ptr2->nameserver = ptr1->nameserver = nameserver;		ptr2->hostname   = ptr1->hostname   = strdup (hostname);		ptr2->id                            = packetid;		ptr2->reply                         = NULL;	}	{		struct dns_packet packet;		struct dns_query query;		packet.nameserver  = nameserver;		packet.id          = packetid;		packet.flags.i     = 0;		packet.qdcount     = 1;		packet.ancount     = 0;		packet.nscount     = 0;		packet.arcount     = 0;		packet.questions   = &query;		packet.answers     = NULL;		packet.authorities = NULL;		packet.additionals = NULL;		query.qname  = hostname;		query.qtype  = DNS_TYPE_A;		query.qclass = DNS_CLASS_IN;		put_packet (&packet);	}	{		struct sockaddr_in addr;		addr.sin_family      = AF_INET;		addr.sin_port        = htons (IPPORT_DNS);		addr.sin_addr.s_addr = htonl (nameserver);		sendto (dns_socket, data_block, data_size, 0, (struct sockaddr *)&addr, sizeof (addr));	}}static struct wait_list_t *get_reply(void) {	struct dns_packet *data;	struct wait_list_t *x;	data_size = recvfrom (dns_socket, data_block, 512, 0, NULL, NULL);	if ((data_size == 0) || (data_size == SOCKET_ERROR)) return 0;	/* Got some data; now decode it */	data = (struct dns_packet *) malloc (sizeof (struct dns_packet));	if (!data) return 0;	get_packet (data);	/* Find the right entry in the waiting list */	for (x = waiting_list->next; x && (x->id != data->id); x = x->next);	if (!x) {                   /* not in list */		free_packet (data);		free (data);		return 0;	}	if (x->next) x->next->prev = x->prev;	if (x->prev) x->prev->next = x->next;	x->reply = data;	return x;}/* dns_lookup: *  Performs a DNS lookup.  If successful, the IP address is stored in *  `address' in host format; otherwise INADDR_NONE (255.255.255.255) is *  put there. * *  Parameters: *      `what' is a string containing a hostname *      `timeout' is a timeout value in seconds *      `address' is a pointer to somewhere to store the resulting IP * *  Return value: *      0   :   hostname resolved successfully *      1   :   internal failure (e.g. memory problem) *      2   :   host not found (non-authoritative) *      3   :   authoritative `host not found' */int __libnet_internal_wsockdos__dns_lookup (const char *what, int timeout, void *address) {	int *addr = address;            /* `int *' is easier to deal with */	int retval,i,j;	char buffer[1024];              /* this always holds the name we're currently looking up (may not be `what' due to CNAMEs) */	int time_limit = clock() + timeout * CLOCKS_PER_SEC;	dns_pkt_id = 0;	if (strlen (what) >= 1024) return 1;	if (!addr) return 1;	if (create_socket()) return 1;	if (create_lists()) { destroy_socket(); return 1; }	*addr = INADDR_NONE;	strcpy (buffer, what);	for (i = 0; i < num_nameservers; i++)		send_request (nameserver[i], buffer);	retval = 2;	while ((clock() < time_limit) && (waiting_list->next) && (retval == 2)) {		struct wait_list_t *x = get_reply();		if (x) {			if (x->reply->flags.f.rcode == 3) { /* auth. host-not-found */				*addr = INADDR_NONE;				retval = 3;			} else {				/* check for address answer */				for (i = 0; i < x->reply->ancount; i++)					if ((x->reply->answers[i].type == DNS_TYPE_A)					 && (x->reply->answers[i]._class == DNS_CLASS_IN)) {						*addr = x->reply->answers[i].data.a.address;						retval = 0;						goto near_end_of_loop;					}				/* check for CNAME answer */				for (i = 0; i < x->reply->ancount; i++)					if ((x->reply->answers[i].type == DNS_TYPE_CNAME)					 && (x->reply->answers[i]._class == DNS_CLASS_IN)) {						strcpy (buffer, x->reply->answers[i].data.cname.cname);					}				/* ask the nameserver again in case it was a cname */				send_request (x->nameserver,buffer);				/* ask all the authoritative nameservers */				for (i = 0; i < x->reply->nscount; i++)					if (x->reply->authorities[i].type == DNS_TYPE_NS) {						int y = 1;						for (j = 0; (j < x->reply->arcount) && y; j++)							if (x->reply->additionals[j].type == DNS_TYPE_A)								if (!stricmp (x->reply->additionals[j].name, x->reply->authorities[i].data.ns.nsdname)) {									y = 0;									send_request (x->reply->additionals[j].data.a.address, buffer);								}					}			}			near_end_of_loop:			free_packet (x->reply);			free (x->reply);			free (x);		}	}	destroy_lists();	destroy_socket();	return retval;}/*------------------------------------------------ libnet interface */#include "libnet.h"#include "internal.h"#include "config.h"static char desc[80] = "Internet via Winsock from DOS";static int default_port = 24785;    /* default port */static int forceport = 0;           /* should we reuse non-vacant ports? */static int ip_address = 0;          /* IP address */int __libnet_internal_wsockdos__dns_timeout = 10;  /* seconds */static int auto_get_ip = 0;         /* should we try to guess our IP? */struct channel_data_t {	SOCKET sock;	struct sockaddr_in target_address;	int address_length;};static int disable_driver = 0;static int detect(void){	if (disable_driver) return NET_DETECT_NO;	return winsock_detect() ? NET_DETECT_NO : NET_DETECT_YES;}static int get_my_ip (int server, int port, int timelimit) {	SOCKET sock;	struct sockaddr_in addr;	u_long one = 1;	int addrlength;	int clock_limit = clock() + timelimit * CLOCKS_PER_SEC;	int clockdiff;	sock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);	if (sock == INVALID_SOCKET) return 0;	if (ioctlsocket (sock, FIONBIO, &one)) {		closesocket (sock);		return 0;	}	addr.sin_family = AF_INET;	addr.sin_port = 0;	addr.sin_addr.s_addr = INADDR_ANY;	addrlength = sizeof (addr);	if (bind (sock, (struct sockaddr *)&addr, addrlength)) {		closesocket (sock);		return 0;	}	addr.sin_addr.s_addr = htonl (server);	addr.sin_port = htons (port);	addr.sin_family = AF_INET;	if (connect (sock, (struct sockaddr *)&addr, addrlength) && (last_error != WSAEWOULDBLOCK)) {		closesocket (sock);		return 0;	}	clockdiff = 1;	do {		{			int clockstop = clock() + (clockdiff *= 2);			while (clock() < clockstop);		} 		addrlength = sizeof (addr);		getsockname (sock, (struct sockaddr *) &addr, &addrlength);	} while ((addr.sin_addr.s_addr == 0) && (clock() < clock_limit));	closesocket (sock);	return ntohl(addr.sin_addr.s_addr);}static int init(void) {	if (winsock_init()) return -1;	if (auto_get_ip) {		int i = 0;		while ((i < num_nameservers) && !ip_address)			ip_address = get_my_ip (nameserver[i++], 53, 5);	}	return 0;}static int drv_exit(void){	return winsock_exit();}#include "inetaddr.h"static int do_init_channel (NET_CHANNEL *chan, int addr, int port, int forceport) {	struct channel_data_t *data;	int addrlength;	struct sockaddr_in sock_addr;	u_long a;	data = (struct channel_data_t *) malloc (sizeof (struct channel_data_t));	if (!data) return 1;	chan->data = data;	data->sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);	if (data->sock==INVALID_SOCKET) { free(data); return 2; }	a = 1;	if (ioctlsocket (data->sock, FIONBIO, &a)) {		closesocket(data->sock);		free(data);		return 3;	}	/* if forceport is set, tell socket not to fail its bind operation if port 	 * is already in use */	setsockopt (data->sock, SOL_SOCKET, SO_REUSEADDR, (char *)&forceport, sizeof (forceport));	sock_addr.sin_family      = AF_INET;	sock_addr.sin_port        = htons(port);	sock_addr.sin_addr.s_addr = htonl(addr);	addrlength = sizeof (sock_addr);	if (bind (data->sock, (struct sockaddr *)&sock_addr, addrlength)) {		closesocket(data->sock);		free(data);		return 4;	}	getsockname (data->sock, (struct sockaddr *)&sock_addr, &addrlength);	write_address (chan->local_addr, &sock_addr);	return 0;}static int init_channel (NET_CHANNEL *chan, const char *addr) {	int a, p, f = forceport;	if (!addr) return do_init_channel (chan, 0, 0, 0);	if (*addr == '+') {		f = 1;		addr++;	} else if (*addr == '-') {		f = 0;		addr++;	}	if (!*addr) return do_init_channel (chan, 0, default_port, f);	parse_address (addr, &a, &p);	if (!p) p = default_port;	return do_init_channel (chan, a, p, f);}static int update_target (NET_CHANNEL *chan) {	struct channel_data_t *data = chan->data;	int addr, port;	if (parse_address (chan->target_addr, &addr, &port)) return 1;	if (port == 0) port = default_port;	data->target_address.sin_family = AF_INET;	data->target_address.sin_port = htons(port);	data->target_address.sin_addr.s_addr = htonl(addr);	data->address_length = sizeof (data->target_address);	return 0;}static int destroy_channel (NET_CHANNEL *chan) {	closesocket (((struct channel_data_t *)chan->data)->sock);	free (chan->data);	return 0;}static int drv_send (NET_CHANNEL *chan, const void *buf, int size) {	struct channel_data_t *data = chan->data;	int x;	if (!size) return 1;    /* filter out empty packets */	x = sendto (data->sock, (char *) buf, size, 0, (struct sockaddr *) &data->target_address, data->address_length);	return (x == SOCKET_ERROR);}static int drv_recv (NET_CHANNEL *chan, void *buf, int size, char *from) {	struct channel_data_t *data = chan->data;	struct sockaddr_in from_addr;	int size_read, addrsize = sizeof (from_addr);	size_read = recvfrom (data->sock, (char *)buf, size, 0, (struct sockaddr *) &from_addr, &addrsize);	if (size_read >= 0) {		if (from) write_address (from, &from_addr);		return size_read;	} else		return -1;}static int query (NET_CHANNEL *chan) {	struct channel_data_t *data = chan->data;	u_long x = 0;	ioctlsocket (data->sock, FIONREAD, &x);	return !!x;}static void load_config (NET_DRIVER *drv, FILE *fp) {  char *option, *value;    if (!__libnet_internal__seek_section (fp, "internet")) {    while (__libnet_internal__get_setting (fp, &option, &value) == 0) {            if (!stricmp (option, "port")) {		int x = atoi (value);	if (x) default_port = x;	      } else if (!stricmp (option, "forceport")) {		forceport = atoi (value);	      } else if (!stricmp (option, "ip")) {		char *chp = value;	int addr = 0, i;		for (i = 0; i < 4; i++) {	  while ((*chp) && (*chp != '.')) chp++;	  if (*chp) *chp++ = 0;	  addr = (addr << 8) + atoi (value);	  value = chp;	}		ip_address = addr;	      } else if (!strcmp (option, "disable")) {        disable_driver = (atoi (value) || (value[0] == 'y'));      }    }  }    if (!__libnet_internal__seek_section (fp, "winsock_dos")) {    while (__libnet_internal__get_setting (fp, &option, &value) == 0) {            if (!stricmp (option, "nameserver")) {		char *chp = value;	int addr = 0, i;		if (num_nameservers < MAX_NAMESERVERS) {	  num_nameservers++;	  for (i = 0; i < 4; i++) {	    while ((*chp) && (*chp != '.')) chp++;	    if (*chp) *chp++ = 0;	    addr = (addr << 8) + atoi (value);	    value = chp;	  }	  nameserver[num_nameservers-1] = addr;	} 	      } else if (!stricmp (option, "dns_timeout")) {		int x = atoi (value);	if (x) __libnet_internal_wsockdos__dns_timeout = x;	      } else if (!stricmp (option, "auto_get_ip")) {		auto_get_ip = atoi (value);	      } else if (!strcmp (option, "disable")) {        disable_driver = (atoi (value) || (value[0] == 'y'));      }    }  }    if (drv->load_conn_config) drv->load_conn_config (drv, fp, "internet");}NET_DRIVER net_driver_wsock_dos = {	"Winsock from DOS",	desc,	NET_CLASS_INET,	detect,	init,	drv_exit,	NULL, NULL,		init_channel,	destroy_channel,		update_target,	drv_send,	drv_recv,	query,		NULL, NULL,	NULL, NULL, NULL, NULL,	NULL, NULL, NULL, NULL, NULL,		load_config,	NULL, NULL};#else /* __USE_REAL_WSOCK_DOS__ *//* Can't use the Winsock DOS-style 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_wsock_dos = {	"Winsock from DOS", "Dummy driver", NET_CLASS_INET,	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 + -