102 lines
2.8 KiB
C
102 lines
2.8 KiB
C
/*
|
|
* conversion from protocol/port string to protocol and port
|
|
* Copyright (C) 2002 Mario Strasser <mast@gmx.net>,
|
|
* Zuercher Hochschule Winterthur,
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by the
|
|
* Free Software Foundation; either version 2 of the License, or (at your
|
|
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* for more details.
|
|
*/
|
|
|
|
#include "internal.h"
|
|
#include "freeswan.h"
|
|
|
|
/*
|
|
* ttoprotoport - converts from protocol/port string to protocol and port
|
|
*/
|
|
err_t
|
|
ttoprotoport(src, src_len, proto, port, has_port_wildcard)
|
|
char *src; /* input string */
|
|
size_t src_len; /* length of input string, use strlen() if 0 */
|
|
u_int8_t *proto; /* extracted protocol number */
|
|
u_int16_t *port; /* extracted port number if it exists */
|
|
int *has_port_wildcard; /* set if port is %any */
|
|
{
|
|
char *end, *service_name;
|
|
char proto_name[16];
|
|
int proto_len;
|
|
long int l;
|
|
struct protoent *protocol;
|
|
struct servent *service;
|
|
|
|
/* get the length of the string */
|
|
if (!src_len) src_len = strlen(src);
|
|
|
|
/* locate delimiter '/' between protocol and port */
|
|
end = strchr(src, '/');
|
|
if (end != NULL) {
|
|
proto_len = end - src;
|
|
service_name = end + 1;
|
|
} else {
|
|
proto_len = src_len;
|
|
service_name = src + src_len;
|
|
}
|
|
|
|
/* copy protocol name*/
|
|
memset(proto_name, '\0', sizeof(proto_name));
|
|
memcpy(proto_name, src, proto_len);
|
|
|
|
/* extract protocol by trying to resolve it by name */
|
|
protocol = getprotobyname(proto_name);
|
|
if (protocol != NULL) {
|
|
*proto = protocol->p_proto;
|
|
}
|
|
else /* failed, now try it by number */
|
|
{
|
|
l = strtol(proto_name, &end, 0);
|
|
|
|
if (*proto_name && *end)
|
|
return "<protocol> is neither a number nor a valid name";
|
|
|
|
if (l < 0 || l > 0xff)
|
|
return "<protocol> must be between 0 and 255";
|
|
|
|
*proto = (u_int8_t)l;
|
|
}
|
|
|
|
/* is there a port wildcard? */
|
|
*has_port_wildcard = (strcmp(service_name, "%any") == 0);
|
|
|
|
if (*has_port_wildcard)
|
|
{
|
|
*port = 0;
|
|
return NULL;
|
|
}
|
|
|
|
/* extract port by trying to resolve it by name */
|
|
service = getservbyname(service_name, NULL);
|
|
if (service != NULL) {
|
|
*port = ntohs(service->s_port);
|
|
}
|
|
else /* failed, now try it by number */
|
|
{
|
|
l = strtol(service_name, &end, 0);
|
|
|
|
if (*service_name && *end)
|
|
return "<port> is neither a number nor a valid name";
|
|
|
|
if (l < 0 || l > 0xffff)
|
|
return "<port> must be between 0 and 65535";
|
|
|
|
*port = (u_int16_t)l;
|
|
}
|
|
return NULL;
|
|
}
|
|
|