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