📄 wsockdos.c
字号:
s = _farpeekl (SocketP, 3 * 4); if (error==0) return s; else { handle_error(error); return INVALID_SOCKET; }}/* Initialisation of the VxD and interface */static int i_loaded_wsock_vxd = 0;static int i_loaded_wsock_386 = 0;static int vxd_loaded = 0;static int load_wsock_vxd (void){ if (vxd_loaded) return 0; if (VxdLdrLoadDevice ("WSOCK.VXD") == 0) i_loaded_wsock_vxd = 1; if (VxdLdrLoadDevice ("WSOCK.386") == 0) i_loaded_wsock_386 = 1; VxdGetEntry (WSockEntry, 0x003e); vxd_loaded = (WSockEntry[1] != 0); /* CS == 0 => wsock.vxd not present */ return vxd_loaded ? 0 : 1;}static int unload_wsock_vxd (void) { int retval = 0; if (i_loaded_wsock_vxd) { i_loaded_wsock_vxd = 0; if (VxdLdrUnLoadDevice ("WSOCK.VXD")) retval = 1; } if (i_loaded_wsock_386) { i_loaded_wsock_386 = 0; if (VxdLdrUnLoadDevice ("WSOCK.386")) retval = 1; } vxd_loaded = 0; return retval;}static int winsock_detect (void) { int retval; retval = load_wsock_vxd(); unload_wsock_vxd(); return retval;}#define ERRORLEVEL(xxx) do { retval = xxx; goto error_level_##xxx; } while (0)static int winsock_init (void) { int retval = -1; if (load_wsock_vxd()) ERRORLEVEL(1); _SocketP.handle = 0; _SocketP.size = 65536; _SocketP.address = 0; if (__dpmi_allocate_memory (&_SocketP) == -1) ERRORLEVEL(2); _SocketD.handle = 0; _SocketD.size = 65536; _SocketD.address = 0; if (__dpmi_allocate_memory (&_SocketD) == -1) ERRORLEVEL(3); if ((SocketP = __dpmi_allocate_ldt_descriptors (1)) == -1) ERRORLEVEL(4); if ((SocketD = __dpmi_allocate_ldt_descriptors (1)) == -1) ERRORLEVEL(5); if ((__dpmi_set_segment_base_address (SocketP, _SocketP.address) == -1) || (__dpmi_set_segment_base_address (SocketD, _SocketD.address) == -1) || (__dpmi_set_segment_limit (SocketP, _SocketP.size) == -1) || (__dpmi_set_segment_limit (SocketD, _SocketD.size) == -1)) ERRORLEVEL(6); return 0; error_level_6: __dpmi_free_ldt_descriptor (SocketD); error_level_5: __dpmi_free_ldt_descriptor (SocketP); error_level_4: __dpmi_free_memory (_SocketD.handle); error_level_3: __dpmi_free_memory (_SocketP.handle); error_level_2: unload_wsock_vxd(); error_level_1: return retval;}static int winsock_exit (void) { int retval = 0; retval |= __dpmi_free_ldt_descriptor (SocketD); retval |= __dpmi_free_ldt_descriptor (SocketP); retval |= __dpmi_free_memory (_SocketD.handle); retval |= __dpmi_free_memory (_SocketP.handle); retval |= unload_wsock_vxd(); return retval;}/*------------------------------------------------ DNS lookup code */#include "dns.h"#define MAX_NAMESERVERS 4static int num_nameservers = 0;static int nameserver[MAX_NAMESERVERS] = { 0 };static unsigned char data_block[512];static int data_size = 0;/* Data putting routines -- these put data into the send/receive buffer. * It's all big-endian. */static void put_1 (int *offset, int x) { if (offset && (*offset >= 0) && (*offset < 512)) data_block [(*offset)++] = x; else if (offset) *offset = -1; if (*offset > data_size) data_size = *offset;}static void put_2 (int *offset, int x) { put_1 (offset, (x & 0xff00) >> 8); put_1 (offset, (x & 0x00ff));}static void put_4 (int *offset, int x) { put_2 (offset, (x & 0xffff0000) >> 16); put_2 (offset, (x & 0x0000ffff));}static void put_hostname (int *offset, char *hostname) { char *p, *q; if ((!offset) || (*offset < 0)) return; if (*hostname == 0) { if (*offset >= 512) { *offset = -1; return; } data_block[(*offset)++] = 0; return; } if (*offset + 1 + strlen (hostname) >= 512) { *offset = -1; return; } strcpy (data_block + *offset + 1, hostname); p = data_block + *offset; q = p + 1; do { while (*q && (*q != '.')) q++; *p = q - (p + 1); p = q++; } while (*p); *offset = ((unsigned char *)q) - data_block; if (*offset > data_size) data_size = *offset;}/* Data getting routines -- these get data from the buffer used for sends * and receives. Big-endian again. */static int do_get_1 (int *offset) { return (offset && (*offset >= 0) && (*offset < data_size)) ? data_block[(*offset)++] : ((offset ? *offset = -1 : 0), 0);}static int get_1 (int *offset) { int x = do_get_1 (offset); return x;}static int get_2 (int *offset) { int ret = get_1(offset); return (ret << 8) + get_1(offset);}static int get_4 (int *offset) { int ret = get_2(offset); return (ret<<16) + get_2(offset);}static char *get_char_string (int *offset, char *buffer) { int ch,i; ch = get_1 (offset); for (i = 0; i < ch; i++) buffer[i] = get_1 (offset); buffer[i] = 0; return i ? buffer : NULL;}static char *get_hostname (int *offset, char *buffer) { static int depth = 0; int ch; #define MAX_DEPTH 20 #define RETURN(xxx) do { char *__fubar = (xxx); depth--; return (__fubar); } while (0) if (++depth > MAX_DEPTH) RETURN (NULL); ch = get_1 (offset); /* read the label length byte */ if (ch == 0) { /* If it's zero, this is the end of the hostname */ *buffer = 0; RETURN (buffer); } switch (ch >> 6) { case 0: /* It's a label */ { int i; for (i = 0; i < ch; i++) buffer[i] = get_1 (offset); buffer[i] = '.'; get_hostname (offset, buffer+i+1); if (!buffer[i+1]) buffer[i] = 0; } break; case 3: /* It's a pointer to somewhere else in the data */ { int i = ((ch & 0x3f) << 8) + get_1 (offset); get_hostname (&i, buffer); } break; default: /* Undefined; this should never occur */ *buffer = 0; RETURN (NULL); } RETURN (buffer); #undef MAX_DEPTH #undef RETURN}/* clear_datablock: * Clears the packet buffer, zeroing its size. */static void clear_datablock(void) { memset (data_block, 0, 512); data_size = 0;}/* These are utility routines to translate the dns_query and dns_packet structs into the RFC1035 format. */static void put_query (int *offset, struct dns_query *q) { put_hostname (offset, q->qname); put_2 (offset, q->qtype); put_2 (offset, q->qclass);}static void get_query (int *offset, struct dns_query *q) { char buffer[512]; char *qname; qname = get_hostname (offset, buffer); q->qname = qname ? strdup (qname) : NULL; q->qtype = get_2 (offset); q->qclass = get_2 (offset);}static void get_rr (int *offset, struct dns_rr *rr) { char buffer[512]; char *name; int rdata,i; name = get_hostname (offset, buffer); rr->name = name ? strdup (name) : NULL; rr->type = get_2 (offset); rr->_class = get_2 (offset); rr->ttl = get_4 (offset); rr->rdlength = get_2 (offset); rr->rdata = (char *) malloc (rr->rdlength); rdata = offset ? *offset : -1; for (i = 0; i < rr->rdlength; i++) rr->rdata[i] = get_1 (offset); switch (rr->type) { case DNS_TYPE_A: rr->data.a.address = get_4 (&rdata); break; case DNS_TYPE_CNAME: rr->data.cname.cname = get_hostname (&rdata, buffer) ? strdup (buffer) : NULL; break; case DNS_TYPE_HINFO: rr->data.hinfo.cpu = get_char_string (&rdata, buffer) ? strdup (buffer) : NULL; rr->data.hinfo.os = get_char_string (&rdata, buffer) ? strdup (buffer) : NULL; break; case DNS_TYPE_MB: rr->data.mb.madname = get_hostname (&rdata, buffer) ? strdup (buffer) : NULL; break; case DNS_TYPE_MD: rr->data.md.madname = get_hostname (&rdata, buffer) ? strdup (buffer) : NULL; break; case DNS_TYPE_MF: rr->data.mf.madname = get_hostname (&rdata, buffer) ? strdup (buffer) : NULL; break; case DNS_TYPE_MG: rr->data.mg.mgmname = get_hostname (&rdata, buffer) ? strdup (buffer) : NULL; break; case DNS_TYPE_MINFO: rr->data.minfo.rmailbx = get_hostname (&rdata, buffer) ? strdup (buffer) : NULL; rr->data.minfo.emailbx = get_hostname (&rdata, buffer) ? strdup (buffer) : NULL; break; case DNS_TYPE_MR: rr->data.mr.newname = get_hostname (&rdata, buffer) ? strdup (buffer) : NULL; break; case DNS_TYPE_MX: rr->data.mx.preference = get_2 (&rdata); rr->data.mx.exchange = get_hostname (&rdata, buffer) ? strdup (buffer) : NULL; break; case DNS_TYPE_NULL: rr->data.null.data = (char *) malloc (rr->rdlength); memcpy (rr->data.null.data, rr->rdata, rr->rdlength); break; case DNS_TYPE_NS: rr->data.ns.nsdname = get_hostname (&rdata, buffer) ? strdup (buffer) : NULL; break; case DNS_TYPE_PTR: rr->data.ptr.ptrdname = get_hostname (&rdata, buffer) ? strdup (buffer) : NULL; break; case DNS_TYPE_SOA: rr->data.soa.mname = get_hostname (&rdata, buffer) ? strdup (buffer) : NULL; rr->data.soa.rname = get_hostname (&rdata, buffer) ? strdup (buffer) : NULL; rr->data.soa.serial = get_4 (&rdata); rr->data.soa.refresh = get_4 (&rdata); rr->data.soa.retry = get_4 (&rdata); rr->data.soa.expire = get_4 (&rdata); rr->data.soa.minimum = get_4 (&rdata); break; case DNS_TYPE_TXT: { int n = 1, m, start = rdata; while (get_char_string (&rdata, buffer)) n++; rr->data.txt.txt_data = (char **) malloc (sizeof (char *) * n); for (m = 0; m < n; m++) rr->data.txt.txt_data[m] = get_char_string (&start, buffer) ? strdup (buffer) : NULL; } break; case DNS_TYPE_WKS: rr->data.wks.address = get_4 (&rdata); rr->data.wks.protocol = get_1 (&rdata); rr->data.wks.bitmapsize = (*offset) - rdata; rr->data.wks.bitmap = (char *) malloc (rr->data.wks.bitmapsize); for (i = 0; i < rr->data.wks.bitmapsize; i++) rr->data.wks.bitmap[i] = get_1 (&rdata); break; }}static void put_packet (struct dns_packet *q) { int offset = 0, i; clear_datablock(); put_2 (&offset, q->id); put_2 (&offset, q->flags.i); put_2 (&offset, q->qdcount); put_2 (&offset, 0); /* q->ancount */ put_2 (&offset, 0); /* q->nscount */ put_2 (&offset, 0); /* q->arcount */ for (i = 0; i < q->qdcount; i++) put_query (&offset, q->questions + i);}static void get_packet (struct dns_packet *a) { int offset = 0, i; a->id = get_2 (&offset); a->flags.i = get_2 (&offset); a->qdcount = get_2 (&offset); a->ancount = get_2 (&offset); a->nscount = get_2 (&offset); a->arcount = get_2 (&offset); a->questions = a->qdcount ? (struct dns_query *) malloc (sizeof (struct dns_query) * a->qdcount) : NULL; a->answers = a->ancount ? (struct dns_rr *) malloc (sizeof (struct dns_rr) * a->ancount) : NULL; a->authorities = a->nscount ? (struct dns_rr *) malloc (sizeof (struct dns_rr) * a->nscount) : NULL; a->additionals = a->arcount ? (struct dns_rr *) malloc (sizeof (struct dns_rr) * a->arcount) : NULL; for (i = 0; i < a->qdcount; i++) get_query (&offset, a->questions + i); for (i = 0; i < a->ancount; i++) get_rr (&offset, a->answers + i); for (i = 0; i < a->nscount; i++) get_rr (&offset, a->authorities + i); for (i = 0; i < a->arcount; i++) get_rr (&offset, a->additionals + i);}static void free_query (struct dns_query *q) { free (q->qname);}static void free_rr (struct dns_rr *rr) { free (rr->name); free (rr->rdata); switch (rr->type) { case DNS_TYPE_CNAME: free (rr->data.cname.cname); break; case DNS_TYPE_HINFO: free (rr->data.hinfo.cpu); free (rr->data.hinfo.os); break; case DNS_TYPE_MB: free (rr->data.mb.madname); break; case DNS_TYPE_MD: free (rr->data.md.madname); break; case DNS_TYPE_MF: free (rr->data.mf.madname); break; case DNS_TYPE_MG: free (rr->data.mg.mgmname); break; case DNS_TYPE_MINFO: free (rr->data.minfo.rmailbx); free (rr->data.minfo.emailbx); break; case DNS_TYPE_MR: free (rr->data.mr.newname); break; case DNS_TYPE_MX: free (rr->data.mx.exchange); break; case DNS_TYPE_NULL: free (rr->data.null.data); break; case DNS_TYPE_NS: free (rr->data.ns.nsdname); break; case DNS_TYPE_PTR: free (rr->data.ptr.ptrdname); break; case DNS_TYPE_SOA: free (rr->data.soa.mname); free (rr->data.soa.rname); break; case DNS_TYPE_TXT: { char **chpp = rr->data.txt.txt_data; while (*chpp) { free (*chpp); chpp++; } free (rr->data.txt.txt_data); } break; case DNS_TYPE_WKS: free (rr->data.wks.bitmap); break; }}static void free_packet (struct dns_packet *p) { int i; for (i = 0; i < p->qdcount; i++) free_query (p->questions + i); for (i = 0; i < p->ancount; i++) free_rr (p->answers + i); for (i = 0; i < p->nscount; i++) free_rr (p->authorities + i); for (i = 0; i < p->arcount; i++) free_rr (p->additionals + i); free (p->questions); free (p->answers); free (p->authorities); free (p->additionals);}/* Now for the main resolver */static struct wait_list_t { struct wait_list_t *next, *prev; int nameserver; /* who was asked */ char *hostname; /* what was looked up */ int id; /* the packet's ID */ struct dns_packet *reply; /* the reply, when it arrives */} *waiting_list = NULL;static struct done_list_t { struct done_list_t *next; int nameserver; /* who was asked */ char *hostname; /* what was looked up */} *done_list = NULL;static SOCKET dns_socket = INVALID_SOCKET;static int dns_pkt_id = 0;static int create_lists (void) { waiting_list = (struct wait_list_t *) malloc (sizeof (struct wait_list_t)); if (!waiting_list) return 1; waiting_list->next = waiting_list->prev = NULL; waiting_list->nameserver = 0xdeadc0de; waiting_list->hostname = NULL; waiting_list->id = -1; waiting_list->reply = NULL; done_list = (struct done_list_t *) malloc (sizeof (struct done_list_t)); if (!done_list) { free (waiting_list); return 1; } done_list->next = NULL; done_list->nameserver = 0xdeadc0de; done_list->hostname = NULL; return 0;}static void destroy_lists (void) { struct wait_list_t *wptr; struct done_list_t *dptr; while (waiting_list) { wptr = waiting_list->next; free (waiting_list); waiting_list = wptr; } dptr = done_list; done_list = done_list->next; free (dptr); while (done_list) { dptr = done_list->next; free (done_list); done_list = dptr; }}static int create_socket(void) { int one = 1; dns_socket = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (dns_socket == INVALID_SOCKET) return 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -