Codebase list filtergen / debian/0.12.6-1 resolver.c
debian/0.12.6-1

Tree @debian/0.12.6-1 (Download .tar.gz)

resolver.c @debian/0.12.6-1raw · history · blame

/* argument name resolver
 *
 * Copyright (c) 2004 Jamie Wilkinson <jaq@spacepants.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <stdio.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "resolver.h"
#include "ast.h"
#include "icmpent.h"

void resolve_option_specifier(struct option_specifier_s * n __attribute__((unused))) {
}

void resolve_icmptype_argument(struct icmptype_argument_s * n) {
    struct icmpent_s * i;

    if (n->icmptype) {
        if ((i = geticmpbyname(n->icmptype))) {
            free(n->icmptype);
              if (asprintf(&n->icmptype, "%s", i->i_type) < 0) {
	        n->icmptype = NULL;
	        fprintf(
	            stderr,
	            "error: asprintf allocation failed when converting icmptype %s\n",
	            i->i_type);
	      }
	} else {
	    /* check that the icmptype is a number if we can't resolve it */
	    //long m;
	    char * e;

	    strtol(n->icmptype, &e, 10);
	    if (*e) {
		fprintf(stderr, "warning: suspicious icmp type encountered: %s\n", n->icmptype);
	    }
        }        
    }
}

void resolve_icmptype_argument_list(struct icmptype_argument_list_s * n) {
    if (n->list) {
        resolve_icmptype_argument_list(n->list);
    }
    if (n->arg) {
        resolve_icmptype_argument(n->arg);
    }
}

void resolve_icmptype_specifier(struct icmptype_specifier_s * n) {
    if (n->list) {
	resolve_icmptype_argument_list(n->list);
    }
}

void resolve_port_argument(struct port_argument_s * n) {
    struct servent * s;

    if (n->port_min) {
	/* try to resolve the port name */
	if ((s = getservbyname(n->port_min, NULL))) {
	    free(n->port_min);
	      if (asprintf(&n->port_min, "%d", ntohs(s->s_port)) < 0) {
	        n->port_min = NULL;
        	fprintf(stderr,
	                "error: asprintf allocation failed when resolving port %d\n",
                	ntohs(s->s_port));
	      }
	} else {
	    /* check that the port is a number if we can't resolve it */
	    //long m;
	    char * e;

	    strtol(n->port_min, &e, 10);
	    if (*e) {
		fprintf(stderr, "warning: suspicious port name encountered: %s\n", n->port_min);
	    }
	}
    }
    if (n->port_max) {
	/* try to resolve the port name */
	if ((s = getservbyname(n->port_max, NULL))) {
	    free(n->port_max);
	      if (asprintf(&n->port_max, "%d", ntohs(s->s_port)) < 0) {
	        n->port_max = NULL;
	        fprintf(stderr,
	                "error: asprintf allocation failed when resolving port %d\n",
	                ntohs(s->s_port));
	      }
	} else {
	    /* check that the port is a number if we can't resolve it */
	    //long m;
	    char * e;

	    strtol(n->port_max, &e, 10);
	    if (*e) {
		fprintf(stderr, "warning: suspicious port name encountered: %s\n", n->port_max);
	    }
	}
    }
}

void resolve_port_argument_list(struct port_argument_list_s * n) {
    if (n->list) {
	resolve_port_argument_list(n->list);
    }
    if (n->arg) {
	resolve_port_argument(n->arg);
    }
}

void resolve_port_specifier(struct port_specifier_s * n) {
    if (n->list) {
	resolve_port_argument_list(n->list);
    }
}

void resolve_protocol_argument(struct protocol_argument_s * n) {
    struct protoent * p;

    if (n->proto) {
	if ((p = getprotobyname(n->proto))) {
	    free(n->proto);
	      if (asprintf(&n->proto, "%d", p->p_proto) < 0) {
	        n->proto = NULL;
        	fprintf(
	            stderr,
        	    "error: asprintf allocation failed when converting protocol %d\n",
	            p->p_proto);
	      }
	} else {
	    /* check that the proto is a number if we can't resolve it */
	    //long m;
	    char * e;

	    strtol(n->proto, &e, 10);
	    if (*e) {
		fprintf(stderr, "warning: suspicious protocol name encountered: %s\n", n->proto);
	    }
	}
    }
}

void resolve_protocol_argument_list(struct protocol_argument_list_s * n) {
    if (n->list) {
	resolve_protocol_argument_list(n->list);
    }
    if (n->arg) {
	resolve_protocol_argument(n->arg);
    }
}

void resolve_protocol_specifier(struct protocol_specifier_s * n) {
    if (n->list) {
	resolve_protocol_argument_list(n->list);
    }
}

void resolve_host_argument(struct host_argument_s * n __attribute__((unused))) {
}

void resolve_host_argument_list(struct host_argument_list_s * n) {
    struct addrinfo * a = NULL, * i;
    struct addrinfo hints;
    int r;
    struct host_argument_list_s * list = NULL;
    struct host_argument_s * host = NULL;

    if (n->list) {
        resolve_host_argument_list(n->list);
    }

    if (n->arg) {
        memset(&hints, 0, sizeof(struct addrinfo));
        /* any address family is good */
        hints.ai_family = PF_UNSPEC;
        /* return hostname, though we don't use it, for debugging */
        hints.ai_flags = AI_CANONNAME;
        /* limit so duplicate hosts aren't returned for each socktype */
        hints.ai_socktype = SOCK_STREAM;
    
        if (n->arg->host) {
            r = getaddrinfo(n->arg->host, NULL, &hints, &a);
            switch (r) {
              case 0:
                /* replace the hostname with the IP */
                free(n->arg->host);
		/* getnameinfo does no allocation. */
		n->arg->host = malloc(NI_MAXHOST + 1);
		if (getnameinfo(a->ai_addr, a->ai_addrlen, n->arg->host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST) == 0) {
		    /* if there's more, create some more hosts */
		    for (i = a->ai_next; i; i = i->ai_next) {
			list = malloc(sizeof(struct host_argument_list_s));
			host = malloc(sizeof(struct host_argument_s));
			host->host = malloc(NI_MAXHOST + 1);
			if (getnameinfo(i->ai_addr, i->ai_addrlen, host->host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST) == 0) {
			    if (n->arg->mask) {
				host->mask = strdup(n->arg->mask);
			    }

			    /* insert the new node */
			    list->arg = host;
			    list->list = n->list;
			    n->list = list;
			} else {
			    fprintf(stderr, "warning: %s\n", strerror(errno));
			}
		    }
		} else {
		    fprintf(stderr, "warning: %s\n", strerror(errno));
		}
                freeaddrinfo(a);
                break;
              default:
                fprintf(stderr, "warning: %s: %s\n", gai_strerror(r), n->arg->host);
                break;
            }
        }
    }
}

void resolve_host_specifier(struct host_specifier_s * n) {
    if (n->list) {
        resolve_host_argument_list(n->list);
    }
}

void resolve_target_specifier(struct target_specifier_s * n __attribute__((unused))) {
}

void resolve_direction_argument(struct direction_argument_s * n __attribute__((unused))) {
}

void resolve_direction_argument_list(struct direction_argument_list_s * n) {
    if (n->list) {
	resolve_direction_argument_list(n->list);
    }
    if (n->arg) {
	resolve_direction_argument(n->arg);
    }
}

void resolve_direction_specifier(struct direction_specifier_s * n) {
    if (n->list) {
	resolve_direction_argument_list(n->list);
    }
}

void resolve_specifier_list(struct specifier_list_s * n);

void resolve_subrule_list(struct subrule_list_s * n) {
    if (n->subrule_list) {
        resolve_subrule_list(n->subrule_list);
    }
    if (n->specifier_list) {
        resolve_specifier_list(n->specifier_list);
    }
}

void resolve_chaingroup_specifier(struct chaingroup_specifier_s * n) {
    if (n->list) {
        resolve_subrule_list(n->list);
    }
}

void resolve_compound_specifier(struct compound_specifier_s * n) {
    if (n->list) {
        resolve_subrule_list(n->list);
    }
}

void resolve_specifier(struct specifier_s * n) {
    if (n->compound) {
	resolve_compound_specifier(n->compound);
    } else if (n->direction) {
	resolve_direction_specifier(n->direction);
    } else if (n->target) {
	resolve_target_specifier(n->target);
    } else if (n->host) {
	resolve_host_specifier(n->host);
    } else if (n->port) {
	resolve_port_specifier(n->port);
    } else if (n->protocol) {
	resolve_protocol_specifier(n->protocol);
    } else if (n->icmptype) {
	resolve_icmptype_specifier(n->icmptype);
    } else if (n->option) {
	resolve_option_specifier(n->option);
    } else if (n->chaingroup) {
	resolve_chaingroup_specifier(n->chaingroup);
    }
}

void resolve_negated_specifier(struct negated_specifier_s * n) {
    if (n->spec) {
	resolve_specifier(n->spec);
    }
}

void resolve_specifier_list(struct specifier_list_s * n) {
    if (n->list) {
	resolve_specifier_list(n->list);
    }
    if (n->spec) {
	resolve_negated_specifier(n->spec);
    }
}

void resolve_rule(struct rule_s * n) {
    if (n->list) {
	resolve_specifier_list(n->list);
    }
}

void resolve_rule_list(struct rule_list_s * n) {
    if (n->list) {
	resolve_rule_list(n->list);
    }
    if (n->rule) {
	resolve_rule(n->rule);
    }
}

void resolve_ast(struct ast_s * n) {
    if (n->list) {
	resolve_rule_list(n->list);
    }
}

void resolve(struct ast_s * n) {
    if (n) {
	resolve_ast(n);
    }
}