summaryrefslogtreecommitdiffstats
path: root/contrib/ipfilter/lib/portnum.c
blob: f80f86d42c939623512663ef80233026f50804dc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/*	$FreeBSD$	*/

/*
 * Copyright (C) 1993-2001 by Darren Reed.
 *
 * See the IPFILTER.LICENCE file for details on licencing.
 *
 *
 * $Id: portnum.c,v 1.6.4.1 2004/12/09 19:41:22 darrenr Exp $
 */

#include <ctype.h>

#include "ipf.h"


/*
 * find the port number given by the name, either from getservbyname() or
 * straight atoi(). Return 1 on success, 0 on failure
 */
int	portnum(name, proto, port, linenum)
char	*name, *proto;
u_short	*port;
int     linenum;
{
	struct	servent	*sp, *sp2;
	u_short	p1 = 0;
	int i;

	if (ISDIGIT(*name)) {
		if (ratoi(name, &i, 0, USHRT_MAX)) {
			*port = (u_short)i;
			return 1;
		}
		fprintf(stderr, "%d: unknown port \"%s\"\n", linenum, name);
		return 0;
	}
	if (proto != NULL && strcasecmp(proto, "tcp/udp") != 0) {
		sp = getservbyname(name, proto);
		if (sp) {
			*port = ntohs(sp->s_port);
			return 1;
		}
		fprintf(stderr, "%d: unknown service \"%s\".\n", linenum, name);
		return 0;
	}
	sp = getservbyname(name, "tcp");
	if (sp)
		p1 = sp->s_port;
	sp2 = getservbyname(name, "udp");
	if (!sp || !sp2) {
		fprintf(stderr, "%d: unknown tcp/udp service \"%s\".\n",
			linenum, name);
		return 0;
	}
	if (p1 != sp2->s_port) {
		fprintf(stderr, "%d: %s %d/tcp is a different port to ",
			linenum, name, p1);
		fprintf(stderr, "%d: %s %d/udp\n", linenum, name, sp->s_port);
		return 0;
	}
	*port = ntohs(p1);
	return 1;
}
OpenPOWER on IntegriCloud