getport.c revision 259065
1232950Stheraven/* $FreeBSD: releng/10.0/contrib/ipfilter/lib/getport.c 255332 2013-09-06 23:11:19Z cy $ */ 2232950Stheraven 3232950Stheraven/* 4232950Stheraven * Copyright (C) 2012 by Darren Reed. 5232950Stheraven * 6232950Stheraven * See the IPFILTER.LICENCE file for details on licencing. 7232950Stheraven * 8232950Stheraven * $Id$ 9232950Stheraven */ 10232950Stheraven 11232950Stheraven#include "ipf.h" 12232950Stheraven#include <ctype.h> 13232950Stheraven 14232950Stheravenint getport(fr, name, port, proto) 15232950Stheraven frentry_t *fr; 16232950Stheraven char *name, *proto; 17232950Stheraven u_short *port; 18232950Stheraven{ 19232950Stheraven struct protoent *p; 20232950Stheraven struct servent *s; 21232950Stheraven u_short p1; 22232950Stheraven 23232950Stheraven if (fr == NULL || fr->fr_type != FR_T_IPF) { 24232950Stheraven s = getservbyname(name, proto); 25232950Stheraven if (s != NULL) { 26232950Stheraven *port = s->s_port; 27227825Stheraven return 0; 28227825Stheraven } 29227825Stheraven 30227825Stheraven if (ISDIGIT(*name)) { 31227825Stheraven int portval = atoi(name); 32233235Stheraven if (portval < 0 || portval > 65535) 33233235Stheraven return -1; 34233235Stheraven *port = htons((u_short)portval); 35233235Stheraven return 0; 36227825Stheraven } 37233235Stheraven return -1; 38233235Stheraven } 39233235Stheraven 40233235Stheraven /* 41233235Stheraven * Some people will use port names in rules without specifying 42233235Stheraven * either TCP or UDP because it is implied by the group head. 43233235Stheraven * If we don't know the protocol, then the best we can do here is 44233235Stheraven * to take either only the TCP or UDP mapping (if one or the other 45233235Stheraven * is missing) or make sure both of them agree. 46233235Stheraven */ 47233235Stheraven if (fr->fr_proto == 0) { 48233235Stheraven s = getservbyname(name, "tcp"); 49233235Stheraven if (s != NULL) 50233235Stheraven p1 = s->s_port; 51233235Stheraven else 52233235Stheraven p1 = 0; 53233235Stheraven s = getservbyname(name, "udp"); 54233235Stheraven if (s != NULL) { 55233235Stheraven if (p1 != s->s_port) 56233235Stheraven return -1; 57233235Stheraven } 58233235Stheraven if ((p1 == 0) && (s == NULL)) 59233235Stheraven return -1; 60233235Stheraven if (p1) 61233235Stheraven *port = p1; 62233235Stheraven else 63233235Stheraven *port = s->s_port; 64233235Stheraven return 0; 65233235Stheraven } 66233235Stheraven 67233235Stheraven if ((fr->fr_flx & FI_TCPUDP) != 0) { 68233235Stheraven /* 69233235Stheraven * If a rule is "tcp/udp" then check that both TCP and UDP 70233235Stheraven * mappings for this protocol name match ports. 71233235Stheraven */ 72233235Stheraven s = getservbyname(name, "tcp"); 73233235Stheraven if (s == NULL) 74233235Stheraven return -1; 75233235Stheraven p1 = s->s_port; 76233235Stheraven s = getservbyname(name, "udp"); 77233235Stheraven if (s == NULL || s->s_port != p1) 78233235Stheraven return -1; 79233235Stheraven *port = p1; 80233235Stheraven return 0; 81233235Stheraven } 82233235Stheraven 83233235Stheraven p = getprotobynumber(fr->fr_proto); 84233235Stheraven s = getservbyname(name, p ? p->p_name : NULL); 85233235Stheraven if (s != NULL) { 86233235Stheraven *port = s->s_port; 87233235Stheraven return 0; 88233235Stheraven } 89233235Stheraven return -1; 90233235Stheraven} 91233235Stheraven