Add Cisco Skinny Station protocol support to libalias, natd, and ppp.
Skinny is the protocol used by Cisco IP phones to talk to Cisco Call Managers. With this code, one can use a Cisco IP phone behind a FreeBSD NAT gateway. Currently, having the Call Manager behind the NAT gateway is not supported. More information on enabling Skinny support in libalias, natd, and ppp can be found in those applications' manpages. PR: 55843 Reviewed by: ru Approved by: ru MFC after: 30 days
This commit is contained in:
parent
1adbd0035e
commit
e19a1e64d2
@ -5,7 +5,7 @@ SHLIBDIR?= /lib
|
||||
SHLIB_MAJOR= 4
|
||||
MAN= libalias.3
|
||||
SRCS= alias.c alias_cuseeme.c alias_db.c alias_ftp.c alias_irc.c \
|
||||
alias_nbt.c alias_pptp.c alias_proxy.c alias_smedia.c \
|
||||
alias_nbt.c alias_pptp.c alias_proxy.c alias_skinny.c alias_smedia.c \
|
||||
alias_util.c
|
||||
INCS= alias.h
|
||||
|
||||
|
@ -917,6 +917,9 @@ TcpAliasIn(struct ip *pip)
|
||||
if (ntohs(tc->th_dport) == PPTP_CONTROL_PORT_NUMBER
|
||||
|| ntohs(tc->th_sport) == PPTP_CONTROL_PORT_NUMBER)
|
||||
AliasHandlePptpIn(pip, link);
|
||||
else if (skinnyPort != 0 && (ntohs(tc->th_dport) == skinnyPort
|
||||
|| ntohs(tc->th_sport) == skinnyPort))
|
||||
AliasHandleSkinny(pip, link);
|
||||
|
||||
alias_address = GetAliasAddress(link);
|
||||
original_address = GetOriginalAddress(link);
|
||||
@ -1098,6 +1101,9 @@ TcpAliasOut(struct ip *pip, int maxpacketsize)
|
||||
else if (ntohs(tc->th_dport) == PPTP_CONTROL_PORT_NUMBER
|
||||
|| ntohs(tc->th_sport) == PPTP_CONTROL_PORT_NUMBER)
|
||||
AliasHandlePptpOut(pip, link);
|
||||
else if (skinnyPort != 0 && (ntohs(tc->th_sport) == skinnyPort
|
||||
|| ntohs(tc->th_dport) == skinnyPort))
|
||||
AliasHandleSkinny(pip, link);
|
||||
|
||||
/* Adjust TCP checksum since source port is being aliased */
|
||||
/* and source address is being altered */
|
||||
|
@ -45,6 +45,7 @@
|
||||
void PacketAliasInit(void);
|
||||
void PacketAliasSetAddress(struct in_addr _addr);
|
||||
void PacketAliasSetFWBase(unsigned int _base, unsigned int _num);
|
||||
void PacketAliasSetSkinnyPort(unsigned int _port);
|
||||
unsigned int
|
||||
PacketAliasSetMode(unsigned int _flags, unsigned int _mask);
|
||||
void PacketAliasUninit(void);
|
||||
|
@ -398,6 +398,9 @@ static int fireWallFD = -1; /* File descriptor to be able to */
|
||||
/* flag. */
|
||||
#endif
|
||||
|
||||
unsigned int skinnyPort = 0; /* TCP port used by the Skinny */
|
||||
/* protocol. */
|
||||
|
||||
|
||||
|
||||
|
||||
@ -2948,3 +2951,8 @@ PacketAliasSetFWBase(unsigned int base, unsigned int num) {
|
||||
fireWallNumNums = num;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
PacketAliasSetSkinnyPort(unsigned int port) {
|
||||
skinnyPort = port;
|
||||
}
|
||||
|
@ -74,6 +74,7 @@
|
||||
/* Globals */
|
||||
|
||||
extern int packetAliasMode;
|
||||
extern unsigned int skinnyPort;
|
||||
|
||||
/* Prototypes */
|
||||
|
||||
@ -212,6 +213,9 @@ int AliasHandleUdpNbtNS(struct ip *_pip, struct alias_link *_link,
|
||||
void AliasHandleCUSeeMeOut(struct ip *_pip, struct alias_link *_link);
|
||||
void AliasHandleCUSeeMeIn(struct ip *_pip, struct in_addr _original_addr);
|
||||
|
||||
/* Skinny routines */
|
||||
void AliasHandleSkinny(struct ip *_pip, struct alias_link *_link);
|
||||
|
||||
/* Transparent proxy routines */
|
||||
int ProxyCheck(struct ip *_pip, struct in_addr *_proxy_server_addr,
|
||||
u_short *_proxy_server_port);
|
||||
|
@ -265,6 +265,16 @@ Set firewall range allocated for punching firewall holes (with the
|
||||
flag).
|
||||
The range will be cleared for all rules on initialization.
|
||||
.Ed
|
||||
.Pp
|
||||
.Ft void
|
||||
.Fn PacketAliasSkinnyPort "unsigned int port"
|
||||
.Bd -ragged -offset indent
|
||||
Set the TCP port used by the Skinny Station protocol.
|
||||
Skinny is used by Cisco IP phones to communicate with
|
||||
Cisco Call Managers to set up voice over IP calls.
|
||||
If this is not set, Skinny aliasing will not be done.
|
||||
The typical port used by Skinny is 2000.
|
||||
.Ed
|
||||
.Sh PACKET HANDLING
|
||||
The packet handling functions are used to modify incoming (remote to local)
|
||||
and outgoing (local to remote) packets.
|
||||
|
@ -31,6 +31,7 @@
|
||||
.Op Fl log_denied
|
||||
.Op Fl log_facility Ar facility_name
|
||||
.Op Fl punch_fw Ar firewall_range
|
||||
.Op Fl skinny_port Ar port
|
||||
.Op Fl log_ipfw_denied
|
||||
.Op Fl pid_file | P Ar pidfile
|
||||
.Ek
|
||||
@ -483,6 +484,13 @@ rules starting from the rule number
|
||||
.Ar basenumber
|
||||
will be used for punching firewall holes.
|
||||
The range will be cleared for all rules on startup.
|
||||
.It Fl skinny_port Ar port
|
||||
This option allows you to specify the TCP port used for
|
||||
the Skinny Station protocol.
|
||||
Skinny is used by Cisco IP phones to communicate with
|
||||
Cisco Call Managers to set up voice over IP calls.
|
||||
By default, Skinny aliasing is not performed.
|
||||
The typical port value for Skinny is 2000.
|
||||
.It Fl log_ipfw_denied
|
||||
Log when a packet cannot be re-injected because an
|
||||
.Xr ipfw 8
|
||||
|
@ -99,6 +99,7 @@ static int StrToProto (const char* str);
|
||||
static int StrToAddrAndPortRange (const char* str, struct in_addr* addr, char* proto, port_range *portRange);
|
||||
static void ParseArgs (int argc, char** argv);
|
||||
static void SetupPunchFW(const char *strValue);
|
||||
static void SetupSkinnyPort(const char *strValue);
|
||||
|
||||
/*
|
||||
* Globals.
|
||||
@ -838,6 +839,7 @@ enum Option {
|
||||
LogDenied,
|
||||
LogFacility,
|
||||
PunchFW,
|
||||
SkinnyPort,
|
||||
LogIpfwDenied,
|
||||
PidFile
|
||||
};
|
||||
@ -1059,6 +1061,14 @@ static struct OptionInfo optionTable[] = {
|
||||
"punch_fw",
|
||||
NULL },
|
||||
|
||||
{ SkinnyPort,
|
||||
0,
|
||||
String,
|
||||
"port",
|
||||
"set the TCP port for use with the Skinny Station protocol",
|
||||
"skinny_port",
|
||||
NULL },
|
||||
|
||||
{ LogIpfwDenied,
|
||||
0,
|
||||
YesNo,
|
||||
@ -1258,6 +1268,10 @@ static void ParseOption (const char* option, const char* parms)
|
||||
SetupPunchFW(strValue);
|
||||
break;
|
||||
|
||||
case SkinnyPort:
|
||||
SetupSkinnyPort(strValue);
|
||||
break;
|
||||
|
||||
case LogIpfwDenied:
|
||||
logIpfwDenied = yesNoValue;;
|
||||
break;
|
||||
@ -1705,3 +1719,14 @@ SetupPunchFW(const char *strValue)
|
||||
PacketAliasSetFWBase(base, num);
|
||||
(void)PacketAliasSetMode(PKT_ALIAS_PUNCH_FW, PKT_ALIAS_PUNCH_FW);
|
||||
}
|
||||
|
||||
static void
|
||||
SetupSkinnyPort(const char *strValue)
|
||||
{
|
||||
unsigned int port;
|
||||
|
||||
if (sscanf(strValue, "%u", &port) != 1)
|
||||
errx(1, "skinny_port: port parameter required");
|
||||
|
||||
PacketAliasSetSkinnyPort(port);
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ SHLIBDIR?= /lib
|
||||
SHLIB_MAJOR= 4
|
||||
MAN= libalias.3
|
||||
SRCS= alias.c alias_cuseeme.c alias_db.c alias_ftp.c alias_irc.c \
|
||||
alias_nbt.c alias_pptp.c alias_proxy.c alias_smedia.c \
|
||||
alias_nbt.c alias_pptp.c alias_proxy.c alias_skinny.c alias_smedia.c \
|
||||
alias_util.c
|
||||
INCS= alias.h
|
||||
|
||||
|
@ -917,6 +917,9 @@ TcpAliasIn(struct ip *pip)
|
||||
if (ntohs(tc->th_dport) == PPTP_CONTROL_PORT_NUMBER
|
||||
|| ntohs(tc->th_sport) == PPTP_CONTROL_PORT_NUMBER)
|
||||
AliasHandlePptpIn(pip, link);
|
||||
else if (skinnyPort != 0 && (ntohs(tc->th_dport) == skinnyPort
|
||||
|| ntohs(tc->th_sport) == skinnyPort))
|
||||
AliasHandleSkinny(pip, link);
|
||||
|
||||
alias_address = GetAliasAddress(link);
|
||||
original_address = GetOriginalAddress(link);
|
||||
@ -1098,6 +1101,9 @@ TcpAliasOut(struct ip *pip, int maxpacketsize)
|
||||
else if (ntohs(tc->th_dport) == PPTP_CONTROL_PORT_NUMBER
|
||||
|| ntohs(tc->th_sport) == PPTP_CONTROL_PORT_NUMBER)
|
||||
AliasHandlePptpOut(pip, link);
|
||||
else if (skinnyPort != 0 && (ntohs(tc->th_sport) == skinnyPort
|
||||
|| ntohs(tc->th_dport) == skinnyPort))
|
||||
AliasHandleSkinny(pip, link);
|
||||
|
||||
/* Adjust TCP checksum since source port is being aliased */
|
||||
/* and source address is being altered */
|
||||
|
@ -45,6 +45,7 @@
|
||||
void PacketAliasInit(void);
|
||||
void PacketAliasSetAddress(struct in_addr _addr);
|
||||
void PacketAliasSetFWBase(unsigned int _base, unsigned int _num);
|
||||
void PacketAliasSetSkinnyPort(unsigned int _port);
|
||||
unsigned int
|
||||
PacketAliasSetMode(unsigned int _flags, unsigned int _mask);
|
||||
void PacketAliasUninit(void);
|
||||
|
@ -398,6 +398,9 @@ static int fireWallFD = -1; /* File descriptor to be able to */
|
||||
/* flag. */
|
||||
#endif
|
||||
|
||||
unsigned int skinnyPort = 0; /* TCP port used by the Skinny */
|
||||
/* protocol. */
|
||||
|
||||
|
||||
|
||||
|
||||
@ -2948,3 +2951,8 @@ PacketAliasSetFWBase(unsigned int base, unsigned int num) {
|
||||
fireWallNumNums = num;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
PacketAliasSetSkinnyPort(unsigned int port) {
|
||||
skinnyPort = port;
|
||||
}
|
||||
|
@ -74,6 +74,7 @@
|
||||
/* Globals */
|
||||
|
||||
extern int packetAliasMode;
|
||||
extern unsigned int skinnyPort;
|
||||
|
||||
/* Prototypes */
|
||||
|
||||
@ -212,6 +213,9 @@ int AliasHandleUdpNbtNS(struct ip *_pip, struct alias_link *_link,
|
||||
void AliasHandleCUSeeMeOut(struct ip *_pip, struct alias_link *_link);
|
||||
void AliasHandleCUSeeMeIn(struct ip *_pip, struct in_addr _original_addr);
|
||||
|
||||
/* Skinny routines */
|
||||
void AliasHandleSkinny(struct ip *_pip, struct alias_link *_link);
|
||||
|
||||
/* Transparent proxy routines */
|
||||
int ProxyCheck(struct ip *_pip, struct in_addr *_proxy_server_addr,
|
||||
u_short *_proxy_server_port);
|
||||
|
@ -265,6 +265,16 @@ Set firewall range allocated for punching firewall holes (with the
|
||||
flag).
|
||||
The range will be cleared for all rules on initialization.
|
||||
.Ed
|
||||
.Pp
|
||||
.Ft void
|
||||
.Fn PacketAliasSkinnyPort "unsigned int port"
|
||||
.Bd -ragged -offset indent
|
||||
Set the TCP port used by the Skinny Station protocol.
|
||||
Skinny is used by Cisco IP phones to communicate with
|
||||
Cisco Call Managers to set up voice over IP calls.
|
||||
If this is not set, Skinny aliasing will not be done.
|
||||
The typical port used by Skinny is 2000.
|
||||
.Ed
|
||||
.Sh PACKET HANDLING
|
||||
The packet handling functions are used to modify incoming (remote to local)
|
||||
and outgoing (local to remote) packets.
|
||||
|
@ -773,6 +773,8 @@ static struct cmdtab const NatCommands[] =
|
||||
{"punch_fw", NULL, nat_PunchFW, LOCAL_AUTH,
|
||||
"firewall control", "nat punch_fw [base count]"},
|
||||
#endif
|
||||
{"skinny_port", NULL, nat_SkinnyPort, LOCAL_AUTH,
|
||||
"TCP port used by Skinny Station protocol", "nat skinny_port [port]"},
|
||||
{"same_ports", NULL, NatOption, LOCAL_AUTH,
|
||||
"try to leave port numbers unchanged", "nat same_ports yes|no",
|
||||
(const void *) PKT_ALIAS_SAME_PORTS},
|
||||
|
@ -470,6 +470,29 @@ nat_PunchFW(struct cmdargs const *arg)
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
nat_SkinnyPort(struct cmdargs const *arg)
|
||||
{
|
||||
char *end;
|
||||
long port;
|
||||
|
||||
if (arg->argc == arg->argn) {
|
||||
PacketAliasSetSkinnyPort(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (arg->argc != arg->argn + 1)
|
||||
return -1;
|
||||
|
||||
port = strtol(arg->argv[arg->argn], &end, 10);
|
||||
if (*end != '\0' || port < 0)
|
||||
return -1;
|
||||
|
||||
PacketAliasSetSkinnyPort(port);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct mbuf *
|
||||
nat_LayerPush(struct bundle *bundle, struct link *l, struct mbuf *bp,
|
||||
int pri, u_short *proto)
|
||||
|
@ -37,5 +37,6 @@ extern int nat_SetTarget(struct cmdargs const *);
|
||||
#ifndef NO_FW_PUNCH
|
||||
extern int nat_PunchFW(struct cmdargs const *);
|
||||
#endif
|
||||
extern int nat_SkinnyPort(struct cmdargs const *);
|
||||
|
||||
extern struct layer natlayer;
|
||||
|
@ -3470,6 +3470,14 @@ The range will be cleared when the
|
||||
command is run.
|
||||
.Pp
|
||||
If no arguments are given, firewall punching is disabled.
|
||||
.It nat skinny_port Op Ar port
|
||||
This command tells
|
||||
.Nm
|
||||
which TCP port is used by the Skinny Station protocol. Skinny is used by
|
||||
Cisco IP phones to communicate with Cisco Call Managers to setup voice
|
||||
over IP calls. The typical port used by Skinny is 2000.
|
||||
.Pp
|
||||
If no argument is given, skinny aliasing is disabled.
|
||||
.It nat same_ports yes|no
|
||||
When enabled, this command will tell the network address translation engine to
|
||||
attempt to avoid changing the port number on outgoing packets.
|
||||
|
Loading…
Reference in New Issue
Block a user