📄 wsockdos.c
字号:
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 + -