2N/A/*
2N/A * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
2N/A * Portions Copyright (c) 1996,1998 by Internet Software Consortium.
2N/A *
2N/A * Permission to use, copy, modify, and distribute this software for any
2N/A * purpose with or without fee is hereby granted, provided that the above
2N/A * copyright notice and this permission notice appear in all copies.
2N/A *
2N/A * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
2N/A * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
2N/A * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
2N/A * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
2N/A * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
2N/A * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
2N/A * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
2N/A */
2N/A
2N/A#if defined(LIBC_SCCS) && !defined(lint)
2N/Astatic const char rcsid[] = "$Id: irp_nw.c,v 1.4 2006/03/09 23:57:56 marka Exp $";
2N/A#endif /* LIBC_SCCS and not lint */
2N/A
2N/A#if 0
2N/A
2N/A#endif
2N/A
2N/A/* Imports */
2N/A
2N/A#include "port_before.h"
2N/A
2N/A#include <syslog.h>
2N/A#include <sys/types.h>
2N/A#include <sys/socket.h>
2N/A
2N/A#include <netinet/in.h>
2N/A#include <arpa/inet.h>
2N/A#include <arpa/nameser.h>
2N/A
2N/A#include <errno.h>
2N/A#include <fcntl.h>
2N/A#include <resolv.h>
2N/A#include <stdio.h>
2N/A#include <stdlib.h>
2N/A#include <string.h>
2N/A#include <syslog.h>
2N/A
2N/A#include <irs.h>
2N/A#include <irp.h>
2N/A#include <isc/irpmarshall.h>
2N/A
2N/A#include <isc/memcluster.h>
2N/A#include <isc/misc.h>
2N/A
2N/A#include "irs_p.h"
2N/A#include "lcl_p.h"
2N/A#include "irp_p.h"
2N/A
2N/A#include "port_after.h"
2N/A
2N/A#define MAXALIASES 35
2N/A#define MAXADDRSIZE 4
2N/A
2N/Astruct pvt {
2N/A struct irp_p *girpdata;
2N/A int warned;
2N/A struct nwent net;
2N/A};
2N/A
2N/A/* Forward */
2N/A
2N/Astatic void nw_close(struct irs_nw *);
2N/Astatic struct nwent * nw_byname(struct irs_nw *, const char *, int);
2N/Astatic struct nwent * nw_byaddr(struct irs_nw *, void *, int, int);
2N/Astatic struct nwent * nw_next(struct irs_nw *);
2N/Astatic void nw_rewind(struct irs_nw *);
2N/Astatic void nw_minimize(struct irs_nw *);
2N/A
2N/Astatic void free_nw(struct nwent *nw);
2N/A
2N/A
2N/A/* Public */
2N/A
2N/A/*%
2N/A * struct irs_nw * irs_irp_nw(struct irs_acc *this)
2N/A *
2N/A */
2N/A
2N/Astruct irs_nw *
2N/Airs_irp_nw(struct irs_acc *this) {
2N/A struct irs_nw *nw;
2N/A struct pvt *pvt;
2N/A
2N/A if (!(pvt = memget(sizeof *pvt))) {
2N/A errno = ENOMEM;
2N/A return (NULL);
2N/A }
2N/A memset(pvt, 0, sizeof *pvt);
2N/A
2N/A if (!(nw = memget(sizeof *nw))) {
2N/A memput(pvt, sizeof *pvt);
2N/A errno = ENOMEM;
2N/A return (NULL);
2N/A }
2N/A memset(nw, 0x0, sizeof *nw);
2N/A pvt->girpdata = this->private;
2N/A
2N/A nw->private = pvt;
2N/A nw->close = nw_close;
2N/A nw->byname = nw_byname;
2N/A nw->byaddr = nw_byaddr;
2N/A nw->next = nw_next;
2N/A nw->rewind = nw_rewind;
2N/A nw->minimize = nw_minimize;
2N/A return (nw);
2N/A}
2N/A
2N/A/* Methods */
2N/A
2N/A/*%
2N/A * void nw_close(struct irs_nw *this)
2N/A *
2N/A */
2N/A
2N/Astatic void
2N/Anw_close(struct irs_nw *this) {
2N/A struct pvt *pvt = (struct pvt *)this->private;
2N/A
2N/A nw_minimize(this);
2N/A
2N/A free_nw(&pvt->net);
2N/A
2N/A memput(pvt, sizeof *pvt);
2N/A memput(this, sizeof *this);
2N/A}
2N/A
2N/A/*%
2N/A * struct nwent * nw_byaddr(struct irs_nw *this, void *net,
2N/A * int length, int type)
2N/A *
2N/A */
2N/A
2N/Astatic struct nwent *
2N/Anw_byaddr(struct irs_nw *this, void *net, int length, int type) {
2N/A struct pvt *pvt = (struct pvt *)this->private;
2N/A struct nwent *nw = &pvt->net;
2N/A char *body = NULL;
2N/A size_t bodylen;
2N/A int code;
2N/A char paddr[24]; /*%< bigenough for ip4 w/ cidr spec. */
2N/A char text[256];
2N/A
2N/A if (inet_net_ntop(type, net, length, paddr, sizeof paddr) == NULL) {
2N/A return (NULL);
2N/A }
2N/A
2N/A if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
2N/A return (NULL);
2N/A }
2N/A
2N/A if (irs_irp_send_command(pvt->girpdata, "getnetbyaddr %s %s",
2N/A paddr, ADDR_T_STR(type)) != 0)
2N/A return (NULL);
2N/A
2N/A if (irs_irp_get_full_response(pvt->girpdata, &code,
2N/A text, sizeof text,
2N/A &body, &bodylen) != 0) {
2N/A return (NULL);
2N/A }
2N/A
2N/A if (code == IRPD_GETNET_OK) {
2N/A free_nw(nw);
2N/A if (irp_unmarshall_nw(nw, body) != 0) {
2N/A nw = NULL;
2N/A }
2N/A } else {
2N/A nw = NULL;
2N/A }
2N/A
2N/A if (body != NULL) {
2N/A memput(body, bodylen);
2N/A }
2N/A
2N/A return (nw);
2N/A}
2N/A
2N/A/*%
2N/A * struct nwent * nw_byname(struct irs_nw *this, const char *name, int type)
2N/A *
2N/A */
2N/A
2N/Astatic struct nwent *
2N/Anw_byname(struct irs_nw *this, const char *name, int type) {
2N/A struct pvt *pvt = (struct pvt *)this->private;
2N/A struct nwent *nw = &pvt->net;
2N/A char *body = NULL;
2N/A size_t bodylen;
2N/A int code;
2N/A char text[256];
2N/A
2N/A if (nw->n_name != NULL &&
2N/A strcmp(name, nw->n_name) == 0 &&
2N/A nw->n_addrtype == type) {
2N/A return (nw);
2N/A }
2N/A
2N/A if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
2N/A return (NULL);
2N/A }
2N/A
2N/A if (irs_irp_send_command(pvt->girpdata, "getnetbyname %s", name) != 0)
2N/A return (NULL);
2N/A
2N/A if (irs_irp_get_full_response(pvt->girpdata, &code,
2N/A text, sizeof text,
2N/A &body, &bodylen) != 0) {
2N/A return (NULL);
2N/A }
2N/A
2N/A if (code == IRPD_GETNET_OK) {
2N/A free_nw(nw);
2N/A if (irp_unmarshall_nw(nw, body) != 0) {
2N/A nw = NULL;
2N/A }
2N/A } else {
2N/A nw = NULL;
2N/A }
2N/A
2N/A if (body != NULL) {
2N/A memput(body, bodylen);
2N/A }
2N/A
2N/A return (nw);
2N/A}
2N/A
2N/A/*%
2N/A * void nw_rewind(struct irs_nw *this)
2N/A *
2N/A */
2N/A
2N/Astatic void
2N/Anw_rewind(struct irs_nw *this) {
2N/A struct pvt *pvt = (struct pvt *)this->private;
2N/A char text[256];
2N/A int code;
2N/A
2N/A if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
2N/A return;
2N/A }
2N/A
2N/A if (irs_irp_send_command(pvt->girpdata, "setnetent") != 0) {
2N/A return;
2N/A }
2N/A
2N/A code = irs_irp_read_response(pvt->girpdata, text, sizeof text);
2N/A if (code != IRPD_GETNET_SETOK) {
2N/A if (irp_log_errors) {
2N/A syslog(LOG_WARNING, "setnetent failed: %s", text);
2N/A }
2N/A }
2N/A
2N/A return;
2N/A}
2N/A
2N/A/*%
2N/A * Prepares the cache if necessary and returns the first, or
2N/A * next item from it.
2N/A */
2N/A
2N/Astatic struct nwent *
2N/Anw_next(struct irs_nw *this) {
2N/A struct pvt *pvt = (struct pvt *)this->private;
2N/A struct nwent *nw = &pvt->net;
2N/A char *body;
2N/A size_t bodylen;
2N/A int code;
2N/A char text[256];
2N/A
2N/A if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
2N/A return (NULL);
2N/A }
2N/A
2N/A if (irs_irp_send_command(pvt->girpdata, "getnetent") != 0) {
2N/A return (NULL);
2N/A }
2N/A
2N/A if (irs_irp_get_full_response(pvt->girpdata, &code,
2N/A text, sizeof text,
2N/A &body, &bodylen) != 0) {
2N/A return (NULL);
2N/A }
2N/A
2N/A if (code == IRPD_GETNET_OK) {
2N/A free_nw(nw);
2N/A if (irp_unmarshall_nw(nw, body) != 0) {
2N/A nw = NULL;
2N/A }
2N/A } else {
2N/A nw = NULL;
2N/A }
2N/A
2N/A if (body != NULL)
2N/A memput(body, bodylen);
2N/A return (nw);
2N/A}
2N/A
2N/A/*%
2N/A * void nw_minimize(struct irs_nw *this)
2N/A *
2N/A */
2N/A
2N/Astatic void
2N/Anw_minimize(struct irs_nw *this) {
2N/A struct pvt *pvt = (struct pvt *)this->private;
2N/A
2N/A irs_irp_disconnect(pvt->girpdata);
2N/A}
2N/A
2N/A
2N/A
2N/A
2N/A/* private. */
2N/A
2N/A/*%
2N/A * deallocate all the memory irp_unmarshall_pw allocated.
2N/A *
2N/A */
2N/A
2N/Astatic void
2N/Afree_nw(struct nwent *nw) {
2N/A char **p;
2N/A
2N/A if (nw == NULL)
2N/A return;
2N/A
2N/A if (nw->n_name != NULL)
2N/A free(nw->n_name);
2N/A
2N/A if (nw->n_aliases != NULL) {
2N/A for (p = nw->n_aliases ; *p != NULL ; p++) {
2N/A free(*p);
2N/A }
2N/A free(nw->n_aliases);
2N/A }
2N/A
2N/A if (nw->n_addr != NULL)
2N/A free(nw->n_addr);
2N/A}
2N/A
2N/A/*! \file */