X-Git-Url: https://git.saurik.com/apple/libinfo.git/blobdiff_plain/e6b95798e71dad1fb3669ea0b8963d24ddd65f93..b3dd680f589a1f02e301659e04768ef61be3b843:/lookup.subproj/lu_network.c diff --git a/lookup.subproj/lu_network.c b/lookup.subproj/lu_network.c index 8f9a551..4f74394 100644 --- a/lookup.subproj/lu_network.c +++ b/lookup.subproj/lu_network.c @@ -29,16 +29,11 @@ #include #include #include -#include -#include #include #include #include #include #include - -#include "_lu_types.h" -#include "lookup.h" #include "lu_utils.h" static pthread_mutex_t _network_lock = PTHREAD_MUTEX_INITIALIZER; @@ -55,409 +50,146 @@ extern struct netent *_old_getnetent(); extern void _old_setnetent(); extern void _old_endnetent(); -extern mach_port_t _lu_port; -extern int _lu_running(void); +#define ENTRY_SIZE sizeof(struct netent) +#define ENTRY_KEY _li_data_key_network -static void -free_network_data(struct netent *n) +static struct netent * +copy_network(struct netent *in) { - char **aliases; - - if (n == NULL) return; - - free(n->n_name); - - aliases = n->n_aliases; - if (aliases != NULL) - { - while (*aliases != NULL) free(*aliases++); - free(n->n_aliases); - } -} + if (in == NULL) return NULL; -static void -free_network(struct netent *n) -{ - if (n == NULL) return; - free_network_data(n); - free(n); + return (struct netent *)LI_ils_create("s*44", in->n_name, in->n_aliases, in->n_addrtype, in->n_net); } -static void -free_lu_thread_info_network(void *x) +/* + * Extract the next network entry from a kvarray. + */ +static void * +extract_network(kvarray_t *in) { - struct lu_thread_info *tdata; - - if (x == NULL) return; + struct netent tmp; + uint32_t d, k, kcount; + char *empty[1]; - tdata = (struct lu_thread_info *)x; - - if (tdata->lu_entry != NULL) - { - free_network((struct netent *)tdata->lu_entry); - tdata->lu_entry = NULL; - } - - _lu_data_free_vm_xdr(tdata); - - free(tdata); -} + if (in == NULL) return NULL; -static struct netent * -extract_network(XDR *xdr) -{ - struct netent *n; - int i, j, nvals, nkeys, status; - char *key, **vals; + d = in->curr; + in->curr++; - if (xdr == NULL) return NULL; + if (d >= in->count) return NULL; - if (!xdr_int(xdr, &nkeys)) return NULL; + empty[0] = NULL; + memset(&tmp, 0, ENTRY_SIZE); - n = (struct netent *)calloc(1, sizeof(struct netent)); + tmp.n_addrtype = AF_INET; - n->n_addrtype = AF_INET; + kcount = in->dict[d].kcount; - for (i = 0; i < nkeys; i++) + for (k = 0; k < kcount; k++) { - key = NULL; - vals = NULL; - nvals = 0; - - status = _lu_xdr_attribute(xdr, &key, &vals, &nvals); - if (status < 0) + if (!strcmp(in->dict[d].key[k], "n_name")) { - free_network(n); - return NULL; - } + if (tmp.n_name != NULL) continue; + if (in->dict[d].vcount[k] == 0) continue; - if (nvals == 0) - { - free(key); - continue; + tmp.n_name = (char *)in->dict[d].val[k][0]; } - - j = 0; - - if ((n->n_name == NULL) && (!strcmp("name", key))) + else if (!strcmp(in->dict[d].key[k], "n_net")) { - n->n_name = vals[0]; - if (nvals > 1) - { - n->n_aliases = (char **)calloc(nvals, sizeof(char *)); - for (j = 1; j < nvals; j++) n->n_aliases[j-1] = vals[j]; - } - j = nvals; + if (in->dict[d].vcount[k] == 0) continue; + tmp.n_net = inet_network(in->dict[d].val[k][0]); } - else if (!strcmp("address", key)) + else if (!strcmp(in->dict[d].key[k], "n_addrtype")) { - n->n_net = inet_network(vals[0]); + if (in->dict[d].vcount[k] == 0) continue; + tmp.n_addrtype = atoi(in->dict[d].val[k][0]); } - - free(key); - if (vals != NULL) + else if (!strcmp(in->dict[d].key[k], "n_aliases")) { - for (; j < nvals; j++) free(vals[j]); - free(vals); - } - } - - if (n->n_name == NULL) n->n_name = strdup(""); - if (n->n_aliases == NULL) n->n_aliases = (char **)calloc(1, sizeof(char *)); + if (tmp.n_aliases != NULL) continue; + if (in->dict[d].vcount[k] == 0) continue; - return n; -} - -static struct netent * -copy_network(struct netent *in) -{ - int i, len; - struct netent *n; - - if (in == NULL) return NULL; - - n = (struct netent *)calloc(1, sizeof(struct netent)); - - n->n_name = LU_COPY_STRING(in->n_name); - - len = 0; - if (in->n_aliases != NULL) - { - for (len = 0; in->n_aliases[len] != NULL; len++); - } - - n->n_aliases = (char **)calloc(len + 1, sizeof(char *)); - for (i = 0; i < len; i++) - { - n->n_aliases[i] = strdup(in->n_aliases[i]); - } - - n->n_addrtype = in->n_addrtype; - n->n_net = in->n_net; - - return n; -} - -static void -recycle_network(struct lu_thread_info *tdata, struct netent *in) -{ - struct netent *n; - - if (tdata == NULL) return; - n = (struct netent *)tdata->lu_entry; - - if (in == NULL) - { - free_network(n); - tdata->lu_entry = NULL; - } - - if (tdata->lu_entry == NULL) - { - tdata->lu_entry = in; - return; + tmp.n_aliases = (char **)in->dict[d].val[k]; + } } - free_network_data(n); + if (tmp.n_name == NULL) tmp.n_name = ""; + if (tmp.n_aliases == NULL) tmp.n_aliases = empty; - n->n_name = in->n_name; - n->n_aliases = in->n_aliases; - n->n_addrtype = in->n_addrtype; - n->n_net = in->n_net; - - free(in); + return copy_network(&tmp); } static struct netent * -lu_getnetbyaddr(long addr, int type) +ds_getnetbyaddr(uint32_t addr, int type) { - struct netent *n; - unsigned datalen; - XDR inxdr; static int proc = -1; - char *lookup_buf; - int count; + unsigned char f1, f2, f3; + char val[64]; if (type != AF_INET) return NULL; - if (proc < 0) - { - if (_lookup_link(_lu_port, "getnetbyaddr", &proc) != KERN_SUCCESS) - { - return NULL; - } - } - - addr = htonl(addr); - datalen = 0; - lookup_buf = NULL; - - if (_lookup_all(_lu_port, proc, (unit *)&addr, 1, &lookup_buf, &datalen) != KERN_SUCCESS) - { - return NULL; - } - - datalen *= BYTES_PER_XDR_UNIT; - if ((lookup_buf == NULL) || (datalen == 0)) return NULL; - - xdrmem_create(&inxdr, lookup_buf, datalen, XDR_DECODE); - - count = 0; - if (!xdr_int(&inxdr, &count)) - { - xdr_destroy(&inxdr); - vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen); - return NULL; - } - - if (count == 0) - { - xdr_destroy(&inxdr); - vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen); - return NULL; - } + f1 = addr & 0xff; + addr >>= 8; + f2 = addr & 0xff; + addr >>= 8; + f3 = addr & 0xff; - n = extract_network(&inxdr); - xdr_destroy(&inxdr); - vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen); + if (f3 != 0) snprintf(val, sizeof(val), "%u.%u.%u", f3, f2, f1); + else if (f2 != 0) snprintf(val, sizeof(val), "%u.%u", f2, f1); + else snprintf(val, sizeof(val), "%u", f1); - return n; + return (struct netent *)LI_getone("getnetbyaddr", &proc, extract_network, "net", val); } static struct netent * -lu_getnetbyname(const char *name) +ds_getnetbyname(const char *name) { - struct netent *n; - unsigned datalen; - char namebuf[_LU_MAXLUSTRLEN + BYTES_PER_XDR_UNIT]; - XDR outxdr; - XDR inxdr; static int proc = -1; - char *lookup_buf; - int count; - - if (proc < 0) - { - if (_lookup_link(_lu_port, "getnetbyname", &proc) != KERN_SUCCESS) - { - return NULL; - } - } - - xdrmem_create(&outxdr, namebuf, sizeof(namebuf), XDR_ENCODE); - if (!xdr__lu_string(&outxdr, (_lu_string *)&name)) - { - xdr_destroy(&outxdr); - return NULL; - } - - datalen = 0; - lookup_buf = NULL; - - if (_lookup_all(_lu_port, proc, (unit *)namebuf, - xdr_getpos(&outxdr) / BYTES_PER_XDR_UNIT, &lookup_buf, &datalen) - != KERN_SUCCESS) - { - xdr_destroy(&outxdr); - return NULL; - } - - xdr_destroy(&outxdr); - - datalen *= BYTES_PER_XDR_UNIT; - if ((lookup_buf == NULL) || (datalen == 0)) return NULL; - - xdrmem_create(&inxdr, lookup_buf, datalen, XDR_DECODE); - - count = 0; - if (!xdr_int(&inxdr, &count)) - { - xdr_destroy(&inxdr); - vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen); - return NULL; - } - - if (count == 0) - { - xdr_destroy(&inxdr); - vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen); - return NULL; - } - n = extract_network(&inxdr); - xdr_destroy(&inxdr); - vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen); - - return n; + return (struct netent *)LI_getone("getnetbyname", &proc, extract_network, "name", name); } static void -lu_endnetent() +ds_endnetent() { - struct lu_thread_info *tdata; - - tdata = _lu_data_create_key(_lu_data_key_network, free_lu_thread_info_network); - _lu_data_free_vm_xdr(tdata); + LI_data_free_kvarray(LI_data_find_key(ENTRY_KEY)); } static void -lu_setnetent() +ds_setnetent() { - lu_endnetent(); + ds_endnetent(); } static struct netent * -lu_getnetent() +ds_getnetent() { static int proc = -1; - struct lu_thread_info *tdata; - struct netent *n; - - tdata = _lu_data_create_key(_lu_data_key_network, free_lu_thread_info_network); - if (tdata == NULL) - { - tdata = (struct lu_thread_info *)calloc(1, sizeof(struct lu_thread_info)); - _lu_data_set_key(_lu_data_key_network, tdata); - } - - if (tdata->lu_vm == NULL) - { - if (proc < 0) - { - if (_lookup_link(_lu_port, "getnetent", &proc) != KERN_SUCCESS) - { - lu_endnetent(); - return NULL; - } - } - - if (_lookup_all(_lu_port, proc, NULL, 0, &(tdata->lu_vm), &(tdata->lu_vm_length)) != KERN_SUCCESS) - { - lu_endnetent(); - return NULL; - } - - /* mig stubs measure size in words (4 bytes) */ - tdata->lu_vm_length *= 4; - - if (tdata->lu_xdr != NULL) - { - xdr_destroy(tdata->lu_xdr); - free(tdata->lu_xdr); - } - tdata->lu_xdr = (XDR *)calloc(1, sizeof(XDR)); - - xdrmem_create(tdata->lu_xdr, tdata->lu_vm, tdata->lu_vm_length, XDR_DECODE); - if (!xdr_int(tdata->lu_xdr, &tdata->lu_vm_cursor)) - { - lu_endnetent(); - return NULL; - } - } - - if (tdata->lu_vm_cursor == 0) - { - lu_endnetent(); - return NULL; - } - - n = extract_network(tdata->lu_xdr); - if (n == NULL) - { - lu_endnetent(); - return NULL; - } - tdata->lu_vm_cursor--; - - return n; + return (struct netent *)LI_getent("getnetent", &proc, extract_network, ENTRY_KEY, ENTRY_SIZE); } static struct netent * -getnet(const char *name, long addr, int type, int source) +getnet(const char *name, uint32_t addr, int type, int source) { struct netent *res = NULL; - struct lu_thread_info *tdata; + struct li_thread_info *tdata; - tdata = _lu_data_create_key(_lu_data_key_network, free_lu_thread_info_network); - if (tdata == NULL) - { - tdata = (struct lu_thread_info *)calloc(1, sizeof(struct lu_thread_info)); - _lu_data_set_key(_lu_data_key_network, tdata); - } + tdata = LI_data_create_key(ENTRY_KEY, ENTRY_SIZE); + if (tdata == NULL) return NULL; - if (_lu_running()) + if (_ds_running()) { switch (source) { case N_GET_NAME: - res = lu_getnetbyname(name); + res = ds_getnetbyname(name); break; case N_GET_ADDR: - res = lu_getnetbyaddr(addr, type); + res = ds_getnetbyaddr(addr, type); break; case N_GET_ENT: - res = lu_getnetent(); + res = ds_getnetent(); break; default: res = NULL; } @@ -465,6 +197,7 @@ getnet(const char *name, long addr, int type, int source) else { pthread_mutex_lock(&_network_lock); + switch (source) { case N_GET_NAME: @@ -478,11 +211,12 @@ getnet(const char *name, long addr, int type, int source) break; default: res = NULL; } + pthread_mutex_unlock(&_network_lock); } - recycle_network(tdata, res); - return (struct netent *)tdata->lu_entry; + LI_data_recycle(tdata, res, ENTRY_SIZE); + return (struct netent *)tdata->li_entry; } struct netent * @@ -506,13 +240,13 @@ getnetent(void) void setnetent(int stayopen) { - if (_lu_running()) lu_setnetent(); + if (_ds_running()) ds_setnetent(); else _old_setnetent(stayopen); } void endnetent(void) { - if (_lu_running()) lu_endnetent(); + if (_ds_running()) ds_endnetent(); else _old_endnetent(); }