Home | History | Annotate | Line # | Download | only in lib
      1 /*	$NetBSD: getport.c,v 1.2 2012/07/22 14:27:36 darrenr Exp $	*/
      2 
      3 /*
      4  * Copyright (C) 2012 by Darren Reed.
      5  *
      6  * See the IPFILTER.LICENCE file for details on licencing.
      7  *
      8  * Id: getport.c,v 1.1.1.2 2012/07/22 13:44:38 darrenr Exp $
      9  */
     10 
     11 #include "ipf.h"
     12 #include <ctype.h>
     13 
     14 int getport(fr, name, port, proto)
     15 	frentry_t *fr;
     16 	char *name, *proto;
     17 	u_short *port;
     18 {
     19 	struct protoent *p;
     20 	struct servent *s;
     21 	u_short p1;
     22 
     23 	if (fr == NULL || fr->fr_type != FR_T_IPF) {
     24 		s = getservbyname(name, proto);
     25 		if (s != NULL) {
     26 			*port = s->s_port;
     27 			return 0;
     28 		}
     29 
     30 		if (ISDIGIT(*name)) {
     31 			int portval = atoi(name);
     32 			if (portval < 0 || portval > 65535)
     33 				return -1;
     34 			*port = htons((u_short)portval);
     35 			return 0;
     36 		}
     37 		return -1;
     38 	}
     39 
     40 	/*
     41 	 * Some people will use port names in rules without specifying
     42 	 * either TCP or UDP because it is implied by the group head.
     43 	 * If we don't know the protocol, then the best we can do here is
     44 	 * to take either only the TCP or UDP mapping (if one or the other
     45 	 * is missing) or make sure both of them agree.
     46 	 */
     47 	if (fr->fr_proto == 0) {
     48 		s = getservbyname(name, "tcp");
     49 		if (s != NULL)
     50 			p1 = s->s_port;
     51 		else
     52 			p1 = 0;
     53 		s = getservbyname(name, "udp");
     54 		if (s != NULL) {
     55 			if (p1 != s->s_port)
     56 				return -1;
     57 		}
     58 		if ((p1 == 0) && (s == NULL))
     59 			return -1;
     60 		if (p1)
     61 			*port = p1;
     62 		else
     63 			*port = s->s_port;
     64 		return 0;
     65 	}
     66 
     67 	if ((fr->fr_flx & FI_TCPUDP) != 0) {
     68 		/*
     69 		 * If a rule is "tcp/udp" then check that both TCP and UDP
     70 		 * mappings for this protocol name match ports.
     71 		 */
     72 		s = getservbyname(name, "tcp");
     73 		if (s == NULL)
     74 			return -1;
     75 		p1 = s->s_port;
     76 		s = getservbyname(name, "udp");
     77 		if (s == NULL || s->s_port != p1)
     78 			return -1;
     79 		*port = p1;
     80 		return 0;
     81 	}
     82 
     83 	p = getprotobynumber(fr->fr_proto);
     84 	s = getservbyname(name, p ? p->p_name : NULL);
     85 	if (s != NULL) {
     86 		*port = s->s_port;
     87 		return 0;
     88 	}
     89 	return -1;
     90 }
     91