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