diff options
Diffstat (limited to 'libc/inet/resolv.c')
-rw-r--r-- | libc/inet/resolv.c | 552 |
1 files changed, 273 insertions, 279 deletions
diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c index 27daaf4d6..ae23064bb 100644 --- a/libc/inet/resolv.c +++ b/libc/inet/resolv.c @@ -31,10 +31,10 @@ #define DPRINTF(X,args...) printf(X,args...) #else #define DPRINTF(X,args...) -#endif /* DEBUG */ +#endif /* DEBUG */ #ifdef L_encodeh -int encode_header(struct resolv_header * h, unsigned char * dest, int maxlen) +int encode_header(struct resolv_header *h, unsigned char *dest, int maxlen) { if (maxlen < 12) return -1; @@ -42,12 +42,9 @@ int encode_header(struct resolv_header * h, unsigned char * dest, int maxlen) dest[0] = (h->id & 0xff00) >> 8; dest[1] = (h->id & 0x00ff) >> 0; dest[2] = (h->qr ? 0x80 : 0) | - ((h->opcode & 0x0f) << 3) | - (h->aa ? 0x04 : 0) | - (h->tc ? 0x02 : 0) | - (h->rd ? 0x01 : 0); - dest[3] = (h->ra ? 0x80 : 0) | - (h->rcode & 0x0f); + ((h->opcode & 0x0f) << 3) | + (h->aa ? 0x04 : 0) | (h->tc ? 0x02 : 0) | (h->rd ? 0x01 : 0); + dest[3] = (h->ra ? 0x80 : 0) | (h->rcode & 0x0f); dest[4] = (h->qdcount & 0xff00) >> 8; dest[5] = (h->qdcount & 0x00ff) >> 0; dest[6] = (h->ancount & 0xff00) >> 8; @@ -56,13 +53,13 @@ int encode_header(struct resolv_header * h, unsigned char * dest, int maxlen) dest[9] = (h->nscount & 0x00ff) >> 0; dest[10] = (h->arcount & 0xff00) >> 8; dest[11] = (h->arcount & 0x00ff) >> 0; - + return 12; } #endif #ifdef L_decodeh -int decode_header(unsigned char * data, struct resolv_header * h) +int decode_header(unsigned char *data, struct resolv_header *h) { h->id = (data[0] << 8) | data[1]; h->qr = (data[2] & 0x80) ? 1 : 0; @@ -76,7 +73,7 @@ int decode_header(unsigned char * data, struct resolv_header * h) h->ancount = (data[6] << 8) | data[7]; h->nscount = (data[8] << 8) | data[9]; h->arcount = (data[10] << 8) | data[11]; - + return 12; } #endif @@ -85,33 +82,33 @@ int decode_header(unsigned char * data, struct resolv_header * h) /* Encode a dotted string into nameserver transport-level encoding. This routine is fairly dumb, and doesn't attempt to compress the data */ - -int encode_dotted(const char * dotted, unsigned char * dest, int maxlen) + +int encode_dotted(const char *dotted, unsigned char *dest, int maxlen) { - int used=0; + int used = 0; - while(dotted && *dotted) { - char * c = strchr(dotted, '.'); + while (dotted && *dotted) { + char *c = strchr(dotted, '.'); int l = c ? c - dotted : strlen(dotted); - - if (l >= (maxlen-used-1)) + + if (l >= (maxlen - used - 1)) return -1; - + dest[used++] = l; - memcpy(dest+used, dotted, l); + memcpy(dest + used, dotted, l); used += l; - + if (c) - dotted = c+1; + dotted = c + 1; else break; } - + if (maxlen < 1) return -1; - + dest[used++] = 0; - + return used; } #endif @@ -120,19 +117,19 @@ int encode_dotted(const char * dotted, unsigned char * dest, int maxlen) /* Decode a dotted string from nameserver transport-level encoding. This routine understands compressed data. */ -int decode_dotted(const unsigned char * data, int offset, - char * dest, int maxlen) +int decode_dotted(const unsigned char *data, int offset, + char *dest, int maxlen) { int l; - int measure=1; + int measure = 1; int total = 0; - int used=0; - + int used = 0; + if (!data) return -1; - - while ((measure && total++), (l=data[offset++])) { - + + while ((measure && total++), (l = data[offset++])) { + if ((l & 0xc0) == (0xc0)) { if (measure) total++; @@ -141,80 +138,80 @@ int decode_dotted(const unsigned char * data, int offset, measure = 0; continue; } - - if ((used+l+1) >= maxlen) + + if ((used + l + 1) >= maxlen) return -1; - - memcpy(dest+used, data+offset, l); + + memcpy(dest + used, data + offset, l); offset += l; used += l; if (measure) total += l; - + if (data[offset] != 0) dest[used++] = '.'; else dest[used++] = '\0'; } - + DPRINTF("Total decode len = %d\n", total); - + return total; } #endif #ifdef L_lengthd -int length_dotted(const unsigned char * data, int offset) +int length_dotted(const unsigned char *data, int offset) { int orig_offset = offset; int l; - + if (!data) return -1; - - while ((l=data[offset++])) { - + + while ((l = data[offset++])) { + if ((l & 0xc0) == (0xc0)) { offset++; break; } - + offset += l; } - - return offset-orig_offset; + + return offset - orig_offset; } #endif #ifdef L_encodeq -int encode_question(struct resolv_question * q, - unsigned char * dest, int maxlen) +int encode_question(struct resolv_question *q, + unsigned char *dest, int maxlen) { int i; i = encode_dotted(q->dotted, dest, maxlen); if (i < 0) return i; - + dest += i; maxlen -= i; - + if (maxlen < 4) return -1; - + dest[0] = (q->qtype & 0xff00) >> 8; dest[1] = (q->qtype & 0x00ff) >> 0; dest[2] = (q->qclass & 0xff00) >> 8; dest[3] = (q->qclass & 0x00ff) >> 0; - - return i+4; + + return i + 4; } #endif #ifdef L_decodeq -int decode_question(unsigned char * message, int offset, - struct resolv_question * q) +int decode_question(unsigned char *message, int offset, + struct resolv_question *q) { char temp[256]; int i; @@ -222,46 +219,45 @@ int decode_question(unsigned char * message, int offset, i = decode_dotted(message, offset, temp, 256); if (i < 0) return i; - + offset += i; - + q->dotted = strdup(temp); - q->qtype = (message[offset+0] << 8) | message[offset+1]; - q->qclass = (message[offset+2] << 8) | message[offset+3]; - - return i+4; + q->qtype = (message[offset + 0] << 8) | message[offset + 1]; + q->qclass = (message[offset + 2] << 8) | message[offset + 3]; + + return i + 4; } #endif #ifdef L_lengthq -int length_question(unsigned char * message, int offset) +int length_question(unsigned char *message, int offset) { int i; i = length_dotted(message, offset); if (i < 0) return i; - - return i+4; + + return i + 4; } #endif #ifdef L_encodea -int encode_answer(struct resolv_answer * a, - unsigned char * dest, int maxlen) +int encode_answer(struct resolv_answer *a, unsigned char *dest, int maxlen) { int i; i = encode_dotted(a->dotted, dest, maxlen); if (i < 0) return i; - + dest += i; maxlen -= i; - - if (maxlen < (10+a->rdlength)) + + if (maxlen < (10 + a->rdlength)) return -1; - + *dest++ = (a->atype & 0xff00) >> 8; *dest++ = (a->atype & 0x00ff) >> 0; *dest++ = (a->aclass & 0xff00) >> 8; @@ -273,14 +269,14 @@ int encode_answer(struct resolv_answer * a, *dest++ = (a->rdlength & 0xff00) >> 8; *dest++ = (a->rdlength & 0x00ff) >> 0; memcpy(dest, a->rdata, a->rdlength); - - return i+10+a->rdlength; + + return i + 10 + a->rdlength; } #endif #ifdef L_decodea -int decode_answer(unsigned char * message, int offset, - struct resolv_answer * a) +int decode_answer(unsigned char *message, int offset, + struct resolv_answer *a) { char temp[256]; int i; @@ -288,47 +284,48 @@ int decode_answer(unsigned char * message, int offset, i = decode_dotted(message, offset, temp, 256); if (i < 0) return i; - - message += offset+i; - + + message += offset + i; + a->dotted = strdup(temp); - a->atype = (message[0] << 8) | message[1]; message += 2; - a->aclass = (message[0] << 8) | message[1]; message += 2; + a->atype = (message[0] << 8) | message[1]; + message += 2; + a->aclass = (message[0] << 8) | message[1]; + message += 2; a->ttl = (message[0] << 24) | - (message[1] << 16) | - (message[2] << 8) | - (message[3] << 0); + (message[1] << 16) | (message[2] << 8) | (message[3] << 0); message += 4; - a->rdlength = (message[0] << 8) | message[1]; message += 2; + a->rdlength = (message[0] << 8) | message[1]; + message += 2; a->rdata = message; - a->rdoffset = offset+i+10; - + a->rdoffset = offset + i + 10; + DPRINTF("i=%d,rdlength=%d\n", i, a->rdlength); - - return i+10+a->rdlength; + + return i + 10 + a->rdlength; } #endif #ifdef L_encodep -int encode_packet(struct resolv_header * h, - struct resolv_question ** q, - struct resolv_answer ** an, - struct resolv_answer ** ns, - struct resolv_answer ** ar, - unsigned char * dest, int maxlen) +int encode_packet(struct resolv_header *h, + struct resolv_question **q, + struct resolv_answer **an, + struct resolv_answer **ns, + struct resolv_answer **ar, + unsigned char *dest, int maxlen) { - int i, total=0; + int i, total = 0; int j; i = encode_header(h, dest, maxlen); if (i < 0) return i; - + dest += i; maxlen -= i; total += i; - - for(j=0;j<h->qdcount;j++) { + + for (j = 0; j < h->qdcount; j++) { i = encode_question(q[j], dest, maxlen); if (i < 0) return i; @@ -337,7 +334,7 @@ int encode_packet(struct resolv_header * h, total += i; } - for(j=0;j<h->ancount;j++) { + for (j = 0; j < h->ancount; j++) { i = encode_answer(an[j], dest, maxlen); if (i < 0) return i; @@ -345,7 +342,7 @@ int encode_packet(struct resolv_header * h, maxlen -= i; total += i; } - for(j=0;j<h->nscount;j++) { + for (j = 0; j < h->nscount; j++) { i = encode_answer(ns[j], dest, maxlen); if (i < 0) return i; @@ -353,7 +350,7 @@ int encode_packet(struct resolv_header * h, maxlen -= i; total += i; } - for(j=0;j<h->arcount;j++) { + for (j = 0; j < h->arcount; j++) { i = encode_answer(ar[j], dest, maxlen); if (i < 0) return i; @@ -361,57 +358,59 @@ int encode_packet(struct resolv_header * h, maxlen -= i; total += i; } - + return total; } #endif #ifdef L_decodep -int decode_packet(unsigned char * data, struct resolv_header * h) +int decode_packet(unsigned char *data, struct resolv_header *h) { return decode_header(data, h); } #endif #ifdef L_formquery -int form_query(int id, const char * name, int type, unsigned char * packet, int maxlen) +int form_query(int id, const char *name, int type, unsigned char *packet, + int maxlen) { struct resolv_header h; struct resolv_question q; - int i,j; - + int i, j; + memset(&h, 0, sizeof(h)); h.id = id; h.qdcount = 1; - - q.dotted = (char*)name; + + q.dotted = (char *) name; q.qtype = type; - q.qclass = 1 /*CLASS_IN*/; - + q.qclass = 1 /*CLASS_IN */ ; + i = encode_header(&h, packet, maxlen); if (i < 0) return i; - - j = encode_question(&q, packet+i, maxlen-i); + + j = encode_question(&q, packet + i, maxlen - i); if (j < 0) return j; - return i+j; + return i + j; } #endif #ifdef L_dnslookup int dns_caught_signal = 0; -void dns_catch_signal(int signo) { +void dns_catch_signal(int signo) +{ dns_caught_signal = 1; -} +} -int dns_lookup(const char * name, int type, int nscount, const char ** nsip, - unsigned char ** outpacket, struct resolv_answer * a) +int dns_lookup(const char *name, int type, int nscount, const char **nsip, + unsigned char **outpacket, struct resolv_answer *a) { - static int id=1; - int i,j,len; + static int id = 1; + int i, j, len; int fd; int pos; static int ns = 0; @@ -421,63 +420,63 @@ int dns_lookup(const char * name, int type, int nscount, const char ** nsip, struct resolv_header h; struct resolv_question q; int retries = 0; - unsigned char * packet = malloc(512); - + unsigned char *packet = malloc(512); + if (!packet) goto fail1; - + DPRINTF("Looking up type %d answer for '%s'\n", type, name); - + if (!nscount) goto fail1; - + ns %= nscount; - + fd = -1; - + while (retries++ < MAX_RETRIES) { - + if (fd != -1) close(fd); fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - - if (fd==-1) + + if (fd == -1) goto fail2; - - + + memset(packet, 0, 512); memset(&h, 0, sizeof(h)); h.id = ++id; h.qdcount = 1; h.rd = 1; - + DPRINTF("encoding header\n"); i = encode_header(&h, packet, 512); if (i < 0) goto fail3; - q.dotted = (char*)name; + q.dotted = (char *) name; q.qtype = type; - q.qclass = 1 /*CLASS_IN*/; - - j = encode_question(&q, packet+i, 512-i); + q.qclass = 1 /*CLASS_IN */ ; + + j = encode_question(&q, packet + i, 512 - i); if (j < 0) goto fail3; - - len = i+j; + + len = i + j; DPRINTF("On try %d, sending query to port %d of machine %s\n", - retries, DNS_SERVICE, nsip[ns]); + retries, DNS_SERVICE, nsip[ns]); sa.sin_family = AF_INET; sa.sin_port = htons(DNS_SERVICE); sa.sin_addr.s_addr = inet_addr(nsip[ns]); - if (connect(fd, (struct sockaddr*)&sa, sizeof(sa))==-1) { + if (connect(fd, (struct sockaddr *) &sa, sizeof(sa)) == -1) { if (errno == ENETUNREACH) { /* routing error, presume not transient */ goto tryall; @@ -485,57 +484,55 @@ int dns_lookup(const char * name, int type, int nscount, const char ** nsip, /* retry */ break; } - - DPRINTF("Transmitting packet of length %d, id=%d, qr=%d\n", - len, h.id, h.qr); + + DPRINTF("Transmitting packet of length %d, id=%d, qr=%d\n", + len, h.id, h.qr); send(fd, packet, len, 0); dns_caught_signal = 0; oldalarm = alarm(REPLY_TIMEOUT); oldhandler = signal(SIGALRM, dns_catch_signal); - + i = recv(fd, packet, 512, 0); - + alarm(0); signal(SIGALRM, oldhandler); alarm(oldalarm); - - DPRINTF("Timeout=%d, len=%d\n", - dns_caught_signal, i); - + + DPRINTF("Timeout=%d, len=%d\n", dns_caught_signal, i); + if (dns_caught_signal) /* timed out, so retry send and receive, to next nameserver on queue */ goto again; - + if (i < 12) /* too short ! */ goto again; - + decode_header(packet, &h); - - DPRINTF("id = %d, qr = %d\n", - h.id, h.qr); - + + DPRINTF("id = %d, qr = %d\n", h.id, h.qr); + if ((h.id != id) || (!h.qr)) /* unsolicited */ goto again; - + DPRINTF("Got response (i think)!\n"); DPRINTF("qrcount=%d,ancount=%d,nscount=%d,arcount=%d\n", - h.qdcount, h.ancount, h.nscount, h.arcount); + h.qdcount, h.ancount, h.nscount, h.arcount); DPRINTF("opcode=%d,aa=%d,tc=%d,rd=%d,ra=%d,rcode=%d\n", - h.opcode,h.aa,h.tc,h.rd,h.ra,h.rcode); - + h.opcode, h.aa, h.tc, h.rd, h.ra, h.rcode); + if ((h.rcode) || (h.ancount < 1)) { /* negative result, not present */ goto tryall; } - + pos = 12; - for(j=0;j<h.qdcount;j++) { + for (j = 0; j < h.qdcount; j++) { DPRINTF("Skipping question %d at %d\n", j, pos); i = length_question(packet, pos); DPRINTF("Length of question %d is %d\n", j, i); @@ -544,82 +541,81 @@ int dns_lookup(const char * name, int type, int nscount, const char ** nsip, pos += i; } DPRINTF("Decoding answer at pos %d\n", pos); - + i = decode_answer(packet, pos, a); - - if (i<0) { + + if (i < 0) { DPRINTF("failed decode %d\n", i); goto again; } - + DPRINTF("Answer name = |%s|\n", a->dotted); DPRINTF("Answer type = |%d|\n", a->atype); - + close(fd); - + if (outpacket) *outpacket = packet; else free(packet); - return (0); /* success! */ + return (0); /* success! */ - tryall: + tryall: /* if there are other nameservers, give them a go, otherwise return with error */ if (retries >= nscount) break; - again: + again: ns = (ns + 1) % nscount; continue; } - - -fail3: + + + fail3: close(fd); -fail2: + fail2: free(packet); -fail1: + fail1: return -1; } #endif #ifdef L_resolveaddress -int resolve_address(const char * address, - int nscount, const char ** nsip, - struct in_addr * in) +int resolve_address(const char *address, + int nscount, const char **nsip, struct in_addr *in) { - unsigned char * packet; + unsigned char *packet; struct resolv_answer a; char temp[256]; int i; - int nest=0; - + int nest = 0; + if (!address || !in) return -1; - + strcpy(temp, address); - - for(;;) { - + + for (;;) { + i = dns_lookup(temp, 1, nscount, nsip, &packet, &a); - - if (i<0) + + if (i < 0) return -1; - + free(a.dotted); - - if (a.atype == 5) { /* CNAME*/ + + if (a.atype == 5) { /* CNAME */ i = decode_dotted(packet, a.rdoffset, temp, 256); free(packet); - - if (i <0) + + if (i < 0) return -1; if (++nest > MAX_RECURSE) return -1; continue; - } else if (a.atype == 1) { /* ADDRESS */ + } else if (a.atype == 1) { /* ADDRESS */ free(packet); break; } else { @@ -627,57 +623,56 @@ int resolve_address(const char * address, return -1; } } - + if (in) memcpy(in, a.rdata, 4); - + return 0; } #endif #ifdef L_resolvemailbox -int resolve_mailbox(const char * address, - int nscount, const char ** nsip, - struct in_addr * in) +int resolve_mailbox(const char *address, + int nscount, const char **nsip, struct in_addr *in) { struct resolv_answer a; - unsigned char * packet; + unsigned char *packet; char temp[256]; - int nest=0; + int nest = 0; int i; - + if (!address || !in) return -1; - + /* look up mail exchange */ i = dns_lookup(address, 15, nscount, nsip, &packet, &a); - + strcpy(temp, address); - - if (i>=0) { - i = decode_dotted(packet, a.rdoffset+2, temp, 256); + + if (i >= 0) { + i = decode_dotted(packet, a.rdoffset + 2, temp, 256); free(packet); } - - for(;;) { - + + for (;;) { + i = dns_lookup(temp, 1, nscount, nsip, &packet, &a); - - if (i<0) + + if (i < 0) return -1; - + free(a.dotted); - - if (a.atype == 5) { /* CNAME*/ + + if (a.atype == 5) { /* CNAME */ i = decode_dotted(packet, a.rdoffset, temp, 256); free(packet); - if (i<0) + if (i < 0) return i; if (++nest > MAX_RECURSE) return -1; continue; - } else if (a.atype == 1) { /* ADDRESS */ + } else if (a.atype == 1) { /* ADDRESS */ free(packet); break; } else { @@ -688,7 +683,7 @@ int resolve_mailbox(const char * address, if (in) memcpy(in, a.rdata, 4); - + return 0; } #endif @@ -709,7 +704,7 @@ int open_nameservers() if ((fp = fopen("/etc/resolv.conf", "r"))) { if ((arg = cfgfind(fp, "nameserver"))) { - for (i=1; arg[i]; i++) { + for (i = 1; arg[i]; i++) { nameserver[nameservers++] = strdup(arg[i]); } } @@ -720,9 +715,10 @@ int open_nameservers() #endif #ifdef L_closenameservers -void close_nameservers(void) { +void close_nameservers(void) +{ - while(nameservers>0) + while (nameservers > 0) free(nameserver[--nameservers]); } #endif @@ -730,85 +726,85 @@ void close_nameservers(void) { #ifdef L_resolvename -const char * resolve_name(const char * name, int mailbox) +const char *resolve_name(const char *name, int mailbox) { struct in_addr in; int i; - + /* shortcut: is it a valid IP address to begin with? */ if (inet_aton(name, &in)) return name; - + open_nameservers(); - + DPRINTF("looking up '%s', mailbox=%d, nameservers=%d\n", - name, mailbox, nameservers); - + name, mailbox, nameservers); + if (mailbox) i = resolve_mailbox(name, nameservers, nameserver, &in); else i = resolve_address(name, nameservers, nameserver, &in); - - if (i<0) + + if (i < 0) return 0; - + DPRINTF("success = '%s'\n", inet_ntoa(in)); - + return inet_ntoa(in); } #endif #ifdef L_gethostbyname -struct hostent * gethostbyname(const char * name) +struct hostent *gethostbyname(const char *name) { static struct hostent h; static char namebuf[256]; static struct in_addr in; static struct in_addr *addr_list[2]; - unsigned char * packet; + unsigned char *packet; struct resolv_answer a; int i; - int nest=0; + int nest = 0; open_nameservers(); - + if (!name) return 0; - + memset(&h, 0, sizeof(h)); - + addr_list[0] = ∈ addr_list[1] = 0; - + strcpy(namebuf, name); - - for(;;) { - + + for (;;) { + i = dns_lookup(namebuf, 1, nameservers, nameserver, &packet, &a); - - if (i<0) + + if (i < 0) return 0; - + strcpy(namebuf, a.dotted); free(a.dotted); - - - if (a.atype == 5) { /* CNAME*/ + + + if (a.atype == 5) { /* CNAME */ i = decode_dotted(packet, a.rdoffset, namebuf, 256); free(packet); - - if (i <0) + + if (i < 0) return 0; if (++nest > MAX_RECURSE) return 0; continue; - } else if (a.atype == 1) { /* ADDRESS */ + } else if (a.atype == 1) { /* ADDRESS */ memcpy(&in, a.rdata, sizeof(in)); h.h_name = namebuf; h.h_addrtype = AF_INET; h.h_length = sizeof(in); - h.h_addr_list = (char**)addr_list; + h.h_addr_list = (char **) addr_list; free(packet); break; } else { @@ -816,77 +812,75 @@ struct hostent * gethostbyname(const char * name) return 0; } } - + return &h; } #endif #ifdef L_gethostbyaddr -struct hostent * gethostbyaddr(const char * addr, int len, int type) +struct hostent *gethostbyaddr(const char *addr, int len, int type) { static struct hostent h; static char namebuf[256]; static struct in_addr in; static struct in_addr *addr_list[2]; - unsigned char * packet; + unsigned char *packet; struct resolv_answer a; int i; - int nest=0; - + int nest = 0; + if (!addr || (len != sizeof(in)) || (type != AF_INET)) return 0; - + memcpy(&in.s_addr, addr, len); open_nameservers(); - + memset(&h, 0, sizeof(h)); - + addr_list[0] = ∈ addr_list[1] = 0; - + sprintf(namebuf, "%d.%d.%d.%d.in-addr.arpa", - (in.s_addr >> 24) & 0xff, - (in.s_addr >> 16) & 0xff, - (in.s_addr >> 8) & 0xff, - (in.s_addr >> 0) & 0xff - ); - - for(;;) { - + (in.s_addr >> 24) & 0xff, + (in.s_addr >> 16) & 0xff, + (in.s_addr >> 8) & 0xff, (in.s_addr >> 0) & 0xff); + + for (;;) { + i = dns_lookup(namebuf, 12, nameservers, nameserver, &packet, &a); - - if (i<0) + + if (i < 0) return 0; - + strcpy(namebuf, a.dotted); free(a.dotted); - - if (a.atype == 5) { /* CNAME*/ + + if (a.atype == 5) { /* CNAME */ i = decode_dotted(packet, a.rdoffset, namebuf, 256); free(packet); - - if (i <0) + + if (i < 0) return 0; if (++nest > MAX_RECURSE) return 0; continue; - } else if (a.atype == 12) { /* ADDRESS */ + } else if (a.atype == 12) { /* ADDRESS */ i = decode_dotted(packet, a.rdoffset, namebuf, 256); free(packet); - + h.h_name = namebuf; h.h_addrtype = AF_INET; h.h_length = sizeof(in); - h.h_addr_list = (char**)addr_list; + h.h_addr_list = (char **) addr_list; break; } else { free(packet); return 0; } } - + return &h; } #endif |