getport.c revision 161357
155714Skris/*	$FreeBSD: head/contrib/ipfilter/lib/getport.c 161357 2006-08-16 12:23:02Z guido $	*/
259191Skris
355714Skris#include "ipf.h"
455714Skris
555714Skrisint getport(fr, name, port)
655714Skrisfrentry_t *fr;
755714Skrischar *name;
855714Skrisu_short *port;
9280297Sjkim{
1055714Skris	struct protoent *p;
1155714Skris	struct servent *s;
1255714Skris	u_short p1;
1355714Skris
1455714Skris	if (fr == NULL || fr->fr_type != FR_T_IPF) {
1555714Skris		s = getservbyname(name, NULL);
16280297Sjkim		if (s != NULL) {
1755714Skris			*port = s->s_port;
1855714Skris			return 0;
1955714Skris		}
2055714Skris		return -1;
2155714Skris	}
2255714Skris
23280297Sjkim	/*
2455714Skris	 * Some people will use port names in rules without specifying
2555714Skris	 * either TCP or UDP because it is implied by the group head.
2655714Skris	 * If we don't know the protocol, then the best we can do here is
2755714Skris	 * to take either only the TCP or UDP mapping (if one or the other
2855714Skris	 * is missing) or make sure both of them agree.
2955714Skris	 */
3055714Skris	if (fr->fr_proto == 0) {
3155714Skris		s = getservbyname(name, "tcp");
3255714Skris		if (s != NULL)
3355714Skris			p1 = s->s_port;
3455714Skris		else
3555714Skris			p1 = 0;
3655714Skris		s = getservbyname(name, "udp");
3755714Skris		if (s != NULL) {
38280297Sjkim			if (p1 != s->s_port)
3955714Skris				return -1;
4055714Skris		}
41280297Sjkim		if ((p1 == 0) && (s == NULL))
4255714Skris			return -1;
4355714Skris		if (p1)
4455714Skris			*port = p1;
4555714Skris		else
4655714Skris			*port = s->s_port;
4755714Skris		return 0;
4855714Skris	}
4955714Skris
5055714Skris	if ((fr->fr_flx & FI_TCPUDP) != 0) {
5155714Skris		/*
5255714Skris		 * If a rule is "tcp/udp" then check that both TCP and UDP
53280297Sjkim		 * mappings for this protocol name match ports.
5455714Skris		 */
5555714Skris		s = getservbyname(name, "tcp");
5655714Skris		if (s == NULL)
5755714Skris			return -1;
5855714Skris		p1 = s->s_port;
5955714Skris		s = getservbyname(name, "udp");
60160814Ssimon		if (s == NULL || s->s_port != p1)
61280297Sjkim			return -1;
62280297Sjkim		*port = p1;
63280297Sjkim		return 0;
64280297Sjkim	}
65160814Ssimon
66280297Sjkim	p = getprotobynumber(fr->fr_proto);
67160814Ssimon	s = getservbyname(name, p ? p->p_name : NULL);
68160814Ssimon	if (s != NULL) {
69109998Smarkm		*port = s->s_port;
70280297Sjkim		return 0;
71280297Sjkim	}
72280297Sjkim	return -1;
73280297Sjkim}
74280297Sjkim