Run through indent(1) so I can read the code without getting a headache.
The result isn't quite knf, but it's knfer than the original, and far more consistent.
This commit is contained in:
parent
f02660b050
commit
f0f93429cf
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=127094
1859
lib/libalias/alias.c
1859
lib/libalias/alias.c
File diff suppressed because it is too large
Load Diff
@ -47,11 +47,11 @@
|
|||||||
* PacketAlias*() the old API which doesn't take an instance pointer
|
* PacketAlias*() the old API which doesn't take an instance pointer
|
||||||
* and therefore can only have one packet engine at a time.
|
* and therefore can only have one packet engine at a time.
|
||||||
*
|
*
|
||||||
* LibAlias*() the new API which takes as first argument a pointer to
|
* LibAlias*() the new API which takes as first argument a pointer to
|
||||||
* the instance of the packet aliasing engine.
|
* the instance of the packet aliasing engine.
|
||||||
*
|
*
|
||||||
* The functions otherwise correspond to each other one for one, except
|
* The functions otherwise correspond to each other one for one, except
|
||||||
* for the LibAliasUnaliasOut()/PacketUnaliasOut() function which were
|
* for the LibAliasUnaliasOut()/PacketUnaliasOut() function which were
|
||||||
* were misnamed in the old API.
|
* were misnamed in the old API.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -66,107 +66,109 @@ struct libalias;
|
|||||||
* PacketAliasRedirectProto(), passed to PacketAliasAddServer(),
|
* PacketAliasRedirectProto(), passed to PacketAliasAddServer(),
|
||||||
* and freed by PacketAliasRedirectDelete().
|
* and freed by PacketAliasRedirectDelete().
|
||||||
*/
|
*/
|
||||||
struct alias_link;
|
struct alias_link;
|
||||||
|
|
||||||
|
|
||||||
/* OLD API */
|
/* OLD API */
|
||||||
|
|
||||||
/* Initialization and control functions. */
|
/* Initialization and control functions. */
|
||||||
void PacketAliasInit(void);
|
void PacketAliasInit(void);
|
||||||
void PacketAliasSetAddress(struct in_addr _addr);
|
void PacketAliasSetAddress(struct in_addr _addr);
|
||||||
void PacketAliasSetFWBase(unsigned int _base, unsigned int _num);
|
void PacketAliasSetFWBase(unsigned int _base, unsigned int _num);
|
||||||
void PacketAliasSetSkinnyPort(unsigned int _port);
|
void PacketAliasSetSkinnyPort(unsigned int _port);
|
||||||
unsigned int
|
unsigned int
|
||||||
PacketAliasSetMode(unsigned int _flags, unsigned int _mask);
|
PacketAliasSetMode(unsigned int _flags, unsigned int _mask);
|
||||||
void PacketAliasUninit(void);
|
void PacketAliasUninit(void);
|
||||||
|
|
||||||
/* Packet Handling functions. */
|
/* Packet Handling functions. */
|
||||||
int PacketAliasIn(char *_ptr, int _maxpacketsize);
|
int PacketAliasIn(char *_ptr, int _maxpacketsize);
|
||||||
int PacketAliasOut(char *_ptr, int _maxpacketsize);
|
int PacketAliasOut(char *_ptr, int _maxpacketsize);
|
||||||
int PacketUnaliasOut(char *_ptr, int _maxpacketsize);
|
int PacketUnaliasOut(char *_ptr, int _maxpacketsize);
|
||||||
|
|
||||||
/* Port and address redirection functions. */
|
/* Port and address redirection functions. */
|
||||||
|
|
||||||
|
|
||||||
int PacketAliasAddServer(struct alias_link *_link,
|
int
|
||||||
struct in_addr _addr, unsigned short _port);
|
PacketAliasAddServer(struct alias_link *_link,
|
||||||
|
struct in_addr _addr, unsigned short _port);
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
PacketAliasRedirectAddr(struct in_addr _src_addr,
|
PacketAliasRedirectAddr(struct in_addr _src_addr,
|
||||||
struct in_addr _alias_addr);
|
struct in_addr _alias_addr);
|
||||||
int PacketAliasRedirectDynamic(struct alias_link *_link);
|
int PacketAliasRedirectDynamic(struct alias_link *_link);
|
||||||
void PacketAliasRedirectDelete(struct alias_link *_link);
|
void PacketAliasRedirectDelete(struct alias_link *_link);
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
PacketAliasRedirectPort(struct in_addr _src_addr,
|
PacketAliasRedirectPort(struct in_addr _src_addr,
|
||||||
unsigned short _src_port, struct in_addr _dst_addr,
|
unsigned short _src_port, struct in_addr _dst_addr,
|
||||||
unsigned short _dst_port, struct in_addr _alias_addr,
|
unsigned short _dst_port, struct in_addr _alias_addr,
|
||||||
unsigned short _alias_port, unsigned char _proto);
|
unsigned short _alias_port, unsigned char _proto);
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
PacketAliasRedirectProto(struct in_addr _src_addr,
|
PacketAliasRedirectProto(struct in_addr _src_addr,
|
||||||
struct in_addr _dst_addr, struct in_addr _alias_addr,
|
struct in_addr _dst_addr, struct in_addr _alias_addr,
|
||||||
unsigned char _proto);
|
unsigned char _proto);
|
||||||
|
|
||||||
/* Fragment Handling functions. */
|
/* Fragment Handling functions. */
|
||||||
void PacketAliasFragmentIn(char *_ptr, char *_ptr_fragment);
|
void PacketAliasFragmentIn(char *_ptr, char *_ptr_fragment);
|
||||||
char *PacketAliasGetFragment(char *_ptr);
|
char *PacketAliasGetFragment(char *_ptr);
|
||||||
int PacketAliasSaveFragment(char *_ptr);
|
int PacketAliasSaveFragment(char *_ptr);
|
||||||
|
|
||||||
/* Miscellaneous functions. */
|
/* Miscellaneous functions. */
|
||||||
int PacketAliasCheckNewLink(void);
|
int PacketAliasCheckNewLink(void);
|
||||||
unsigned short
|
unsigned short
|
||||||
PacketAliasInternetChecksum(unsigned short *_ptr, int _nbytes);
|
PacketAliasInternetChecksum(unsigned short *_ptr, int _nbytes);
|
||||||
void PacketAliasSetTarget(struct in_addr _target_addr);
|
void PacketAliasSetTarget(struct in_addr _target_addr);
|
||||||
|
|
||||||
/* Transparent proxying routines. */
|
/* Transparent proxying routines. */
|
||||||
int PacketAliasProxyRule(const char *_cmd);
|
int PacketAliasProxyRule(const char *_cmd);
|
||||||
|
|
||||||
/* NEW API */
|
/* NEW API */
|
||||||
|
|
||||||
/* Initialization and control functions. */
|
/* Initialization and control functions. */
|
||||||
struct libalias *LibAliasInit(struct libalias *);
|
struct libalias *LibAliasInit(struct libalias *);
|
||||||
void LibAliasSetAddress(struct libalias *, struct in_addr _addr);
|
void LibAliasSetAddress(struct libalias *, struct in_addr _addr);
|
||||||
void LibAliasSetFWBase(struct libalias *, unsigned int _base, unsigned int _num);
|
void LibAliasSetFWBase(struct libalias *, unsigned int _base, unsigned int _num);
|
||||||
void LibAliasSetSkinnyPort(struct libalias *, unsigned int _port);
|
void LibAliasSetSkinnyPort(struct libalias *, unsigned int _port);
|
||||||
unsigned int
|
unsigned int
|
||||||
LibAliasSetMode(struct libalias *, unsigned int _flags, unsigned int _mask);
|
LibAliasSetMode(struct libalias *, unsigned int _flags, unsigned int _mask);
|
||||||
void LibAliasUninit(struct libalias *);
|
void LibAliasUninit(struct libalias *);
|
||||||
|
|
||||||
/* Packet Handling functions. */
|
/* Packet Handling functions. */
|
||||||
int LibAliasIn(struct libalias *, char *_ptr, int _maxpacketsize);
|
int LibAliasIn (struct libalias *, char *_ptr, int _maxpacketsize);
|
||||||
int LibAliasOut(struct libalias *, char *_ptr, int _maxpacketsize);
|
int LibAliasOut(struct libalias *, char *_ptr, int _maxpacketsize);
|
||||||
int LibAliasUnaliasOut(struct libalias *, char *_ptr, int _maxpacketsize);
|
int LibAliasUnaliasOut(struct libalias *, char *_ptr, int _maxpacketsize);
|
||||||
|
|
||||||
/* Port and address redirection functions. */
|
/* Port and address redirection functions. */
|
||||||
|
|
||||||
int LibAliasAddServer(struct libalias *, struct alias_link *_link,
|
int
|
||||||
struct in_addr _addr, unsigned short _port);
|
LibAliasAddServer(struct libalias *, struct alias_link *_link,
|
||||||
|
struct in_addr _addr, unsigned short _port);
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
LibAliasRedirectAddr(struct libalias *, struct in_addr _src_addr,
|
LibAliasRedirectAddr(struct libalias *, struct in_addr _src_addr,
|
||||||
struct in_addr _alias_addr);
|
struct in_addr _alias_addr);
|
||||||
int LibAliasRedirectDynamic(struct libalias *, struct alias_link *_link);
|
int LibAliasRedirectDynamic(struct libalias *, struct alias_link *_link);
|
||||||
void LibAliasRedirectDelete(struct libalias *, struct alias_link *_link);
|
void LibAliasRedirectDelete(struct libalias *, struct alias_link *_link);
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
LibAliasRedirectPort(struct libalias *, struct in_addr _src_addr,
|
LibAliasRedirectPort(struct libalias *, struct in_addr _src_addr,
|
||||||
unsigned short _src_port, struct in_addr _dst_addr,
|
unsigned short _src_port, struct in_addr _dst_addr,
|
||||||
unsigned short _dst_port, struct in_addr _alias_addr,
|
unsigned short _dst_port, struct in_addr _alias_addr,
|
||||||
unsigned short _alias_port, unsigned char _proto);
|
unsigned short _alias_port, unsigned char _proto);
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
LibAliasRedirectProto(struct libalias *, struct in_addr _src_addr,
|
LibAliasRedirectProto(struct libalias *, struct in_addr _src_addr,
|
||||||
struct in_addr _dst_addr, struct in_addr _alias_addr,
|
struct in_addr _dst_addr, struct in_addr _alias_addr,
|
||||||
unsigned char _proto);
|
unsigned char _proto);
|
||||||
|
|
||||||
/* Fragment Handling functions. */
|
/* Fragment Handling functions. */
|
||||||
void LibAliasFragmentIn(struct libalias *, char *_ptr, char *_ptr_fragment);
|
void LibAliasFragmentIn(struct libalias *, char *_ptr, char *_ptr_fragment);
|
||||||
char *LibAliasGetFragment(struct libalias *, char *_ptr);
|
char *LibAliasGetFragment(struct libalias *, char *_ptr);
|
||||||
int LibAliasSaveFragment(struct libalias *, char *_ptr);
|
int LibAliasSaveFragment(struct libalias *, char *_ptr);
|
||||||
|
|
||||||
/* Miscellaneous functions. */
|
/* Miscellaneous functions. */
|
||||||
int LibAliasCheckNewLink(struct libalias *);
|
int LibAliasCheckNewLink(struct libalias *);
|
||||||
unsigned short
|
unsigned short
|
||||||
LibAliasInternetChecksum(struct libalias *, unsigned short *_ptr, int _nbytes);
|
LibAliasInternetChecksum(struct libalias *, unsigned short *_ptr, int _nbytes);
|
||||||
void LibAliasSetTarget(struct libalias *, struct in_addr _target_addr);
|
void LibAliasSetTarget(struct libalias *, struct in_addr _target_addr);
|
||||||
|
|
||||||
/* Transparent proxying routines. */
|
/* Transparent proxying routines. */
|
||||||
int LibAliasProxyRule(struct libalias *, const char *_cmd);
|
int LibAliasProxyRule(struct libalias *, const char *_cmd);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -257,6 +259,6 @@ int LibAliasProxyRule(struct libalias *, const char *_cmd);
|
|||||||
#define PKT_ALIAS_UNRESOLVED_FRAGMENT 3
|
#define PKT_ALIAS_UNRESOLVED_FRAGMENT 3
|
||||||
#define PKT_ALIAS_FOUND_HEADER_FRAGMENT 4
|
#define PKT_ALIAS_FOUND_HEADER_FRAGMENT 4
|
||||||
|
|
||||||
#endif /* !_ALIAS_H_ */
|
#endif /* !_ALIAS_H_ */
|
||||||
|
|
||||||
/* lint -restore */
|
/* lint -restore */
|
||||||
|
@ -40,83 +40,84 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
/* CU-SeeMe Data Header */
|
/* CU-SeeMe Data Header */
|
||||||
struct cu_header {
|
struct cu_header {
|
||||||
u_int16_t dest_family;
|
u_int16_t dest_family;
|
||||||
u_int16_t dest_port;
|
u_int16_t dest_port;
|
||||||
u_int32_t dest_addr;
|
u_int32_t dest_addr;
|
||||||
int16_t family;
|
int16_t family;
|
||||||
u_int16_t port;
|
u_int16_t port;
|
||||||
u_int32_t addr;
|
u_int32_t addr;
|
||||||
u_int32_t seq;
|
u_int32_t seq;
|
||||||
u_int16_t msg;
|
u_int16_t msg;
|
||||||
u_int16_t data_type;
|
u_int16_t data_type;
|
||||||
u_int16_t packet_len;
|
u_int16_t packet_len;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Open Continue Header */
|
/* Open Continue Header */
|
||||||
struct oc_header {
|
struct oc_header {
|
||||||
u_int16_t client_count; /* Number of client info structs */
|
u_int16_t client_count; /* Number of client info structs */
|
||||||
u_int32_t seq_no;
|
u_int32_t seq_no;
|
||||||
char user_name[20];
|
char user_name [20];
|
||||||
char reserved[4]; /* flags, version stuff, etc */
|
char reserved [4]; /* flags, version stuff, etc */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* client info structures */
|
/* client info structures */
|
||||||
struct client_info {
|
struct client_info {
|
||||||
u_int32_t address; /* Client address */
|
u_int32_t address;/* Client address */
|
||||||
char reserved[8]; /* Flags, pruning bitfield, packet counts etc */
|
char reserved [8]; /* Flags, pruning bitfield, packet
|
||||||
|
* counts etc */
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
AliasHandleCUSeeMeOut(struct libalias *la, struct ip *pip, struct alias_link *link)
|
AliasHandleCUSeeMeOut(struct libalias *la, struct ip *pip, struct alias_link *link)
|
||||||
{
|
{
|
||||||
struct udphdr *ud;
|
struct udphdr *ud;
|
||||||
|
|
||||||
ud = (struct udphdr *)((char *)pip + (pip->ip_hl << 2));
|
ud = (struct udphdr *)((char *)pip + (pip->ip_hl << 2));
|
||||||
if (ntohs(ud->uh_ulen) - sizeof(struct udphdr) >= sizeof(struct cu_header)) {
|
if (ntohs(ud->uh_ulen) - sizeof(struct udphdr) >= sizeof(struct cu_header)) {
|
||||||
struct cu_header *cu;
|
struct cu_header *cu;
|
||||||
struct alias_link *cu_link;
|
struct alias_link *cu_link;
|
||||||
|
|
||||||
cu = (struct cu_header *)(ud + 1);
|
cu = (struct cu_header *)(ud + 1);
|
||||||
if (cu->addr)
|
if (cu->addr)
|
||||||
cu->addr = (u_int32_t)GetAliasAddress(link).s_addr;
|
cu->addr = (u_int32_t) GetAliasAddress(link).s_addr;
|
||||||
|
|
||||||
cu_link = FindUdpTcpOut(la, pip->ip_src, GetDestAddress(link),
|
cu_link = FindUdpTcpOut(la, pip->ip_src, GetDestAddress(link),
|
||||||
ud->uh_dport, 0, IPPROTO_UDP, 1);
|
ud->uh_dport, 0, IPPROTO_UDP, 1);
|
||||||
|
|
||||||
#ifndef NO_FW_PUNCH
|
#ifndef NO_FW_PUNCH
|
||||||
if (cu_link)
|
if (cu_link)
|
||||||
PunchFWHole(cu_link);
|
PunchFWHole(cu_link);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
AliasHandleCUSeeMeIn(struct libalias *la, struct ip *pip, struct in_addr original_addr)
|
AliasHandleCUSeeMeIn(struct libalias *la, struct ip *pip, struct in_addr original_addr)
|
||||||
{
|
{
|
||||||
struct in_addr alias_addr;
|
struct in_addr alias_addr;
|
||||||
struct udphdr *ud;
|
struct udphdr *ud;
|
||||||
struct cu_header *cu;
|
struct cu_header *cu;
|
||||||
struct oc_header *oc;
|
struct oc_header *oc;
|
||||||
struct client_info *ci;
|
struct client_info *ci;
|
||||||
char *end;
|
char *end;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
alias_addr.s_addr = pip->ip_dst.s_addr;
|
alias_addr.s_addr = pip->ip_dst.s_addr;
|
||||||
ud = (struct udphdr *)((char *)pip + (pip->ip_hl << 2));
|
ud = (struct udphdr *)((char *)pip + (pip->ip_hl << 2));
|
||||||
cu = (struct cu_header *)(ud + 1);
|
cu = (struct cu_header *)(ud + 1);
|
||||||
oc = (struct oc_header *)(cu + 1);
|
oc = (struct oc_header *)(cu + 1);
|
||||||
ci = (struct client_info *)(oc + 1);
|
ci = (struct client_info *)(oc + 1);
|
||||||
end = (char *)ud + ntohs(ud->uh_ulen);
|
end = (char *)ud + ntohs(ud->uh_ulen);
|
||||||
|
|
||||||
if ((char *)oc <= end) {
|
if ((char *)oc <= end) {
|
||||||
if(cu->dest_addr)
|
if (cu->dest_addr)
|
||||||
cu->dest_addr = (u_int32_t)original_addr.s_addr;
|
cu->dest_addr = (u_int32_t) original_addr.s_addr;
|
||||||
if(ntohs(cu->data_type) == 101)
|
if (ntohs(cu->data_type) == 101)
|
||||||
/* Find and change our address */
|
/* Find and change our address */
|
||||||
for(i = 0; (char *)(ci + 1) <= end && i < oc->client_count; i++, ci++)
|
for (i = 0; (char *)(ci + 1) <= end && i < oc->client_count; i++, ci++)
|
||||||
if(ci->address == (u_int32_t)alias_addr.s_addr) {
|
if (ci->address == (u_int32_t) alias_addr.s_addr) {
|
||||||
ci->address = (u_int32_t)original_addr.s_addr;
|
ci->address = (u_int32_t) original_addr.s_addr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -87,495 +87,589 @@ __FBSDID("$FreeBSD$");
|
|||||||
#define WAIT_CRLF 0x01
|
#define WAIT_CRLF 0x01
|
||||||
|
|
||||||
enum ftp_message_type {
|
enum ftp_message_type {
|
||||||
FTP_PORT_COMMAND,
|
FTP_PORT_COMMAND,
|
||||||
FTP_EPRT_COMMAND,
|
FTP_EPRT_COMMAND,
|
||||||
FTP_227_REPLY,
|
FTP_227_REPLY,
|
||||||
FTP_229_REPLY,
|
FTP_229_REPLY,
|
||||||
FTP_UNKNOWN_MESSAGE
|
FTP_UNKNOWN_MESSAGE
|
||||||
};
|
};
|
||||||
|
|
||||||
static int ParseFtpPortCommand(struct libalias *la, char *, int);
|
static int ParseFtpPortCommand(struct libalias *la, char *, int);
|
||||||
static int ParseFtpEprtCommand(struct libalias *la, char *, int);
|
static int ParseFtpEprtCommand(struct libalias *la, char *, int);
|
||||||
static int ParseFtp227Reply(struct libalias *la, char *, int);
|
static int ParseFtp227Reply(struct libalias *la, char *, int);
|
||||||
static int ParseFtp229Reply(struct libalias *la, char *, int);
|
static int ParseFtp229Reply(struct libalias *la, char *, int);
|
||||||
static void NewFtpMessage(struct libalias *la, struct ip *, struct alias_link *, int, int);
|
static void NewFtpMessage(struct libalias *la, struct ip *, struct alias_link *, int, int);
|
||||||
|
|
||||||
void
|
void
|
||||||
AliasHandleFtpOut(
|
AliasHandleFtpOut(
|
||||||
struct libalias *la,
|
struct libalias *la,
|
||||||
struct ip *pip, /* IP packet to examine/patch */
|
struct ip *pip, /* IP packet to examine/patch */
|
||||||
struct alias_link *link, /* The link to go through (aliased port) */
|
struct alias_link *link, /* The link to go through (aliased port) */
|
||||||
int maxpacketsize /* The maximum size this packet can grow to (including headers) */)
|
int maxpacketsize /* The maximum size this packet can grow to
|
||||||
|
(including headers) */ )
|
||||||
{
|
{
|
||||||
int hlen, tlen, dlen, pflags;
|
int hlen, tlen, dlen, pflags;
|
||||||
char *sptr;
|
char *sptr;
|
||||||
struct tcphdr *tc;
|
struct tcphdr *tc;
|
||||||
int ftp_message_type;
|
int ftp_message_type;
|
||||||
|
|
||||||
/* Calculate data length of TCP packet */
|
/* Calculate data length of TCP packet */
|
||||||
tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
|
tc = (struct tcphdr *)((char *)pip + (pip->ip_hl << 2));
|
||||||
hlen = (pip->ip_hl + tc->th_off) << 2;
|
hlen = (pip->ip_hl + tc->th_off) << 2;
|
||||||
tlen = ntohs(pip->ip_len);
|
tlen = ntohs(pip->ip_len);
|
||||||
dlen = tlen - hlen;
|
dlen = tlen - hlen;
|
||||||
|
|
||||||
/* Place string pointer and beginning of data */
|
/* Place string pointer and beginning of data */
|
||||||
sptr = (char *) pip;
|
sptr = (char *)pip;
|
||||||
sptr += hlen;
|
sptr += hlen;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check that data length is not too long and previous message was
|
* Check that data length is not too long and previous message was
|
||||||
* properly terminated with CRLF.
|
* properly terminated with CRLF.
|
||||||
*/
|
*/
|
||||||
pflags = GetProtocolFlags(link);
|
pflags = GetProtocolFlags(link);
|
||||||
if (dlen <= MAX_MESSAGE_SIZE && !(pflags & WAIT_CRLF)) {
|
if (dlen <= MAX_MESSAGE_SIZE && !(pflags & WAIT_CRLF)) {
|
||||||
ftp_message_type = FTP_UNKNOWN_MESSAGE;
|
ftp_message_type = FTP_UNKNOWN_MESSAGE;
|
||||||
|
|
||||||
if (ntohs(tc->th_dport) == FTP_CONTROL_PORT_NUMBER) {
|
if (ntohs(tc->th_dport) == FTP_CONTROL_PORT_NUMBER) {
|
||||||
/*
|
/*
|
||||||
* When aliasing a client, check for the PORT/EPRT command.
|
* When aliasing a client, check for the PORT/EPRT command.
|
||||||
*/
|
*/
|
||||||
if (ParseFtpPortCommand(la, sptr, dlen))
|
if (ParseFtpPortCommand(la, sptr, dlen))
|
||||||
ftp_message_type = FTP_PORT_COMMAND;
|
ftp_message_type = FTP_PORT_COMMAND;
|
||||||
else if (ParseFtpEprtCommand(la, sptr, dlen))
|
else if (ParseFtpEprtCommand(la, sptr, dlen))
|
||||||
ftp_message_type = FTP_EPRT_COMMAND;
|
ftp_message_type = FTP_EPRT_COMMAND;
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* When aliasing a server, check for the 227/229 reply.
|
* When aliasing a server, check for the 227/229 reply.
|
||||||
*/
|
*/
|
||||||
if (ParseFtp227Reply(la, sptr, dlen))
|
if (ParseFtp227Reply(la, sptr, dlen))
|
||||||
ftp_message_type = FTP_227_REPLY;
|
ftp_message_type = FTP_227_REPLY;
|
||||||
else if (ParseFtp229Reply(la, sptr, dlen)) {
|
else if (ParseFtp229Reply(la, sptr, dlen)) {
|
||||||
ftp_message_type = FTP_229_REPLY;
|
ftp_message_type = FTP_229_REPLY;
|
||||||
la->true_addr.s_addr = pip->ip_src.s_addr;
|
la->true_addr.s_addr = pip->ip_src.s_addr;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ftp_message_type != FTP_UNKNOWN_MESSAGE)
|
||||||
|
NewFtpMessage(la, pip, link, maxpacketsize, ftp_message_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ftp_message_type != FTP_UNKNOWN_MESSAGE)
|
|
||||||
NewFtpMessage(la, pip, link, maxpacketsize, ftp_message_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Track the msgs which are CRLF term'd for PORT/PASV FW breach */
|
/* Track the msgs which are CRLF term'd for PORT/PASV FW breach */
|
||||||
|
|
||||||
if (dlen) { /* only if there's data */
|
if (dlen) { /* only if there's data */
|
||||||
sptr = (char *) pip; /* start over at beginning */
|
sptr = (char *)pip; /* start over at beginning */
|
||||||
tlen = ntohs(pip->ip_len); /* recalc tlen, pkt may have grown */
|
tlen = ntohs(pip->ip_len); /* recalc tlen, pkt may
|
||||||
if (sptr[tlen-2] == '\r' && sptr[tlen-1] == '\n')
|
* have grown */
|
||||||
pflags &= ~WAIT_CRLF;
|
if (sptr[tlen - 2] == '\r' && sptr[tlen - 1] == '\n')
|
||||||
else
|
pflags &= ~WAIT_CRLF;
|
||||||
pflags |= WAIT_CRLF;
|
else
|
||||||
SetProtocolFlags(link, pflags);
|
pflags |= WAIT_CRLF;
|
||||||
}
|
SetProtocolFlags(link, pflags);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ParseFtpPortCommand(struct libalias *la, char *sptr, int dlen)
|
ParseFtpPortCommand(struct libalias *la, char *sptr, int dlen)
|
||||||
{
|
{
|
||||||
char ch;
|
char ch;
|
||||||
int i, state;
|
int i, state;
|
||||||
u_int32_t addr;
|
u_int32_t addr;
|
||||||
u_short port;
|
u_short port;
|
||||||
u_int8_t octet;
|
u_int8_t octet;
|
||||||
|
|
||||||
/* Format: "PORT A,D,D,R,PO,RT". */
|
/* Format: "PORT A,D,D,R,PO,RT". */
|
||||||
|
|
||||||
/* Return if data length is too short. */
|
/* Return if data length is too short. */
|
||||||
if (dlen < 18)
|
if (dlen < 18)
|
||||||
return 0;
|
|
||||||
|
|
||||||
addr = port = octet = 0;
|
|
||||||
state = -4;
|
|
||||||
for (i = 0; i < dlen; i++) {
|
|
||||||
ch = sptr[i];
|
|
||||||
switch (state) {
|
|
||||||
case -4: if (ch == 'P') state++; else return 0; break;
|
|
||||||
case -3: if (ch == 'O') state++; else return 0; break;
|
|
||||||
case -2: if (ch == 'R') state++; else return 0; break;
|
|
||||||
case -1: if (ch == 'T') state++; else return 0; break;
|
|
||||||
|
|
||||||
case 0:
|
|
||||||
if (isspace(ch))
|
|
||||||
break;
|
|
||||||
else
|
|
||||||
state++;
|
|
||||||
case 1: case 3: case 5: case 7: case 9: case 11:
|
|
||||||
if (isdigit(ch)) {
|
|
||||||
octet = ch - '0';
|
|
||||||
state++;
|
|
||||||
} else
|
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
|
||||||
case 2: case 4: case 6: case 8:
|
addr = port = octet = 0;
|
||||||
if (isdigit(ch))
|
state = -4;
|
||||||
octet = 10 * octet + ch - '0';
|
for (i = 0; i < dlen; i++) {
|
||||||
else if (ch == ',') {
|
ch = sptr[i];
|
||||||
addr = (addr << 8) + octet;
|
switch (state) {
|
||||||
state++;
|
case -4:
|
||||||
} else
|
if (ch == 'P')
|
||||||
return 0;
|
state++;
|
||||||
break;
|
else
|
||||||
case 10: case 12:
|
return 0;
|
||||||
if (isdigit(ch))
|
break;
|
||||||
octet = 10 * octet + ch - '0';
|
case -3:
|
||||||
else if (ch == ',' || state == 12) {
|
if (ch == 'O')
|
||||||
port = (port << 8) + octet;
|
state++;
|
||||||
state++;
|
else
|
||||||
} else
|
return 0;
|
||||||
return 0;
|
break;
|
||||||
break;
|
case -2:
|
||||||
|
if (ch == 'R')
|
||||||
|
state++;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
case -1:
|
||||||
|
if (ch == 'T')
|
||||||
|
state++;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0:
|
||||||
|
if (isspace(ch))
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
state++;
|
||||||
|
case 1:
|
||||||
|
case 3:
|
||||||
|
case 5:
|
||||||
|
case 7:
|
||||||
|
case 9:
|
||||||
|
case 11:
|
||||||
|
if (isdigit(ch)) {
|
||||||
|
octet = ch - '0';
|
||||||
|
state++;
|
||||||
|
} else
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
case 4:
|
||||||
|
case 6:
|
||||||
|
case 8:
|
||||||
|
if (isdigit(ch))
|
||||||
|
octet = 10 * octet + ch - '0';
|
||||||
|
else if (ch == ',') {
|
||||||
|
addr = (addr << 8) + octet;
|
||||||
|
state++;
|
||||||
|
} else
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
case 12:
|
||||||
|
if (isdigit(ch))
|
||||||
|
octet = 10 * octet + ch - '0';
|
||||||
|
else if (ch == ',' || state == 12) {
|
||||||
|
port = (port << 8) + octet;
|
||||||
|
state++;
|
||||||
|
} else
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (state == 13) {
|
if (state == 13) {
|
||||||
la->true_addr.s_addr = htonl(addr);
|
la->true_addr.s_addr = htonl(addr);
|
||||||
la->true_port = port;
|
la->true_port = port;
|
||||||
return 1;
|
return 1;
|
||||||
} else
|
} else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ParseFtpEprtCommand(struct libalias *la, char *sptr, int dlen)
|
ParseFtpEprtCommand(struct libalias *la, char *sptr, int dlen)
|
||||||
{
|
{
|
||||||
char ch, delim;
|
char ch, delim;
|
||||||
int i, state;
|
int i, state;
|
||||||
u_int32_t addr;
|
u_int32_t addr;
|
||||||
u_short port;
|
u_short port;
|
||||||
u_int8_t octet;
|
u_int8_t octet;
|
||||||
|
|
||||||
/* Format: "EPRT |1|A.D.D.R|PORT|". */
|
/* Format: "EPRT |1|A.D.D.R|PORT|". */
|
||||||
|
|
||||||
/* Return if data length is too short. */
|
/* Return if data length is too short. */
|
||||||
if (dlen < 18)
|
if (dlen < 18)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
addr = port = octet = 0;
|
addr = port = octet = 0;
|
||||||
delim = '|'; /* XXX gcc -Wuninitialized */
|
delim = '|'; /* XXX gcc -Wuninitialized */
|
||||||
state = -4;
|
state = -4;
|
||||||
for (i = 0; i < dlen; i++) {
|
for (i = 0; i < dlen; i++) {
|
||||||
ch = sptr[i];
|
ch = sptr[i];
|
||||||
switch (state)
|
switch (state) {
|
||||||
{
|
case -4:
|
||||||
case -4: if (ch == 'E') state++; else return 0; break;
|
if (ch == 'E')
|
||||||
case -3: if (ch == 'P') state++; else return 0; break;
|
state++;
|
||||||
case -2: if (ch == 'R') state++; else return 0; break;
|
else
|
||||||
case -1: if (ch == 'T') state++; else return 0; break;
|
return 0;
|
||||||
|
break;
|
||||||
|
case -3:
|
||||||
|
if (ch == 'P')
|
||||||
|
state++;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
case -2:
|
||||||
|
if (ch == 'R')
|
||||||
|
state++;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
case -1:
|
||||||
|
if (ch == 'T')
|
||||||
|
state++;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
|
||||||
case 0:
|
case 0:
|
||||||
if (!isspace(ch)) {
|
if (!isspace(ch)) {
|
||||||
delim = ch;
|
delim = ch;
|
||||||
state++;
|
state++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
if (ch == '1') /* IPv4 address */
|
if (ch == '1') /* IPv4 address */
|
||||||
state++;
|
state++;
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
if (ch == delim)
|
if (ch == delim)
|
||||||
state++;
|
state++;
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
case 3: case 5: case 7: case 9:
|
case 3:
|
||||||
if (isdigit(ch)) {
|
case 5:
|
||||||
octet = ch - '0';
|
case 7:
|
||||||
state++;
|
case 9:
|
||||||
} else
|
if (isdigit(ch)) {
|
||||||
return 0;
|
octet = ch - '0';
|
||||||
break;
|
state++;
|
||||||
case 4: case 6: case 8: case 10:
|
} else
|
||||||
if (isdigit(ch))
|
return 0;
|
||||||
octet = 10 * octet + ch - '0';
|
break;
|
||||||
else if (ch == '.' || state == 10) {
|
case 4:
|
||||||
addr = (addr << 8) + octet;
|
case 6:
|
||||||
state++;
|
case 8:
|
||||||
} else
|
case 10:
|
||||||
return 0;
|
if (isdigit(ch))
|
||||||
break;
|
octet = 10 * octet + ch - '0';
|
||||||
case 11:
|
else if (ch == '.' || state == 10) {
|
||||||
if (isdigit(ch)) {
|
addr = (addr << 8) + octet;
|
||||||
port = ch - '0';
|
state++;
|
||||||
state++;
|
} else
|
||||||
} else
|
return 0;
|
||||||
return 0;
|
break;
|
||||||
break;
|
case 11:
|
||||||
case 12:
|
if (isdigit(ch)) {
|
||||||
if (isdigit(ch))
|
port = ch - '0';
|
||||||
port = 10 * port + ch - '0';
|
state++;
|
||||||
else if (ch == delim)
|
} else
|
||||||
state++;
|
return 0;
|
||||||
else
|
break;
|
||||||
return 0;
|
case 12:
|
||||||
break;
|
if (isdigit(ch))
|
||||||
|
port = 10 * port + ch - '0';
|
||||||
|
else if (ch == delim)
|
||||||
|
state++;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (state == 13) {
|
if (state == 13) {
|
||||||
la->true_addr.s_addr = htonl(addr);
|
la->true_addr.s_addr = htonl(addr);
|
||||||
la->true_port = port;
|
la->true_port = port;
|
||||||
return 1;
|
return 1;
|
||||||
} else
|
} else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ParseFtp227Reply(struct libalias *la, char *sptr, int dlen)
|
ParseFtp227Reply(struct libalias *la, char *sptr, int dlen)
|
||||||
{
|
{
|
||||||
char ch;
|
char ch;
|
||||||
int i, state;
|
int i, state;
|
||||||
u_int32_t addr;
|
u_int32_t addr;
|
||||||
u_short port;
|
u_short port;
|
||||||
u_int8_t octet;
|
u_int8_t octet;
|
||||||
|
|
||||||
/* Format: "227 Entering Passive Mode (A,D,D,R,PO,RT)" */
|
/* Format: "227 Entering Passive Mode (A,D,D,R,PO,RT)" */
|
||||||
|
|
||||||
/* Return if data length is too short. */
|
/* Return if data length is too short. */
|
||||||
if (dlen < 17)
|
if (dlen < 17)
|
||||||
return 0;
|
|
||||||
|
|
||||||
addr = port = octet = 0;
|
|
||||||
|
|
||||||
state = -3;
|
|
||||||
for (i = 0; i < dlen; i++) {
|
|
||||||
ch = sptr[i];
|
|
||||||
switch (state)
|
|
||||||
{
|
|
||||||
case -3: if (ch == '2') state++; else return 0; break;
|
|
||||||
case -2: if (ch == '2') state++; else return 0; break;
|
|
||||||
case -1: if (ch == '7') state++; else return 0; break;
|
|
||||||
|
|
||||||
case 0:
|
|
||||||
if (ch == '(')
|
|
||||||
state++;
|
|
||||||
break;
|
|
||||||
case 1: case 3: case 5: case 7: case 9: case 11:
|
|
||||||
if (isdigit(ch)) {
|
|
||||||
octet = ch - '0';
|
|
||||||
state++;
|
|
||||||
} else
|
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
|
||||||
case 2: case 4: case 6: case 8:
|
addr = port = octet = 0;
|
||||||
if (isdigit(ch))
|
|
||||||
octet = 10 * octet + ch - '0';
|
state = -3;
|
||||||
else if (ch == ',') {
|
for (i = 0; i < dlen; i++) {
|
||||||
addr = (addr << 8) + octet;
|
ch = sptr[i];
|
||||||
state++;
|
switch (state) {
|
||||||
} else
|
case -3:
|
||||||
return 0;
|
if (ch == '2')
|
||||||
break;
|
state++;
|
||||||
case 10: case 12:
|
else
|
||||||
if (isdigit(ch))
|
return 0;
|
||||||
octet = 10 * octet + ch - '0';
|
break;
|
||||||
else if (ch == ',' || (state == 12 && ch == ')')) {
|
case -2:
|
||||||
port = (port << 8) + octet;
|
if (ch == '2')
|
||||||
state++;
|
state++;
|
||||||
} else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
|
case -1:
|
||||||
|
if (ch == '7')
|
||||||
|
state++;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0:
|
||||||
|
if (ch == '(')
|
||||||
|
state++;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
case 3:
|
||||||
|
case 5:
|
||||||
|
case 7:
|
||||||
|
case 9:
|
||||||
|
case 11:
|
||||||
|
if (isdigit(ch)) {
|
||||||
|
octet = ch - '0';
|
||||||
|
state++;
|
||||||
|
} else
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
case 4:
|
||||||
|
case 6:
|
||||||
|
case 8:
|
||||||
|
if (isdigit(ch))
|
||||||
|
octet = 10 * octet + ch - '0';
|
||||||
|
else if (ch == ',') {
|
||||||
|
addr = (addr << 8) + octet;
|
||||||
|
state++;
|
||||||
|
} else
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
case 12:
|
||||||
|
if (isdigit(ch))
|
||||||
|
octet = 10 * octet + ch - '0';
|
||||||
|
else if (ch == ',' || (state == 12 && ch == ')')) {
|
||||||
|
port = (port << 8) + octet;
|
||||||
|
state++;
|
||||||
|
} else
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (state == 13) {
|
if (state == 13) {
|
||||||
la->true_port = port;
|
la->true_port = port;
|
||||||
la->true_addr.s_addr = htonl(addr);
|
la->true_addr.s_addr = htonl(addr);
|
||||||
return 1;
|
return 1;
|
||||||
} else
|
} else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ParseFtp229Reply(struct libalias *la, char *sptr, int dlen)
|
ParseFtp229Reply(struct libalias *la, char *sptr, int dlen)
|
||||||
{
|
{
|
||||||
char ch, delim;
|
char ch, delim;
|
||||||
int i, state;
|
int i, state;
|
||||||
u_short port;
|
u_short port;
|
||||||
|
|
||||||
/* Format: "229 Entering Extended Passive Mode (|||PORT|)" */
|
/* Format: "229 Entering Extended Passive Mode (|||PORT|)" */
|
||||||
|
|
||||||
/* Return if data length is too short. */
|
/* Return if data length is too short. */
|
||||||
if (dlen < 11)
|
if (dlen < 11)
|
||||||
return 0;
|
|
||||||
|
|
||||||
port = 0;
|
|
||||||
delim = '|'; /* XXX gcc -Wuninitialized */
|
|
||||||
|
|
||||||
state = -3;
|
|
||||||
for (i = 0; i < dlen; i++) {
|
|
||||||
ch = sptr[i];
|
|
||||||
switch (state)
|
|
||||||
{
|
|
||||||
case -3: if (ch == '2') state++; else return 0; break;
|
|
||||||
case -2: if (ch == '2') state++; else return 0; break;
|
|
||||||
case -1: if (ch == '9') state++; else return 0; break;
|
|
||||||
|
|
||||||
case 0:
|
|
||||||
if (ch == '(')
|
|
||||||
state++;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
delim = ch;
|
|
||||||
state++;
|
|
||||||
break;
|
|
||||||
case 2: case 3:
|
|
||||||
if (ch == delim)
|
|
||||||
state++;
|
|
||||||
else
|
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
|
||||||
case 4:
|
port = 0;
|
||||||
if (isdigit(ch)) {
|
delim = '|'; /* XXX gcc -Wuninitialized */
|
||||||
port = ch - '0';
|
|
||||||
state++;
|
state = -3;
|
||||||
} else
|
for (i = 0; i < dlen; i++) {
|
||||||
return 0;
|
ch = sptr[i];
|
||||||
break;
|
switch (state) {
|
||||||
case 5:
|
case -3:
|
||||||
if (isdigit(ch))
|
if (ch == '2')
|
||||||
port = 10 * port + ch - '0';
|
state++;
|
||||||
else if (ch == delim)
|
else
|
||||||
state++;
|
return 0;
|
||||||
else
|
break;
|
||||||
return 0;
|
case -2:
|
||||||
break;
|
if (ch == '2')
|
||||||
case 6:
|
state++;
|
||||||
if (ch == ')')
|
else
|
||||||
state++;
|
return 0;
|
||||||
else
|
break;
|
||||||
return 0;
|
case -1:
|
||||||
break;
|
if (ch == '9')
|
||||||
|
state++;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0:
|
||||||
|
if (ch == '(')
|
||||||
|
state++;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
delim = ch;
|
||||||
|
state++;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
if (ch == delim)
|
||||||
|
state++;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
if (isdigit(ch)) {
|
||||||
|
port = ch - '0';
|
||||||
|
state++;
|
||||||
|
} else
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
if (isdigit(ch))
|
||||||
|
port = 10 * port + ch - '0';
|
||||||
|
else if (ch == delim)
|
||||||
|
state++;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
if (ch == ')')
|
||||||
|
state++;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (state == 7) {
|
if (state == 7) {
|
||||||
la->true_port = port;
|
la->true_port = port;
|
||||||
return 1;
|
return 1;
|
||||||
} else
|
} else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
NewFtpMessage(struct libalias *la, struct ip *pip,
|
NewFtpMessage(struct libalias *la, struct ip *pip,
|
||||||
struct alias_link *link,
|
struct alias_link *link,
|
||||||
int maxpacketsize,
|
int maxpacketsize,
|
||||||
int ftp_message_type)
|
int ftp_message_type)
|
||||||
{
|
{
|
||||||
struct alias_link *ftp_link;
|
struct alias_link *ftp_link;
|
||||||
|
|
||||||
/* Security checks. */
|
/* Security checks. */
|
||||||
if (pip->ip_src.s_addr != la->true_addr.s_addr)
|
if (pip->ip_src.s_addr != la->true_addr.s_addr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (la->true_port < IPPORT_RESERVED)
|
if (la->true_port < IPPORT_RESERVED)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Establish link to address and port found in FTP control message. */
|
/* Establish link to address and port found in FTP control message. */
|
||||||
ftp_link = FindUdpTcpOut(la, la->true_addr, GetDestAddress(link),
|
ftp_link = FindUdpTcpOut(la, la->true_addr, GetDestAddress(link),
|
||||||
htons(la->true_port), 0, IPPROTO_TCP, 1);
|
htons(la->true_port), 0, IPPROTO_TCP, 1);
|
||||||
|
|
||||||
if (ftp_link != NULL)
|
if (ftp_link != NULL) {
|
||||||
{
|
int slen, hlen, tlen, dlen;
|
||||||
int slen, hlen, tlen, dlen;
|
struct tcphdr *tc;
|
||||||
struct tcphdr *tc;
|
|
||||||
|
|
||||||
#ifndef NO_FW_PUNCH
|
#ifndef NO_FW_PUNCH
|
||||||
/* Punch hole in firewall */
|
/* Punch hole in firewall */
|
||||||
PunchFWHole(ftp_link);
|
PunchFWHole(ftp_link);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Calculate data length of TCP packet */
|
/* Calculate data length of TCP packet */
|
||||||
tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
|
tc = (struct tcphdr *)((char *)pip + (pip->ip_hl << 2));
|
||||||
hlen = (pip->ip_hl + tc->th_off) << 2;
|
hlen = (pip->ip_hl + tc->th_off) << 2;
|
||||||
tlen = ntohs(pip->ip_len);
|
tlen = ntohs(pip->ip_len);
|
||||||
dlen = tlen - hlen;
|
dlen = tlen - hlen;
|
||||||
|
|
||||||
/* Create new FTP message. */
|
/* Create new FTP message. */
|
||||||
{
|
{
|
||||||
char stemp[MAX_MESSAGE_SIZE + 1];
|
char stemp[MAX_MESSAGE_SIZE + 1];
|
||||||
char *sptr;
|
char *sptr;
|
||||||
u_short alias_port;
|
u_short alias_port;
|
||||||
u_char *ptr;
|
u_char *ptr;
|
||||||
int a1, a2, a3, a4, p1, p2;
|
int a1, a2, a3, a4, p1, p2;
|
||||||
struct in_addr alias_address;
|
struct in_addr alias_address;
|
||||||
|
|
||||||
/* Decompose alias address into quad format */
|
/* Decompose alias address into quad format */
|
||||||
alias_address = GetAliasAddress(link);
|
alias_address = GetAliasAddress(link);
|
||||||
ptr = (u_char *) &alias_address.s_addr;
|
ptr = (u_char *) & alias_address.s_addr;
|
||||||
a1 = *ptr++; a2=*ptr++; a3=*ptr++; a4=*ptr;
|
a1 = *ptr++;
|
||||||
|
a2 = *ptr++;
|
||||||
|
a3 = *ptr++;
|
||||||
|
a4 = *ptr;
|
||||||
|
|
||||||
alias_port = GetAliasPort(ftp_link);
|
alias_port = GetAliasPort(ftp_link);
|
||||||
|
|
||||||
switch (ftp_message_type)
|
switch (ftp_message_type) {
|
||||||
{
|
case FTP_PORT_COMMAND:
|
||||||
case FTP_PORT_COMMAND:
|
case FTP_227_REPLY:
|
||||||
case FTP_227_REPLY:
|
/* Decompose alias port into pair format. */
|
||||||
/* Decompose alias port into pair format. */
|
ptr = (char *)&alias_port;
|
||||||
ptr = (char *) &alias_port;
|
p1 = *ptr++;
|
||||||
p1 = *ptr++; p2=*ptr;
|
p2 = *ptr;
|
||||||
|
|
||||||
if (ftp_message_type == FTP_PORT_COMMAND) {
|
if (ftp_message_type == FTP_PORT_COMMAND) {
|
||||||
/* Generate PORT command string. */
|
/* Generate PORT command string. */
|
||||||
sprintf(stemp, "PORT %d,%d,%d,%d,%d,%d\r\n",
|
sprintf(stemp, "PORT %d,%d,%d,%d,%d,%d\r\n",
|
||||||
a1,a2,a3,a4,p1,p2);
|
a1, a2, a3, a4, p1, p2);
|
||||||
} else {
|
} else {
|
||||||
/* Generate 227 reply string. */
|
/* Generate 227 reply string. */
|
||||||
sprintf(stemp,
|
sprintf(stemp,
|
||||||
"227 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n",
|
"227 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n",
|
||||||
a1,a2,a3,a4,p1,p2);
|
a1, a2, a3, a4, p1, p2);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FTP_EPRT_COMMAND:
|
case FTP_EPRT_COMMAND:
|
||||||
/* Generate EPRT command string. */
|
/* Generate EPRT command string. */
|
||||||
sprintf(stemp, "EPRT |1|%d.%d.%d.%d|%d|\r\n",
|
sprintf(stemp, "EPRT |1|%d.%d.%d.%d|%d|\r\n",
|
||||||
a1,a2,a3,a4,ntohs(alias_port));
|
a1, a2, a3, a4, ntohs(alias_port));
|
||||||
break;
|
break;
|
||||||
case FTP_229_REPLY:
|
case FTP_229_REPLY:
|
||||||
/* Generate 229 reply string. */
|
/* Generate 229 reply string. */
|
||||||
sprintf(stemp, "229 Entering Extended Passive Mode (|||%d|)\r\n",
|
sprintf(stemp, "229 Entering Extended Passive Mode (|||%d|)\r\n",
|
||||||
ntohs(alias_port));
|
ntohs(alias_port));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save string length for IP header modification */
|
/* Save string length for IP header modification */
|
||||||
slen = strlen(stemp);
|
slen = strlen(stemp);
|
||||||
|
|
||||||
/* Copy modified buffer into IP packet. */
|
/* Copy modified buffer into IP packet. */
|
||||||
sptr = (char *) pip; sptr += hlen;
|
sptr = (char *)pip;
|
||||||
strncpy(sptr, stemp, maxpacketsize-hlen);
|
sptr += hlen;
|
||||||
}
|
strncpy(sptr, stemp, maxpacketsize - hlen);
|
||||||
|
}
|
||||||
|
|
||||||
/* Save information regarding modified seq and ack numbers */
|
/* Save information regarding modified seq and ack numbers */
|
||||||
{
|
{
|
||||||
int delta;
|
int delta;
|
||||||
|
|
||||||
SetAckModified(link);
|
SetAckModified(link);
|
||||||
delta = GetDeltaSeqOut(pip, link);
|
delta = GetDeltaSeqOut(pip, link);
|
||||||
AddSeq(pip, link, delta+slen-dlen);
|
AddSeq(pip, link, delta + slen - dlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Revise IP header */
|
/* Revise IP header */
|
||||||
{
|
{
|
||||||
u_short new_len;
|
u_short new_len;
|
||||||
|
|
||||||
new_len = htons(hlen + slen);
|
new_len = htons(hlen + slen);
|
||||||
DifferentialChecksum(&pip->ip_sum,
|
DifferentialChecksum(&pip->ip_sum,
|
||||||
&new_len,
|
&new_len,
|
||||||
&pip->ip_len,
|
&pip->ip_len,
|
||||||
1);
|
1);
|
||||||
pip->ip_len = new_len;
|
pip->ip_len = new_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compute TCP checksum for revised packet */
|
/* Compute TCP checksum for revised packet */
|
||||||
tc->th_sum = 0;
|
tc->th_sum = 0;
|
||||||
tc->th_sum = TcpChecksum(pip);
|
tc->th_sum = TcpChecksum(pip);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"PacketAlias/HandleFtpOut: Cannot allocate FTP data port\n");
|
"PacketAlias/HandleFtpOut: Cannot allocate FTP data port\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,277 +65,305 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
AliasHandleIrcOut(struct libalias *la,
|
AliasHandleIrcOut(struct libalias *la,
|
||||||
struct ip *pip, /* IP packet to examine */
|
struct ip *pip, /* IP packet to examine */
|
||||||
struct alias_link *link, /* Which link are we on? */
|
struct alias_link *link, /* Which link are we on? */
|
||||||
int maxsize /* Maximum size of IP packet including headers */
|
int maxsize /* Maximum size of IP packet including
|
||||||
)
|
* headers */
|
||||||
|
)
|
||||||
{
|
{
|
||||||
int hlen, tlen, dlen;
|
int hlen, tlen, dlen;
|
||||||
struct in_addr true_addr;
|
struct in_addr true_addr;
|
||||||
u_short true_port;
|
u_short true_port;
|
||||||
char *sptr;
|
char *sptr;
|
||||||
struct tcphdr *tc;
|
struct tcphdr *tc;
|
||||||
int i; /* Iterator through the source */
|
int i; /* Iterator through the source */
|
||||||
|
|
||||||
/* Calculate data length of TCP packet */
|
/* Calculate data length of TCP packet */
|
||||||
tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
|
tc = (struct tcphdr *)((char *)pip + (pip->ip_hl << 2));
|
||||||
hlen = (pip->ip_hl + tc->th_off) << 2;
|
hlen = (pip->ip_hl + tc->th_off) << 2;
|
||||||
tlen = ntohs(pip->ip_len);
|
tlen = ntohs(pip->ip_len);
|
||||||
dlen = tlen - hlen;
|
dlen = tlen - hlen;
|
||||||
|
|
||||||
/* Return if data length is too short - assume an entire PRIVMSG in each packet. */
|
/*
|
||||||
if (dlen<sizeof(":A!a@n.n PRIVMSG A :aDCC 1 1a")-1)
|
* Return if data length is too short - assume an entire PRIVMSG in
|
||||||
return;
|
* each packet.
|
||||||
|
*/
|
||||||
|
if (dlen < sizeof(":A!a@n.n PRIVMSG A :aDCC 1 1a") - 1)
|
||||||
|
return;
|
||||||
|
|
||||||
/* Place string pointer at beginning of data */
|
/* Place string pointer at beginning of data */
|
||||||
sptr = (char *) pip;
|
sptr = (char *)pip;
|
||||||
sptr += hlen;
|
sptr += hlen;
|
||||||
maxsize -= hlen; /* We're interested in maximum size of data, not packet */
|
maxsize -= hlen; /* We're interested in maximum size of
|
||||||
|
* data, not packet */
|
||||||
|
|
||||||
/* Search for a CTCP command [Note 1] */
|
/* Search for a CTCP command [Note 1] */
|
||||||
for( i=0; i<dlen; i++ ) {
|
for (i = 0; i < dlen; i++) {
|
||||||
if(sptr[i]=='\001')
|
if (sptr[i] == '\001')
|
||||||
goto lFOUND_CTCP;
|
goto lFOUND_CTCP;
|
||||||
}
|
}
|
||||||
return; /* No CTCP commands in */
|
return; /* No CTCP commands in */
|
||||||
/* Handle CTCP commands - the buffer may have to be copied */
|
/* Handle CTCP commands - the buffer may have to be copied */
|
||||||
lFOUND_CTCP:
|
lFOUND_CTCP:
|
||||||
{
|
{
|
||||||
char newpacket[65536]; /* Estimate of maximum packet size :) */
|
char newpacket[65536]; /* Estimate of maximum packet size
|
||||||
int copyat = i; /* Same */
|
* :) */
|
||||||
int iCopy = 0; /* How much data have we written to copy-back string? */
|
int copyat = i; /* Same */
|
||||||
unsigned long org_addr; /* Original IP address */
|
int iCopy = 0; /* How much data have we written to
|
||||||
unsigned short org_port; /* Original source port address */
|
* copy-back string? */
|
||||||
lCTCP_START:
|
unsigned long org_addr; /* Original IP address */
|
||||||
if( i >= dlen || iCopy >= sizeof(newpacket) )
|
unsigned short org_port; /* Original source port
|
||||||
goto lPACKET_DONE;
|
* address */
|
||||||
newpacket[iCopy++] = sptr[i++]; /* Copy the CTCP start character */
|
|
||||||
/* Start of a CTCP */
|
|
||||||
if( i+4 >= dlen ) /* Too short for DCC */
|
|
||||||
goto lBAD_CTCP;
|
|
||||||
if( sptr[i+0] != 'D' )
|
|
||||||
goto lBAD_CTCP;
|
|
||||||
if( sptr[i+1] != 'C' )
|
|
||||||
goto lBAD_CTCP;
|
|
||||||
if( sptr[i+2] != 'C' )
|
|
||||||
goto lBAD_CTCP;
|
|
||||||
if( sptr[i+3] != ' ' )
|
|
||||||
goto lBAD_CTCP;
|
|
||||||
/* We have a DCC command - handle it! */
|
|
||||||
i+= 4; /* Skip "DCC " */
|
|
||||||
if( iCopy+4 > sizeof(newpacket) )
|
|
||||||
goto lPACKET_DONE;
|
|
||||||
newpacket[iCopy++] = 'D';
|
|
||||||
newpacket[iCopy++] = 'C';
|
|
||||||
newpacket[iCopy++] = 'C';
|
|
||||||
newpacket[iCopy++] = ' ';
|
|
||||||
|
|
||||||
DBprintf(("Found DCC\n"));
|
lCTCP_START:
|
||||||
/* Skip any extra spaces (should not occur according to
|
if (i >= dlen || iCopy >= sizeof(newpacket))
|
||||||
protocol, but DCC breaks CTCP protocol anyway */
|
goto lPACKET_DONE;
|
||||||
while(sptr[i] == ' ') {
|
newpacket[iCopy++] = sptr[i++]; /* Copy the CTCP start
|
||||||
if( ++i >= dlen) {
|
* character */
|
||||||
DBprintf(("DCC packet terminated in just spaces\n"));
|
/* Start of a CTCP */
|
||||||
goto lPACKET_DONE;
|
if (i + 4 >= dlen) /* Too short for DCC */
|
||||||
}
|
goto lBAD_CTCP;
|
||||||
}
|
if (sptr[i + 0] != 'D')
|
||||||
|
goto lBAD_CTCP;
|
||||||
|
if (sptr[i + 1] != 'C')
|
||||||
|
goto lBAD_CTCP;
|
||||||
|
if (sptr[i + 2] != 'C')
|
||||||
|
goto lBAD_CTCP;
|
||||||
|
if (sptr[i + 3] != ' ')
|
||||||
|
goto lBAD_CTCP;
|
||||||
|
/* We have a DCC command - handle it! */
|
||||||
|
i += 4; /* Skip "DCC " */
|
||||||
|
if (iCopy + 4 > sizeof(newpacket))
|
||||||
|
goto lPACKET_DONE;
|
||||||
|
newpacket[iCopy++] = 'D';
|
||||||
|
newpacket[iCopy++] = 'C';
|
||||||
|
newpacket[iCopy++] = 'C';
|
||||||
|
newpacket[iCopy++] = ' ';
|
||||||
|
|
||||||
DBprintf(("Transferring command...\n"));
|
DBprintf(("Found DCC\n"));
|
||||||
while(sptr[i] != ' ') {
|
/*
|
||||||
newpacket[iCopy++] = sptr[i];
|
* Skip any extra spaces (should not occur according to
|
||||||
if( ++i >= dlen || iCopy >= sizeof(newpacket) ) {
|
* protocol, but DCC breaks CTCP protocol anyway
|
||||||
DBprintf(("DCC packet terminated during command\n"));
|
*/
|
||||||
goto lPACKET_DONE;
|
while (sptr[i] == ' ') {
|
||||||
}
|
if (++i >= dlen) {
|
||||||
}
|
DBprintf(("DCC packet terminated in just spaces\n"));
|
||||||
/* Copy _one_ space */
|
goto lPACKET_DONE;
|
||||||
if( i+1 < dlen && iCopy < sizeof(newpacket) )
|
}
|
||||||
newpacket[iCopy++] = sptr[i++];
|
}
|
||||||
|
|
||||||
DBprintf(("Done command - removing spaces\n"));
|
DBprintf(("Transferring command...\n"));
|
||||||
/* Skip any extra spaces (should not occur according to
|
while (sptr[i] != ' ') {
|
||||||
protocol, but DCC breaks CTCP protocol anyway */
|
newpacket[iCopy++] = sptr[i];
|
||||||
while(sptr[i] == ' ') {
|
if (++i >= dlen || iCopy >= sizeof(newpacket)) {
|
||||||
if( ++i >= dlen ) {
|
DBprintf(("DCC packet terminated during command\n"));
|
||||||
DBprintf(("DCC packet terminated in just spaces (post-command)\n"));
|
goto lPACKET_DONE;
|
||||||
goto lPACKET_DONE;
|
}
|
||||||
}
|
}
|
||||||
}
|
/* Copy _one_ space */
|
||||||
|
if (i + 1 < dlen && iCopy < sizeof(newpacket))
|
||||||
|
newpacket[iCopy++] = sptr[i++];
|
||||||
|
|
||||||
DBprintf(("Transferring filename...\n"));
|
DBprintf(("Done command - removing spaces\n"));
|
||||||
while(sptr[i] != ' ') {
|
/*
|
||||||
newpacket[iCopy++] = sptr[i];
|
* Skip any extra spaces (should not occur according to
|
||||||
if( ++i >= dlen || iCopy >= sizeof(newpacket) ) {
|
* protocol, but DCC breaks CTCP protocol anyway
|
||||||
DBprintf(("DCC packet terminated during filename\n"));
|
*/
|
||||||
goto lPACKET_DONE;
|
while (sptr[i] == ' ') {
|
||||||
}
|
if (++i >= dlen) {
|
||||||
}
|
DBprintf(("DCC packet terminated in just spaces (post-command)\n"));
|
||||||
/* Copy _one_ space */
|
goto lPACKET_DONE;
|
||||||
if( i+1 < dlen && iCopy < sizeof(newpacket) )
|
}
|
||||||
newpacket[iCopy++] = sptr[i++];
|
}
|
||||||
|
|
||||||
DBprintf(("Done filename - removing spaces\n"));
|
DBprintf(("Transferring filename...\n"));
|
||||||
/* Skip any extra spaces (should not occur according to
|
while (sptr[i] != ' ') {
|
||||||
protocol, but DCC breaks CTCP protocol anyway */
|
newpacket[iCopy++] = sptr[i];
|
||||||
while(sptr[i] == ' ') {
|
if (++i >= dlen || iCopy >= sizeof(newpacket)) {
|
||||||
if( ++i >= dlen ) {
|
DBprintf(("DCC packet terminated during filename\n"));
|
||||||
DBprintf(("DCC packet terminated in just spaces (post-filename)\n"));
|
goto lPACKET_DONE;
|
||||||
goto lPACKET_DONE;
|
}
|
||||||
}
|
}
|
||||||
}
|
/* Copy _one_ space */
|
||||||
|
if (i + 1 < dlen && iCopy < sizeof(newpacket))
|
||||||
|
newpacket[iCopy++] = sptr[i++];
|
||||||
|
|
||||||
DBprintf(("Fetching IP address\n"));
|
DBprintf(("Done filename - removing spaces\n"));
|
||||||
/* Fetch IP address */
|
/*
|
||||||
org_addr = 0;
|
* Skip any extra spaces (should not occur according to
|
||||||
while(i<dlen && isdigit(sptr[i])) {
|
* protocol, but DCC breaks CTCP protocol anyway
|
||||||
if( org_addr > ULONG_MAX/10UL ) { /* Terminate on overflow */
|
*/
|
||||||
DBprintf(("DCC Address overflow (org_addr == 0x%08lx, next char %c\n", org_addr, sptr[i]));
|
while (sptr[i] == ' ') {
|
||||||
goto lBAD_CTCP;
|
if (++i >= dlen) {
|
||||||
}
|
DBprintf(("DCC packet terminated in just spaces (post-filename)\n"));
|
||||||
org_addr *= 10;
|
goto lPACKET_DONE;
|
||||||
org_addr += sptr[i++]-'0';
|
}
|
||||||
}
|
}
|
||||||
DBprintf(("Skipping space\n"));
|
|
||||||
if( i+1 >= dlen || sptr[i] != ' ' ) {
|
|
||||||
DBprintf(("Overflow (%d >= %d) or bad character (%02x) terminating IP address\n", i+1, dlen, sptr[i]));
|
|
||||||
goto lBAD_CTCP;
|
|
||||||
}
|
|
||||||
/* Skip any extra spaces (should not occur according to
|
|
||||||
protocol, but DCC breaks CTCP protocol anyway, so we might
|
|
||||||
as well play it safe */
|
|
||||||
while(sptr[i] == ' ') {
|
|
||||||
if( ++i >= dlen ) {
|
|
||||||
DBprintf(("Packet failure - space overflow.\n"));
|
|
||||||
goto lPACKET_DONE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DBprintf(("Fetching port number\n"));
|
|
||||||
/* Fetch source port */
|
|
||||||
org_port = 0;
|
|
||||||
while(i<dlen && isdigit(sptr[i])) {
|
|
||||||
if( org_port > 6554 ) { /* Terminate on overflow (65536/10 rounded up*/
|
|
||||||
DBprintf(("DCC: port number overflow\n"));
|
|
||||||
goto lBAD_CTCP;
|
|
||||||
}
|
|
||||||
org_port *= 10;
|
|
||||||
org_port += sptr[i++]-'0';
|
|
||||||
}
|
|
||||||
/* Skip illegal addresses (or early termination) */
|
|
||||||
if( i >= dlen || (sptr[i] != '\001' && sptr[i] != ' ') ) {
|
|
||||||
DBprintf(("Bad port termination\n"));
|
|
||||||
goto lBAD_CTCP;
|
|
||||||
}
|
|
||||||
DBprintf(("Got IP %lu and port %u\n", org_addr, (unsigned)org_port));
|
|
||||||
|
|
||||||
/* We've got the address and port - now alias it */
|
DBprintf(("Fetching IP address\n"));
|
||||||
{
|
/* Fetch IP address */
|
||||||
struct alias_link *dcc_link;
|
org_addr = 0;
|
||||||
struct in_addr destaddr;
|
while (i < dlen && isdigit(sptr[i])) {
|
||||||
|
if (org_addr > ULONG_MAX / 10UL) { /* Terminate on overflow */
|
||||||
|
DBprintf(("DCC Address overflow (org_addr == 0x%08lx, next char %c\n", org_addr, sptr[i]));
|
||||||
|
goto lBAD_CTCP;
|
||||||
|
}
|
||||||
|
org_addr *= 10;
|
||||||
|
org_addr += sptr[i++] - '0';
|
||||||
|
}
|
||||||
|
DBprintf(("Skipping space\n"));
|
||||||
|
if (i + 1 >= dlen || sptr[i] != ' ') {
|
||||||
|
DBprintf(("Overflow (%d >= %d) or bad character (%02x) terminating IP address\n", i + 1, dlen, sptr[i]));
|
||||||
|
goto lBAD_CTCP;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Skip any extra spaces (should not occur according to
|
||||||
|
* protocol, but DCC breaks CTCP protocol anyway, so we
|
||||||
|
* might as well play it safe
|
||||||
|
*/
|
||||||
|
while (sptr[i] == ' ') {
|
||||||
|
if (++i >= dlen) {
|
||||||
|
DBprintf(("Packet failure - space overflow.\n"));
|
||||||
|
goto lPACKET_DONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DBprintf(("Fetching port number\n"));
|
||||||
|
/* Fetch source port */
|
||||||
|
org_port = 0;
|
||||||
|
while (i < dlen && isdigit(sptr[i])) {
|
||||||
|
if (org_port > 6554) { /* Terminate on overflow
|
||||||
|
* (65536/10 rounded up */
|
||||||
|
DBprintf(("DCC: port number overflow\n"));
|
||||||
|
goto lBAD_CTCP;
|
||||||
|
}
|
||||||
|
org_port *= 10;
|
||||||
|
org_port += sptr[i++] - '0';
|
||||||
|
}
|
||||||
|
/* Skip illegal addresses (or early termination) */
|
||||||
|
if (i >= dlen || (sptr[i] != '\001' && sptr[i] != ' ')) {
|
||||||
|
DBprintf(("Bad port termination\n"));
|
||||||
|
goto lBAD_CTCP;
|
||||||
|
}
|
||||||
|
DBprintf(("Got IP %lu and port %u\n", org_addr, (unsigned)org_port));
|
||||||
|
|
||||||
|
/* We've got the address and port - now alias it */
|
||||||
|
{
|
||||||
|
struct alias_link *dcc_link;
|
||||||
|
struct in_addr destaddr;
|
||||||
|
|
||||||
|
|
||||||
true_port = htons(org_port);
|
true_port = htons(org_port);
|
||||||
true_addr.s_addr = htonl(org_addr);
|
true_addr.s_addr = htonl(org_addr);
|
||||||
destaddr.s_addr = 0;
|
destaddr.s_addr = 0;
|
||||||
|
|
||||||
/* Sanity/Security checking */
|
/* Sanity/Security checking */
|
||||||
if (!org_addr || !org_port ||
|
if (!org_addr || !org_port ||
|
||||||
pip->ip_src.s_addr != true_addr.s_addr ||
|
pip->ip_src.s_addr != true_addr.s_addr ||
|
||||||
org_port < IPPORT_RESERVED)
|
org_port < IPPORT_RESERVED)
|
||||||
goto lBAD_CTCP;
|
goto lBAD_CTCP;
|
||||||
|
|
||||||
/* Steal the FTP_DATA_PORT - it doesn't really matter, and this
|
/*
|
||||||
would probably allow it through at least _some_
|
* Steal the FTP_DATA_PORT - it doesn't really
|
||||||
firewalls. */
|
* matter, and this would probably allow it through
|
||||||
dcc_link = FindUdpTcpOut(la, true_addr, destaddr,
|
* at least _some_ firewalls.
|
||||||
true_port, 0,
|
*/
|
||||||
IPPROTO_TCP, 1);
|
dcc_link = FindUdpTcpOut(la, true_addr, destaddr,
|
||||||
DBprintf(("Got a DCC link\n"));
|
true_port, 0,
|
||||||
if ( dcc_link ) {
|
IPPROTO_TCP, 1);
|
||||||
struct in_addr alias_address; /* Address from aliasing */
|
DBprintf(("Got a DCC link\n"));
|
||||||
u_short alias_port; /* Port given by aliasing */
|
if (dcc_link) {
|
||||||
int n;
|
struct in_addr alias_address; /* Address from aliasing */
|
||||||
|
u_short alias_port; /* Port given by
|
||||||
|
* aliasing */
|
||||||
|
int n;
|
||||||
|
|
||||||
#ifndef NO_FW_PUNCH
|
#ifndef NO_FW_PUNCH
|
||||||
/* Generate firewall hole as appropriate */
|
/* Generate firewall hole as appropriate */
|
||||||
PunchFWHole(dcc_link);
|
PunchFWHole(dcc_link);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
alias_address = GetAliasAddress(link);
|
alias_address = GetAliasAddress(link);
|
||||||
n = snprintf(&newpacket[iCopy],
|
n = snprintf(&newpacket[iCopy],
|
||||||
sizeof(newpacket)-iCopy,
|
sizeof(newpacket) - iCopy,
|
||||||
"%lu ", (u_long)htonl(alias_address.s_addr));
|
"%lu ", (u_long) htonl(alias_address.s_addr));
|
||||||
if( n < 0 ) {
|
if (n < 0) {
|
||||||
DBprintf(("DCC packet construct failure.\n"));
|
DBprintf(("DCC packet construct failure.\n"));
|
||||||
goto lBAD_CTCP;
|
goto lBAD_CTCP;
|
||||||
}
|
}
|
||||||
if( (iCopy += n) >= sizeof(newpacket) ) { /* Truncated/fit exactly - bad news */
|
if ((iCopy += n) >= sizeof(newpacket)) { /* Truncated/fit exactly
|
||||||
DBprintf(("DCC constructed packet overflow.\n"));
|
* - bad news */
|
||||||
goto lBAD_CTCP;
|
DBprintf(("DCC constructed packet overflow.\n"));
|
||||||
}
|
goto lBAD_CTCP;
|
||||||
alias_port = GetAliasPort(dcc_link);
|
}
|
||||||
n = snprintf(&newpacket[iCopy],
|
alias_port = GetAliasPort(dcc_link);
|
||||||
sizeof(newpacket)-iCopy,
|
n = snprintf(&newpacket[iCopy],
|
||||||
"%u", htons(alias_port) );
|
sizeof(newpacket) - iCopy,
|
||||||
if( n < 0 ) {
|
"%u", htons(alias_port));
|
||||||
DBprintf(("DCC packet construct failure.\n"));
|
if (n < 0) {
|
||||||
goto lBAD_CTCP;
|
DBprintf(("DCC packet construct failure.\n"));
|
||||||
}
|
goto lBAD_CTCP;
|
||||||
iCopy += n;
|
}
|
||||||
/* Done - truncated cases will be taken care of by lBAD_CTCP */
|
iCopy += n;
|
||||||
DBprintf(("Aliased IP %lu and port %u\n", alias_address.s_addr, (unsigned)alias_port));
|
/*
|
||||||
}
|
* Done - truncated cases will be taken
|
||||||
}
|
* care of by lBAD_CTCP
|
||||||
/* An uninteresting CTCP - state entered right after '\001' has
|
*/
|
||||||
been pushed. Also used to copy the rest of a DCC, after IP
|
DBprintf(("Aliased IP %lu and port %u\n", alias_address.s_addr, (unsigned)alias_port));
|
||||||
address and port has been handled */
|
}
|
||||||
lBAD_CTCP:
|
}
|
||||||
for(; i<dlen && iCopy<sizeof(newpacket); i++,iCopy++) {
|
/*
|
||||||
newpacket[iCopy] = sptr[i]; /* Copy CTCP unchanged */
|
* An uninteresting CTCP - state entered right after '\001'
|
||||||
if(sptr[i] == '\001') {
|
* has been pushed. Also used to copy the rest of a DCC,
|
||||||
goto lNORMAL_TEXT;
|
* after IP address and port has been handled
|
||||||
}
|
*/
|
||||||
}
|
lBAD_CTCP:
|
||||||
goto lPACKET_DONE;
|
for (; i < dlen && iCopy < sizeof(newpacket); i++, iCopy++) {
|
||||||
/* Normal text */
|
newpacket[iCopy] = sptr[i]; /* Copy CTCP unchanged */
|
||||||
lNORMAL_TEXT:
|
if (sptr[i] == '\001') {
|
||||||
for(; i<dlen && iCopy<sizeof(newpacket); i++,iCopy++) {
|
goto lNORMAL_TEXT;
|
||||||
newpacket[iCopy] = sptr[i]; /* Copy CTCP unchanged */
|
}
|
||||||
if(sptr[i] == '\001') {
|
}
|
||||||
goto lCTCP_START;
|
goto lPACKET_DONE;
|
||||||
}
|
/* Normal text */
|
||||||
}
|
lNORMAL_TEXT:
|
||||||
/* Handle the end of a packet */
|
for (; i < dlen && iCopy < sizeof(newpacket); i++, iCopy++) {
|
||||||
lPACKET_DONE:
|
newpacket[iCopy] = sptr[i]; /* Copy CTCP unchanged */
|
||||||
iCopy = iCopy > maxsize-copyat ? maxsize-copyat : iCopy;
|
if (sptr[i] == '\001') {
|
||||||
memcpy(sptr+copyat, newpacket, iCopy);
|
goto lCTCP_START;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Handle the end of a packet */
|
||||||
|
lPACKET_DONE:
|
||||||
|
iCopy = iCopy > maxsize - copyat ? maxsize - copyat : iCopy;
|
||||||
|
memcpy(sptr + copyat, newpacket, iCopy);
|
||||||
|
|
||||||
/* Save information regarding modified seq and ack numbers */
|
/* Save information regarding modified seq and ack numbers */
|
||||||
{
|
{
|
||||||
int delta;
|
int delta;
|
||||||
|
|
||||||
SetAckModified(link);
|
SetAckModified(link);
|
||||||
delta = GetDeltaSeqOut(pip, link);
|
delta = GetDeltaSeqOut(pip, link);
|
||||||
AddSeq(pip, link, delta+copyat+iCopy-dlen);
|
AddSeq(pip, link, delta + copyat + iCopy - dlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Revise IP header */
|
/* Revise IP header */
|
||||||
{
|
{
|
||||||
u_short new_len;
|
u_short new_len;
|
||||||
|
|
||||||
new_len = htons(hlen + iCopy + copyat);
|
new_len = htons(hlen + iCopy + copyat);
|
||||||
DifferentialChecksum(&pip->ip_sum,
|
DifferentialChecksum(&pip->ip_sum,
|
||||||
&new_len,
|
&new_len,
|
||||||
&pip->ip_len,
|
&pip->ip_len,
|
||||||
1);
|
1);
|
||||||
pip->ip_len = new_len;
|
pip->ip_len = new_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compute TCP checksum for revised packet */
|
/* Compute TCP checksum for revised packet */
|
||||||
tc->th_sum = 0;
|
tc->th_sum = 0;
|
||||||
tc->th_sum = TcpChecksum(pip);
|
tc->th_sum = TcpChecksum(pip);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Notes:
|
/* Notes:
|
||||||
|
@ -55,80 +55,84 @@
|
|||||||
struct proxy_entry;
|
struct proxy_entry;
|
||||||
|
|
||||||
struct libalias {
|
struct libalias {
|
||||||
LIST_ENTRY(libalias) instancelist;
|
LIST_ENTRY(libalias) instancelist;
|
||||||
|
|
||||||
int packetAliasMode; /* Mode flags */
|
int packetAliasMode; /* Mode flags */
|
||||||
/* - documented in alias.h */
|
/* - documented in alias.h */
|
||||||
|
|
||||||
struct in_addr aliasAddress; /* Address written onto source */
|
struct in_addr aliasAddress; /* Address written onto source */
|
||||||
/* field of IP packet. */
|
/* field of IP packet. */
|
||||||
|
|
||||||
struct in_addr targetAddress; /* IP address incoming packets */
|
struct in_addr targetAddress; /* IP address incoming packets */
|
||||||
/* are sent to if no aliasing */
|
/* are sent to if no aliasing */
|
||||||
/* link already exists */
|
/* link already exists */
|
||||||
|
|
||||||
struct in_addr nullAddress; /* Used as a dummy parameter for */
|
struct in_addr nullAddress; /* Used as a dummy parameter for */
|
||||||
/* some function calls */
|
/* some function calls */
|
||||||
|
|
||||||
LIST_HEAD(, alias_link) linkTableOut[LINK_TABLE_OUT_SIZE];
|
LIST_HEAD (, alias_link) linkTableOut[LINK_TABLE_OUT_SIZE];
|
||||||
/* Lookup table of pointers to */
|
/* Lookup table of pointers to */
|
||||||
/* chains of link records. Each */
|
/* chains of link records. Each */
|
||||||
|
|
||||||
LIST_HEAD(, alias_link) linkTableIn[LINK_TABLE_IN_SIZE];
|
LIST_HEAD (, alias_link) linkTableIn[LINK_TABLE_IN_SIZE];
|
||||||
/* link record is doubly indexed */
|
/* link record is doubly indexed */
|
||||||
/* into input and output lookup */
|
/* into input and output lookup */
|
||||||
/* tables. */
|
/* tables. */
|
||||||
|
|
||||||
/* Link statistics */
|
/* Link statistics */
|
||||||
int icmpLinkCount;
|
int icmpLinkCount;
|
||||||
int udpLinkCount;
|
int udpLinkCount;
|
||||||
int tcpLinkCount;
|
int tcpLinkCount;
|
||||||
int pptpLinkCount;
|
int pptpLinkCount;
|
||||||
int protoLinkCount;
|
int protoLinkCount;
|
||||||
int fragmentIdLinkCount;
|
int fragmentIdLinkCount;
|
||||||
int fragmentPtrLinkCount;
|
int fragmentPtrLinkCount;
|
||||||
int sockCount;
|
int sockCount;
|
||||||
|
|
||||||
int cleanupIndex; /* Index to chain of link table */
|
int cleanupIndex; /* Index to chain of link table */
|
||||||
/* being inspected for old links */
|
/* being inspected for old links */
|
||||||
|
|
||||||
int timeStamp; /* System time in seconds for */
|
int timeStamp; /* System time in seconds for */
|
||||||
/* current packet */
|
/* current packet */
|
||||||
|
|
||||||
int lastCleanupTime; /* Last time IncrementalCleanup() */
|
int lastCleanupTime; /* Last time
|
||||||
/* was called */
|
* IncrementalCleanup() */
|
||||||
|
/* was called */
|
||||||
|
|
||||||
int houseKeepingResidual; /* used by HouseKeeping() */
|
int houseKeepingResidual; /* used by HouseKeeping() */
|
||||||
|
|
||||||
int deleteAllLinks; /* If equal to zero, DeleteLink() */
|
int deleteAllLinks; /* If equal to zero, DeleteLink() */
|
||||||
/* will not remove permanent links */
|
/* will not remove permanent links */
|
||||||
|
|
||||||
FILE *monitorFile; /* File descriptor for link */
|
FILE *monitorFile; /* File descriptor for link */
|
||||||
/* statistics monitoring file */
|
/* statistics monitoring file */
|
||||||
|
|
||||||
int newDefaultLink; /* Indicates if a new aliasing */
|
int newDefaultLink; /* Indicates if a new aliasing */
|
||||||
/* link has been created after a */
|
/* link has been created after a */
|
||||||
/* call to PacketAliasIn/Out(). */
|
/* call to PacketAliasIn/Out(). */
|
||||||
|
|
||||||
#ifndef NO_FW_PUNCH
|
#ifndef NO_FW_PUNCH
|
||||||
int fireWallFD; /* File descriptor to be able to */
|
int fireWallFD; /* File descriptor to be able to */
|
||||||
/* control firewall. Opened by */
|
/* control firewall. Opened by */
|
||||||
/* PacketAliasSetMode on first */
|
/* PacketAliasSetMode on first */
|
||||||
/* setting the PKT_ALIAS_PUNCH_FW */
|
/* setting the PKT_ALIAS_PUNCH_FW */
|
||||||
/* flag. */
|
/* flag. */
|
||||||
int fireWallBaseNum; /* The first firewall entry free for our use */
|
int fireWallBaseNum; /* The first firewall entry
|
||||||
int fireWallNumNums; /* How many entries can we use? */
|
* free for our use */
|
||||||
int fireWallActiveNum; /* Which entry did we last use? */
|
int fireWallNumNums; /* How many entries can we
|
||||||
char *fireWallField; /* bool array for entries */
|
* use? */
|
||||||
|
int fireWallActiveNum; /* Which entry did we last
|
||||||
|
* use? */
|
||||||
|
char *fireWallField; /* bool array for entries */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
unsigned int skinnyPort; /* TCP port used by the Skinny */
|
unsigned int skinnyPort; /* TCP port used by the Skinny */
|
||||||
/* protocol. */
|
/* protocol. */
|
||||||
|
|
||||||
struct proxy_entry *proxyList;
|
struct proxy_entry *proxyList;
|
||||||
|
|
||||||
struct in_addr true_addr; /* in network byte order. */
|
struct in_addr true_addr; /* in network byte order. */
|
||||||
u_short true_port; /* in host byte order. */
|
u_short true_port; /* in host byte order. */
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -161,148 +165,159 @@ struct libalias {
|
|||||||
/* Prototypes */
|
/* Prototypes */
|
||||||
|
|
||||||
/* General utilities */
|
/* General utilities */
|
||||||
u_short IpChecksum(struct ip *_pip);
|
u_short IpChecksum(struct ip *_pip);
|
||||||
u_short TcpChecksum(struct ip *_pip);
|
u_short TcpChecksum(struct ip *_pip);
|
||||||
void DifferentialChecksum(u_short *_cksum, u_short *_new, u_short *_old,
|
void
|
||||||
int _n);
|
DifferentialChecksum(u_short * _cksum, u_short * _new, u_short * _old,
|
||||||
|
int _n);
|
||||||
|
|
||||||
/* Internal data access */
|
/* Internal data access */
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
FindIcmpIn(struct libalias *la, struct in_addr _dst_addr, struct in_addr _alias_addr,
|
FindIcmpIn(struct libalias *la, struct in_addr _dst_addr, struct in_addr _alias_addr,
|
||||||
u_short _id_alias, int _create);
|
u_short _id_alias, int _create);
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
FindIcmpOut(struct libalias *la, struct in_addr _src_addr, struct in_addr _dst_addr,
|
FindIcmpOut(struct libalias *la, struct in_addr _src_addr, struct in_addr _dst_addr,
|
||||||
u_short _id, int _create);
|
u_short _id, int _create);
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
FindFragmentIn1(struct libalias *la, struct in_addr _dst_addr, struct in_addr _alias_addr,
|
FindFragmentIn1(struct libalias *la, struct in_addr _dst_addr, struct in_addr _alias_addr,
|
||||||
u_short _ip_id);
|
u_short _ip_id);
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
FindFragmentIn2(struct libalias *la, struct in_addr _dst_addr, struct in_addr _alias_addr,
|
FindFragmentIn2(struct libalias *la, struct in_addr _dst_addr, struct in_addr _alias_addr,
|
||||||
u_short _ip_id);
|
u_short _ip_id);
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
AddFragmentPtrLink(struct libalias *la, struct in_addr _dst_addr, u_short _ip_id);
|
AddFragmentPtrLink(struct libalias *la, struct in_addr _dst_addr, u_short _ip_id);
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
FindFragmentPtr(struct libalias *la, struct in_addr _dst_addr, u_short _ip_id);
|
FindFragmentPtr(struct libalias *la, struct in_addr _dst_addr, u_short _ip_id);
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
FindProtoIn(struct libalias *la, struct in_addr _dst_addr, struct in_addr _alias_addr,
|
FindProtoIn(struct libalias *la, struct in_addr _dst_addr, struct in_addr _alias_addr,
|
||||||
u_char _proto);
|
u_char _proto);
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
FindProtoOut(struct libalias *la, struct in_addr _src_addr, struct in_addr _dst_addr,
|
FindProtoOut(struct libalias *la, struct in_addr _src_addr, struct in_addr _dst_addr,
|
||||||
u_char _proto);
|
u_char _proto);
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
FindUdpTcpIn(struct libalias *la, struct in_addr _dst_addr, struct in_addr _alias_addr,
|
FindUdpTcpIn(struct libalias *la, struct in_addr _dst_addr, struct in_addr _alias_addr,
|
||||||
u_short _dst_port, u_short _alias_port, u_char _proto, int _create);
|
u_short _dst_port, u_short _alias_port, u_char _proto, int _create);
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
FindUdpTcpOut(struct libalias *la, struct in_addr _src_addr, struct in_addr _dst_addr,
|
FindUdpTcpOut(struct libalias *la, struct in_addr _src_addr, struct in_addr _dst_addr,
|
||||||
u_short _src_port, u_short _dst_port, u_char _proto, int _create);
|
u_short _src_port, u_short _dst_port, u_char _proto, int _create);
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
AddPptp(struct libalias *la, struct in_addr _src_addr, struct in_addr _dst_addr,
|
AddPptp(struct libalias *la, struct in_addr _src_addr, struct in_addr _dst_addr,
|
||||||
struct in_addr _alias_addr, u_int16_t _src_call_id);
|
struct in_addr _alias_addr, u_int16_t _src_call_id);
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
FindPptpOutByCallId(struct libalias *la, struct in_addr _src_addr,
|
FindPptpOutByCallId(struct libalias *la, struct in_addr _src_addr,
|
||||||
struct in_addr _dst_addr, u_int16_t _src_call_id);
|
struct in_addr _dst_addr, u_int16_t _src_call_id);
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
FindPptpInByCallId(struct libalias *la, struct in_addr _dst_addr,
|
FindPptpInByCallId(struct libalias *la, struct in_addr _dst_addr,
|
||||||
struct in_addr _alias_addr, u_int16_t _dst_call_id);
|
struct in_addr _alias_addr, u_int16_t _dst_call_id);
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
FindPptpOutByPeerCallId(struct libalias *la, struct in_addr _src_addr,
|
FindPptpOutByPeerCallId(struct libalias *la, struct in_addr _src_addr,
|
||||||
struct in_addr _dst_addr, u_int16_t _dst_call_id);
|
struct in_addr _dst_addr, u_int16_t _dst_call_id);
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
FindPptpInByPeerCallId(struct libalias *la, struct in_addr _dst_addr,
|
FindPptpInByPeerCallId(struct libalias *la, struct in_addr _dst_addr,
|
||||||
struct in_addr _alias_addr, u_int16_t _alias_call_id);
|
struct in_addr _alias_addr, u_int16_t _alias_call_id);
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
FindRtspOut(struct libalias *la, struct in_addr _src_addr, struct in_addr _dst_addr,
|
FindRtspOut(struct libalias *la, struct in_addr _src_addr, struct in_addr _dst_addr,
|
||||||
u_short _src_port, u_short _alias_port, u_char _proto);
|
u_short _src_port, u_short _alias_port, u_char _proto);
|
||||||
struct in_addr
|
struct in_addr
|
||||||
FindOriginalAddress(struct libalias *la, struct in_addr _alias_addr);
|
FindOriginalAddress(struct libalias *la, struct in_addr _alias_addr);
|
||||||
struct in_addr
|
struct in_addr
|
||||||
FindAliasAddress(struct libalias *la, struct in_addr _original_addr);
|
FindAliasAddress(struct libalias *la, struct in_addr _original_addr);
|
||||||
|
|
||||||
/* External data access/modification */
|
/* External data access/modification */
|
||||||
int FindNewPortGroup(struct libalias *la, struct in_addr _dst_addr, struct in_addr _alias_addr,
|
int
|
||||||
u_short _src_port, u_short _dst_port, u_short _port_count,
|
FindNewPortGroup(struct libalias *la, struct in_addr _dst_addr, struct in_addr _alias_addr,
|
||||||
u_char _proto, u_char _align);
|
u_short _src_port, u_short _dst_port, u_short _port_count,
|
||||||
void GetFragmentAddr(struct alias_link *_link, struct in_addr *_src_addr);
|
u_char _proto, u_char _align);
|
||||||
void SetFragmentAddr(struct alias_link *_link, struct in_addr _src_addr);
|
void GetFragmentAddr(struct alias_link *_link, struct in_addr *_src_addr);
|
||||||
void GetFragmentPtr(struct alias_link *_link, char **_fptr);
|
void SetFragmentAddr(struct alias_link *_link, struct in_addr _src_addr);
|
||||||
void SetFragmentPtr(struct alias_link *_link, char *fptr);
|
void GetFragmentPtr(struct alias_link *_link, char **_fptr);
|
||||||
void SetStateIn(struct alias_link *_link, int _state);
|
void SetFragmentPtr(struct alias_link *_link, char *fptr);
|
||||||
void SetStateOut(struct alias_link *_link, int _state);
|
void SetStateIn(struct alias_link *_link, int _state);
|
||||||
int GetStateIn(struct alias_link *_link);
|
void SetStateOut(struct alias_link *_link, int _state);
|
||||||
int GetStateOut(struct alias_link *_link);
|
int GetStateIn (struct alias_link *_link);
|
||||||
|
int GetStateOut(struct alias_link *_link);
|
||||||
struct in_addr
|
struct in_addr
|
||||||
GetOriginalAddress(struct alias_link *_link);
|
GetOriginalAddress(struct alias_link *_link);
|
||||||
struct in_addr
|
struct in_addr
|
||||||
GetDestAddress(struct alias_link *_link);
|
GetDestAddress(struct alias_link *_link);
|
||||||
struct in_addr
|
struct in_addr
|
||||||
GetAliasAddress(struct alias_link *_link);
|
GetAliasAddress(struct alias_link *_link);
|
||||||
struct in_addr
|
struct in_addr
|
||||||
GetDefaultAliasAddress(struct libalias *la);
|
GetDefaultAliasAddress(struct libalias *la);
|
||||||
void SetDefaultAliasAddress(struct libalias *la, struct in_addr _alias_addr);
|
void SetDefaultAliasAddress(struct libalias *la, struct in_addr _alias_addr);
|
||||||
u_short GetOriginalPort(struct alias_link *_link);
|
u_short GetOriginalPort(struct alias_link *_link);
|
||||||
u_short GetAliasPort(struct alias_link *_link);
|
u_short GetAliasPort(struct alias_link *_link);
|
||||||
struct in_addr
|
struct in_addr
|
||||||
GetProxyAddress(struct alias_link *_link);
|
GetProxyAddress(struct alias_link *_link);
|
||||||
void SetProxyAddress(struct alias_link *_link, struct in_addr _addr);
|
void SetProxyAddress(struct alias_link *_link, struct in_addr _addr);
|
||||||
u_short GetProxyPort(struct alias_link *_link);
|
u_short GetProxyPort(struct alias_link *_link);
|
||||||
void SetProxyPort(struct alias_link *_link, u_short _port);
|
void SetProxyPort(struct alias_link *_link, u_short _port);
|
||||||
void SetAckModified(struct alias_link *_link);
|
void SetAckModified(struct alias_link *_link);
|
||||||
int GetAckModified(struct alias_link *_link);
|
int GetAckModified(struct alias_link *_link);
|
||||||
int GetDeltaAckIn(struct ip *_pip, struct alias_link *_link);
|
int GetDeltaAckIn(struct ip *_pip, struct alias_link *_link);
|
||||||
int GetDeltaSeqOut(struct ip *_pip, struct alias_link *_link);
|
int GetDeltaSeqOut(struct ip *_pip, struct alias_link *_link);
|
||||||
void AddSeq(struct ip *_pip, struct alias_link *_link, int _delta);
|
void AddSeq (struct ip *_pip, struct alias_link *_link, int _delta);
|
||||||
void SetExpire(struct alias_link *_link, int _expire);
|
void SetExpire (struct alias_link *_link, int _expire);
|
||||||
void ClearCheckNewLink(struct libalias *la);
|
void ClearCheckNewLink(struct libalias *la);
|
||||||
void SetProtocolFlags(struct alias_link *_link, int _pflags);
|
void SetProtocolFlags(struct alias_link *_link, int _pflags);
|
||||||
int GetProtocolFlags(struct alias_link *_link);
|
int GetProtocolFlags(struct alias_link *_link);
|
||||||
void SetDestCallId(struct alias_link *_link, u_int16_t _cid);
|
void SetDestCallId(struct alias_link *_link, u_int16_t _cid);
|
||||||
|
|
||||||
#ifndef NO_FW_PUNCH
|
#ifndef NO_FW_PUNCH
|
||||||
void PunchFWHole(struct alias_link *_link);
|
void PunchFWHole(struct alias_link *_link);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Housekeeping function */
|
/* Housekeeping function */
|
||||||
void HouseKeeping(struct libalias *);
|
void HouseKeeping(struct libalias *);
|
||||||
|
|
||||||
/* Tcp specfic routines */
|
/* Tcp specfic routines */
|
||||||
/* lint -save -library Suppress flexelint warnings */
|
/* lint -save -library Suppress flexelint warnings */
|
||||||
|
|
||||||
/* FTP routines */
|
/* FTP routines */
|
||||||
void AliasHandleFtpOut(struct libalias *la, struct ip *_pip, struct alias_link *_link,
|
void
|
||||||
int _maxpacketsize);
|
AliasHandleFtpOut(struct libalias *la, struct ip *_pip, struct alias_link *_link,
|
||||||
|
int _maxpacketsize);
|
||||||
|
|
||||||
/* IRC routines */
|
/* IRC routines */
|
||||||
void AliasHandleIrcOut(struct libalias *la, struct ip *_pip, struct alias_link *_link,
|
void
|
||||||
int _maxsize);
|
AliasHandleIrcOut(struct libalias *la, struct ip *_pip, struct alias_link *_link,
|
||||||
|
int _maxsize);
|
||||||
|
|
||||||
/* RTSP routines */
|
/* RTSP routines */
|
||||||
void AliasHandleRtspOut(struct libalias *la, struct ip *_pip, struct alias_link *_link,
|
void
|
||||||
int _maxpacketsize);
|
AliasHandleRtspOut(struct libalias *la, struct ip *_pip, struct alias_link *_link,
|
||||||
|
int _maxpacketsize);
|
||||||
|
|
||||||
/* PPTP routines */
|
/* PPTP routines */
|
||||||
void AliasHandlePptpOut(struct libalias *la, struct ip *_pip, struct alias_link *_link);
|
void AliasHandlePptpOut(struct libalias *la, struct ip *_pip, struct alias_link *_link);
|
||||||
void AliasHandlePptpIn(struct libalias *la, struct ip *_pip, struct alias_link *_link);
|
void AliasHandlePptpIn(struct libalias *la, struct ip *_pip, struct alias_link *_link);
|
||||||
int AliasHandlePptpGreOut(struct libalias *la, struct ip *_pip);
|
int AliasHandlePptpGreOut(struct libalias *la, struct ip *_pip);
|
||||||
int AliasHandlePptpGreIn(struct libalias *la, struct ip *_pip);
|
int AliasHandlePptpGreIn(struct libalias *la, struct ip *_pip);
|
||||||
|
|
||||||
/* NetBIOS routines */
|
/* NetBIOS routines */
|
||||||
int AliasHandleUdpNbt(struct libalias *la, struct ip *_pip, struct alias_link *_link,
|
int
|
||||||
struct in_addr *_alias_address, u_short _alias_port);
|
AliasHandleUdpNbt(struct libalias *la, struct ip *_pip, struct alias_link *_link,
|
||||||
int AliasHandleUdpNbtNS(struct libalias *la, struct ip *_pip, struct alias_link *_link,
|
struct in_addr *_alias_address, u_short _alias_port);
|
||||||
struct in_addr *_alias_address, u_short *_alias_port,
|
int
|
||||||
struct in_addr *_original_address, u_short *_original_port);
|
AliasHandleUdpNbtNS(struct libalias *la, struct ip *_pip, struct alias_link *_link,
|
||||||
|
struct in_addr *_alias_address, u_short * _alias_port,
|
||||||
|
struct in_addr *_original_address, u_short * _original_port);
|
||||||
|
|
||||||
/* CUSeeMe routines */
|
/* CUSeeMe routines */
|
||||||
void AliasHandleCUSeeMeOut(struct libalias *la, struct ip *_pip, struct alias_link *_link);
|
void AliasHandleCUSeeMeOut(struct libalias *la, struct ip *_pip, struct alias_link *_link);
|
||||||
void AliasHandleCUSeeMeIn(struct libalias *la, struct ip *_pip, struct in_addr _original_addr);
|
void AliasHandleCUSeeMeIn(struct libalias *la, struct ip *_pip, struct in_addr _original_addr);
|
||||||
|
|
||||||
/* Skinny routines */
|
/* Skinny routines */
|
||||||
void AliasHandleSkinny(struct libalias *la, struct ip *_pip, struct alias_link *_link);
|
void AliasHandleSkinny(struct libalias *la, struct ip *_pip, struct alias_link *_link);
|
||||||
|
|
||||||
/* Transparent proxy routines */
|
/* Transparent proxy routines */
|
||||||
int ProxyCheck(struct libalias *la, struct ip *_pip, struct in_addr *_proxy_server_addr,
|
int
|
||||||
u_short *_proxy_server_port);
|
ProxyCheck(struct libalias *la, struct ip *_pip, struct in_addr *_proxy_server_addr,
|
||||||
void ProxyModify(struct libalias *la, struct alias_link *_link, struct ip *_pip,
|
u_short * _proxy_server_port);
|
||||||
int _maxpacketsize, int _proxy_type);
|
void
|
||||||
|
ProxyModify(struct libalias *la, struct alias_link *_link, struct ip *_pip,
|
||||||
|
int _maxpacketsize, int _proxy_type);
|
||||||
|
|
||||||
enum alias_tcp_state {
|
enum alias_tcp_state {
|
||||||
ALIAS_TCP_STATE_NOT_CONNECTED,
|
ALIAS_TCP_STATE_NOT_CONNECTED,
|
||||||
@ -312,4 +327,4 @@ enum alias_tcp_state {
|
|||||||
|
|
||||||
/*lint -restore */
|
/*lint -restore */
|
||||||
|
|
||||||
#endif /* !_ALIAS_LOCAL_H_ */
|
#endif /* !_ALIAS_LOCAL_H_ */
|
||||||
|
@ -55,22 +55,22 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include "alias_local.h"
|
#include "alias_local.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
struct in_addr oldaddr;
|
struct in_addr oldaddr;
|
||||||
u_short oldport;
|
u_short oldport;
|
||||||
struct in_addr newaddr;
|
struct in_addr newaddr;
|
||||||
u_short newport;
|
u_short newport;
|
||||||
u_short *uh_sum;
|
u_short *uh_sum;
|
||||||
} NBTArguments;
|
} NBTArguments;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned char type;
|
unsigned char type;
|
||||||
unsigned char flags;
|
unsigned char flags;
|
||||||
u_short id;
|
u_short id;
|
||||||
struct in_addr source_ip;
|
struct in_addr source_ip;
|
||||||
u_short source_port;
|
u_short source_port;
|
||||||
u_short len;
|
u_short len;
|
||||||
u_short offset;
|
u_short offset;
|
||||||
} NbtDataHeader;
|
} NbtDataHeader;
|
||||||
|
|
||||||
#define OpQuery 0
|
#define OpQuery 0
|
||||||
#define OpUnknown 4
|
#define OpUnknown 4
|
||||||
@ -79,13 +79,13 @@ typedef struct {
|
|||||||
#define OpWACK 7
|
#define OpWACK 7
|
||||||
#define OpRefresh 8
|
#define OpRefresh 8
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u_short nametrid;
|
u_short nametrid;
|
||||||
u_short dir:1, opcode:4, nmflags:7, rcode:4;
|
u_short dir: 1, opcode:4, nmflags:7, rcode:4;
|
||||||
u_short qdcount;
|
u_short qdcount;
|
||||||
u_short ancount;
|
u_short ancount;
|
||||||
u_short nscount;
|
u_short nscount;
|
||||||
u_short arcount;
|
u_short arcount;
|
||||||
} NbtNSHeader;
|
} NbtNSHeader;
|
||||||
|
|
||||||
#define FMT_ERR 0x1
|
#define FMT_ERR 0x1
|
||||||
#define SRV_ERR 0x2
|
#define SRV_ERR 0x2
|
||||||
@ -96,56 +96,61 @@ typedef struct {
|
|||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
static void PrintRcode( u_char rcode ) {
|
static void
|
||||||
|
PrintRcode(u_char rcode)
|
||||||
|
{
|
||||||
|
|
||||||
switch (rcode) {
|
switch (rcode) {
|
||||||
case FMT_ERR:
|
case FMT_ERR:
|
||||||
printf("\nFormat Error.");
|
printf("\nFormat Error.");
|
||||||
case SRV_ERR:
|
case SRV_ERR:
|
||||||
printf("\nSever failure.");
|
printf("\nSever failure.");
|
||||||
case IMP_ERR:
|
case IMP_ERR:
|
||||||
printf("\nUnsupported request error.\n");
|
printf("\nUnsupported request error.\n");
|
||||||
case RFS_ERR:
|
case RFS_ERR:
|
||||||
printf("\nRefused error.\n");
|
printf("\nRefused error.\n");
|
||||||
case ACT_ERR:
|
case ACT_ERR:
|
||||||
printf("\nActive error.\n");
|
printf("\nActive error.\n");
|
||||||
case CFT_ERR:
|
case CFT_ERR:
|
||||||
printf("\nName in conflict error.\n");
|
printf("\nName in conflict error.\n");
|
||||||
default:
|
default:
|
||||||
printf("\n?%c?=%0x\n", '?', rcode );
|
printf("\n?%c?=%0x\n", '?', rcode);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Handling Name field */
|
/* Handling Name field */
|
||||||
static u_char *AliasHandleName ( u_char *p, char *pmax ) {
|
static u_char *
|
||||||
|
AliasHandleName(u_char * p, char *pmax)
|
||||||
|
{
|
||||||
|
|
||||||
u_char *s;
|
u_char *s;
|
||||||
u_char c;
|
u_char c;
|
||||||
int compress;
|
int compress;
|
||||||
|
|
||||||
/* Following length field */
|
/* Following length field */
|
||||||
|
|
||||||
if (p == NULL || (char *)p >= pmax)
|
if (p == NULL || (char *)p >= pmax)
|
||||||
return(NULL);
|
return (NULL);
|
||||||
|
|
||||||
if (*p & 0xc0 ) {
|
if (*p & 0xc0) {
|
||||||
p = p + 2;
|
p = p + 2;
|
||||||
if ((char *)p > pmax)
|
if ((char *)p > pmax)
|
||||||
return(NULL);
|
return (NULL);
|
||||||
return ((u_char *)p);
|
return ((u_char *) p);
|
||||||
}
|
}
|
||||||
while ( ( *p & 0x3f) != 0x00 ) {
|
while ((*p & 0x3f) != 0x00) {
|
||||||
s = p + 1;
|
s = p + 1;
|
||||||
if ( *p == 0x20 )
|
if (*p == 0x20)
|
||||||
compress = 1;
|
compress = 1;
|
||||||
else
|
else
|
||||||
compress = 0;
|
compress = 0;
|
||||||
|
|
||||||
/* Get next length field */
|
/* Get next length field */
|
||||||
p = (u_char *)(p + (*p & 0x3f) + 1);
|
p = (u_char *) (p + (*p & 0x3f) + 1);
|
||||||
if ((char *)p > pmax) {
|
if ((char *)p > pmax) {
|
||||||
p = NULL;
|
p = NULL;
|
||||||
break;
|
break;
|
||||||
@ -154,15 +159,15 @@ static u_char *AliasHandleName ( u_char *p, char *pmax ) {
|
|||||||
printf(":");
|
printf(":");
|
||||||
#endif
|
#endif
|
||||||
while (s < p) {
|
while (s < p) {
|
||||||
if ( compress == 1 ) {
|
if (compress == 1) {
|
||||||
c = (u_char )(((((*s & 0x0f) << 4) | (*(s+1) & 0x0f)) - 0x11));
|
c = (u_char) (((((*s & 0x0f) << 4) | (*(s + 1) & 0x0f)) - 0x11));
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (isprint( c ) )
|
if (isprint(c))
|
||||||
printf("%c", c );
|
printf("%c", c);
|
||||||
else
|
else
|
||||||
printf("<0x%02x>", c );
|
printf("<0x%02x>", c);
|
||||||
#endif
|
#endif
|
||||||
s +=2;
|
s += 2;
|
||||||
} else {
|
} else {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("%c", *s);
|
printf("%c", *s);
|
||||||
@ -174,14 +179,14 @@ static u_char *AliasHandleName ( u_char *p, char *pmax ) {
|
|||||||
printf(":");
|
printf(":");
|
||||||
#endif
|
#endif
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set up to out of Name field */
|
/* Set up to out of Name field */
|
||||||
if (p == NULL || (char *)p >= pmax)
|
if (p == NULL || (char *)p >= pmax)
|
||||||
p = NULL;
|
p = NULL;
|
||||||
else
|
else
|
||||||
p++;
|
p++;
|
||||||
return ((u_char *)p);
|
return ((u_char *) p);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -195,58 +200,61 @@ static u_char *AliasHandleName ( u_char *p, char *pmax ) {
|
|||||||
#define DGM_POSITIVE_RES 0x15
|
#define DGM_POSITIVE_RES 0x15
|
||||||
#define DGM_NEGATIVE_RES 0x16
|
#define DGM_NEGATIVE_RES 0x16
|
||||||
|
|
||||||
int AliasHandleUdpNbt(
|
int
|
||||||
struct libalias *la,
|
AliasHandleUdpNbt(
|
||||||
struct ip *pip, /* IP packet to examine/patch */
|
struct libalias *la,
|
||||||
struct alias_link *link,
|
struct ip *pip, /* IP packet to examine/patch */
|
||||||
struct in_addr *alias_address,
|
struct alias_link *link,
|
||||||
u_short alias_port
|
struct in_addr *alias_address,
|
||||||
) {
|
u_short alias_port
|
||||||
struct udphdr * uh;
|
)
|
||||||
NbtDataHeader *ndh;
|
{
|
||||||
u_char *p = NULL;
|
struct udphdr *uh;
|
||||||
char *pmax;
|
NbtDataHeader *ndh;
|
||||||
|
u_char *p = NULL;
|
||||||
|
char *pmax;
|
||||||
|
|
||||||
/* Calculate data length of UDP packet */
|
/* Calculate data length of UDP packet */
|
||||||
uh = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2));
|
uh = (struct udphdr *)((char *)pip + (pip->ip_hl << 2));
|
||||||
pmax = (char *)uh + ntohs( uh->uh_ulen );
|
pmax = (char *)uh + ntohs(uh->uh_ulen);
|
||||||
|
|
||||||
ndh = (NbtDataHeader *)((char *)uh + (sizeof (struct udphdr)));
|
ndh = (NbtDataHeader *) ((char *)uh + (sizeof(struct udphdr)));
|
||||||
if ((char *)(ndh + 1) > pmax)
|
if ((char *)(ndh + 1) > pmax)
|
||||||
return(-1);
|
return (-1);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("\nType=%02x,", ndh->type );
|
printf("\nType=%02x,", ndh->type);
|
||||||
#endif
|
#endif
|
||||||
switch ( ndh->type ) {
|
switch (ndh->type) {
|
||||||
case DGM_DIRECT_UNIQ:
|
case DGM_DIRECT_UNIQ:
|
||||||
case DGM_DIRECT_GROUP:
|
case DGM_DIRECT_GROUP:
|
||||||
case DGM_BROADCAST:
|
case DGM_BROADCAST:
|
||||||
p = (u_char *)ndh + 14;
|
p = (u_char *) ndh + 14;
|
||||||
p = AliasHandleName ( p, pmax ); /* Source Name */
|
p = AliasHandleName(p, pmax); /* Source Name */
|
||||||
p = AliasHandleName ( p, pmax ); /* Destination Name */
|
p = AliasHandleName(p, pmax); /* Destination Name */
|
||||||
break;
|
break;
|
||||||
case DGM_ERROR:
|
case DGM_ERROR:
|
||||||
p = (u_char *)ndh + 11;
|
p = (u_char *) ndh + 11;
|
||||||
break;
|
break;
|
||||||
case DGM_QUERY:
|
case DGM_QUERY:
|
||||||
case DGM_POSITIVE_RES:
|
case DGM_POSITIVE_RES:
|
||||||
case DGM_NEGATIVE_RES:
|
case DGM_NEGATIVE_RES:
|
||||||
p = (u_char *)ndh + 10;
|
p = (u_char *) ndh + 10;
|
||||||
p = AliasHandleName ( p, pmax ); /* Destination Name */
|
p = AliasHandleName(p, pmax); /* Destination Name */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (p == NULL || (char *)p > pmax)
|
if (p == NULL || (char *)p > pmax)
|
||||||
p = NULL;
|
p = NULL;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("%s:%d-->", inet_ntoa(ndh->source_ip), ntohs(ndh->source_port) );
|
printf("%s:%d-->", inet_ntoa(ndh->source_ip), ntohs(ndh->source_port));
|
||||||
#endif
|
#endif
|
||||||
/* Doing an IP address and Port number Translation */
|
/* Doing an IP address and Port number Translation */
|
||||||
if ( uh->uh_sum != 0 ) {
|
if (uh->uh_sum != 0) {
|
||||||
int acc;
|
int acc;
|
||||||
u_short *sptr;
|
u_short *sptr;
|
||||||
acc = ndh->source_port;
|
|
||||||
|
acc = ndh->source_port;
|
||||||
acc -= alias_port;
|
acc -= alias_port;
|
||||||
sptr = (u_short *) &(ndh->source_ip);
|
sptr = (u_short *) & (ndh->source_ip);
|
||||||
acc += *sptr++;
|
acc += *sptr++;
|
||||||
acc += *sptr;
|
acc += *sptr;
|
||||||
sptr = (u_short *) alias_address;
|
sptr = (u_short *) alias_address;
|
||||||
@ -254,49 +262,49 @@ int AliasHandleUdpNbt(
|
|||||||
acc -= *sptr;
|
acc -= *sptr;
|
||||||
ADJUST_CHECKSUM(acc, uh->uh_sum);
|
ADJUST_CHECKSUM(acc, uh->uh_sum);
|
||||||
}
|
}
|
||||||
ndh->source_ip = *alias_address;
|
ndh->source_ip = *alias_address;
|
||||||
ndh->source_port = alias_port;
|
ndh->source_port = alias_port;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("%s:%d\n", inet_ntoa(ndh->source_ip), ntohs(ndh->source_port) );
|
printf("%s:%d\n", inet_ntoa(ndh->source_ip), ntohs(ndh->source_port));
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
#endif
|
#endif
|
||||||
return((p == NULL) ? -1 : 0);
|
return ((p == NULL) ? -1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Question Section */
|
/* Question Section */
|
||||||
#define QS_TYPE_NB 0x0020
|
#define QS_TYPE_NB 0x0020
|
||||||
#define QS_TYPE_NBSTAT 0x0021
|
#define QS_TYPE_NBSTAT 0x0021
|
||||||
#define QS_CLAS_IN 0x0001
|
#define QS_CLAS_IN 0x0001
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u_short type; /* The type of Request */
|
u_short type; /* The type of Request */
|
||||||
u_short class; /* The class of Request */
|
u_short class; /* The class of Request */
|
||||||
} NBTNsQuestion;
|
} NBTNsQuestion;
|
||||||
|
|
||||||
static u_char *
|
static u_char *
|
||||||
AliasHandleQuestion(
|
AliasHandleQuestion(
|
||||||
u_short count,
|
u_short count,
|
||||||
NBTNsQuestion *q,
|
NBTNsQuestion * q,
|
||||||
char *pmax,
|
char *pmax,
|
||||||
NBTArguments *nbtarg)
|
NBTArguments * nbtarg)
|
||||||
{
|
{
|
||||||
|
|
||||||
while ( count != 0 ) {
|
while (count != 0) {
|
||||||
/* Name Filed */
|
/* Name Filed */
|
||||||
q = (NBTNsQuestion *)AliasHandleName((u_char *)q, pmax);
|
q = (NBTNsQuestion *) AliasHandleName((u_char *) q, pmax);
|
||||||
|
|
||||||
if (q == NULL || (char *)(q + 1) > pmax) {
|
if (q == NULL || (char *)(q + 1) > pmax) {
|
||||||
q = NULL;
|
q = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Type and Class filed */
|
/* Type and Class filed */
|
||||||
switch ( ntohs(q->type) ) {
|
switch (ntohs(q->type)) {
|
||||||
case QS_TYPE_NB:
|
case QS_TYPE_NB:
|
||||||
case QS_TYPE_NBSTAT:
|
case QS_TYPE_NBSTAT:
|
||||||
q= q+1;
|
q = q + 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("\nUnknown Type on Question %0x\n", ntohs(q->type) );
|
printf("\nUnknown Type on Question %0x\n", ntohs(q->type));
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -304,7 +312,7 @@ AliasHandleQuestion(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Set up to out of Question Section */
|
/* Set up to out of Question Section */
|
||||||
return ((u_char *)q);
|
return ((u_char *) q);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Resource Record */
|
/* Resource Record */
|
||||||
@ -316,101 +324,99 @@ AliasHandleQuestion(
|
|||||||
#define RR_CLAS_IN 0x0001
|
#define RR_CLAS_IN 0x0001
|
||||||
#define SizeOfNsResource 8
|
#define SizeOfNsResource 8
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u_short type;
|
u_short type;
|
||||||
u_short class;
|
u_short class;
|
||||||
unsigned int ttl;
|
unsigned int ttl;
|
||||||
u_short rdlen;
|
u_short rdlen;
|
||||||
} NBTNsResource;
|
} NBTNsResource;
|
||||||
|
|
||||||
#define SizeOfNsRNB 6
|
#define SizeOfNsRNB 6
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u_short g:1, ont:2, resv:13;
|
u_short g: 1 , ont:2, resv:13;
|
||||||
struct in_addr addr;
|
struct in_addr addr;
|
||||||
} NBTNsRNB;
|
} NBTNsRNB;
|
||||||
|
|
||||||
static u_char *
|
static u_char *
|
||||||
AliasHandleResourceNB(
|
AliasHandleResourceNB(
|
||||||
NBTNsResource *q,
|
NBTNsResource * q,
|
||||||
char *pmax,
|
char *pmax,
|
||||||
NBTArguments *nbtarg)
|
NBTArguments * nbtarg)
|
||||||
{
|
{
|
||||||
NBTNsRNB *nb;
|
NBTNsRNB *nb;
|
||||||
u_short bcount;
|
u_short bcount;
|
||||||
|
|
||||||
if (q == NULL || (char *)(q + 1) > pmax)
|
if (q == NULL || (char *)(q + 1) > pmax)
|
||||||
return(NULL);
|
return (NULL);
|
||||||
/* Check out a length */
|
/* Check out a length */
|
||||||
bcount = ntohs(q->rdlen);
|
bcount = ntohs(q->rdlen);
|
||||||
|
|
||||||
/* Forward to Resource NB position */
|
/* Forward to Resource NB position */
|
||||||
nb = (NBTNsRNB *)((u_char *)q + SizeOfNsResource);
|
nb = (NBTNsRNB *) ((u_char *) q + SizeOfNsResource);
|
||||||
|
|
||||||
/* Processing all in_addr array */
|
/* Processing all in_addr array */
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("NB rec[%s", inet_ntoa(nbtarg->oldaddr));
|
printf("NB rec[%s", inet_ntoa(nbtarg->oldaddr));
|
||||||
printf("->%s, %dbytes] ",inet_ntoa(nbtarg->newaddr ), bcount);
|
printf("->%s, %dbytes] ", inet_ntoa(nbtarg->newaddr), bcount);
|
||||||
#endif
|
#endif
|
||||||
while ( nb != NULL && bcount != 0 ) {
|
while (nb != NULL && bcount != 0) {
|
||||||
if ((char *)(nb + 1) > pmax) {
|
if ((char *)(nb + 1) > pmax) {
|
||||||
nb = NULL;
|
nb = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("<%s>", inet_ntoa(nb->addr) );
|
printf("<%s>", inet_ntoa(nb->addr));
|
||||||
#endif
|
#endif
|
||||||
if (!bcmp(&nbtarg->oldaddr,&nb->addr, sizeof(struct in_addr) ) ) {
|
if (!bcmp(&nbtarg->oldaddr, &nb->addr, sizeof(struct in_addr))) {
|
||||||
if ( *nbtarg->uh_sum != 0 ) {
|
if (*nbtarg->uh_sum != 0) {
|
||||||
int acc;
|
int acc;
|
||||||
u_short *sptr;
|
u_short *sptr;
|
||||||
|
|
||||||
sptr = (u_short *) &(nb->addr);
|
sptr = (u_short *) & (nb->addr);
|
||||||
acc = *sptr++;
|
acc = *sptr++;
|
||||||
acc += *sptr;
|
acc += *sptr;
|
||||||
sptr = (u_short *) &(nbtarg->newaddr);
|
sptr = (u_short *) & (nbtarg->newaddr);
|
||||||
acc -= *sptr++;
|
acc -= *sptr++;
|
||||||
acc -= *sptr;
|
acc -= *sptr;
|
||||||
ADJUST_CHECKSUM(acc, *nbtarg->uh_sum);
|
ADJUST_CHECKSUM(acc, *nbtarg->uh_sum);
|
||||||
}
|
}
|
||||||
|
|
||||||
nb->addr = nbtarg->newaddr;
|
nb->addr = nbtarg->newaddr;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("O");
|
printf("O");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
else {
|
else {
|
||||||
printf(".");
|
printf(".");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
nb=(NBTNsRNB *)((u_char *)nb + SizeOfNsRNB);
|
nb = (NBTNsRNB *) ((u_char *) nb + SizeOfNsRNB);
|
||||||
bcount -= SizeOfNsRNB;
|
bcount -= SizeOfNsRNB;
|
||||||
}
|
}
|
||||||
if (nb == NULL || (char *)(nb + 1) > pmax) {
|
if (nb == NULL || (char *)(nb + 1) > pmax) {
|
||||||
nb = NULL;
|
nb = NULL;
|
||||||
}
|
}
|
||||||
|
return ((u_char *) nb);
|
||||||
return ((u_char *)nb);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SizeOfResourceA 6
|
#define SizeOfResourceA 6
|
||||||
typedef struct {
|
typedef struct {
|
||||||
struct in_addr addr;
|
struct in_addr addr;
|
||||||
} NBTNsResourceA;
|
} NBTNsResourceA;
|
||||||
|
|
||||||
static u_char *
|
static u_char *
|
||||||
AliasHandleResourceA(
|
AliasHandleResourceA(
|
||||||
NBTNsResource *q,
|
NBTNsResource * q,
|
||||||
char *pmax,
|
char *pmax,
|
||||||
NBTArguments *nbtarg)
|
NBTArguments * nbtarg)
|
||||||
{
|
{
|
||||||
NBTNsResourceA *a;
|
NBTNsResourceA *a;
|
||||||
u_short bcount;
|
u_short bcount;
|
||||||
|
|
||||||
if (q == NULL || (char *)(q + 1) > pmax)
|
if (q == NULL || (char *)(q + 1) > pmax)
|
||||||
return(NULL);
|
return (NULL);
|
||||||
|
|
||||||
/* Forward to Resource A position */
|
/* Forward to Resource A position */
|
||||||
a = (NBTNsResourceA *)( (u_char *)q + sizeof(NBTNsResource) );
|
a = (NBTNsResourceA *) ((u_char *) q + sizeof(NBTNsResource));
|
||||||
|
|
||||||
/* Check out of length */
|
/* Check out of length */
|
||||||
bcount = ntohs(q->rdlen);
|
bcount = ntohs(q->rdlen);
|
||||||
@ -418,62 +424,61 @@ AliasHandleResourceA(
|
|||||||
/* Processing all in_addr array */
|
/* Processing all in_addr array */
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("Arec [%s", inet_ntoa(nbtarg->oldaddr));
|
printf("Arec [%s", inet_ntoa(nbtarg->oldaddr));
|
||||||
printf("->%s]",inet_ntoa(nbtarg->newaddr ));
|
printf("->%s]", inet_ntoa(nbtarg->newaddr));
|
||||||
#endif
|
#endif
|
||||||
while ( bcount != 0 ) {
|
while (bcount != 0) {
|
||||||
if (a == NULL || (char *)(a + 1) > pmax)
|
if (a == NULL || (char *)(a + 1) > pmax)
|
||||||
return(NULL);
|
return (NULL);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("..%s", inet_ntoa(a->addr) );
|
printf("..%s", inet_ntoa(a->addr));
|
||||||
#endif
|
#endif
|
||||||
if ( !bcmp(&nbtarg->oldaddr, &a->addr, sizeof(struct in_addr) ) ) {
|
if (!bcmp(&nbtarg->oldaddr, &a->addr, sizeof(struct in_addr))) {
|
||||||
if ( *nbtarg->uh_sum != 0 ) {
|
if (*nbtarg->uh_sum != 0) {
|
||||||
int acc;
|
int acc;
|
||||||
u_short *sptr;
|
u_short *sptr;
|
||||||
|
|
||||||
sptr = (u_short *) &(a->addr); /* Old */
|
sptr = (u_short *) & (a->addr); /* Old */
|
||||||
acc = *sptr++;
|
acc = *sptr++;
|
||||||
acc += *sptr;
|
acc += *sptr;
|
||||||
sptr = (u_short *) &nbtarg->newaddr; /* New */
|
sptr = (u_short *) & nbtarg->newaddr; /* New */
|
||||||
acc -= *sptr++;
|
acc -= *sptr++;
|
||||||
acc -= *sptr;
|
acc -= *sptr;
|
||||||
ADJUST_CHECKSUM(acc, *nbtarg->uh_sum);
|
ADJUST_CHECKSUM(acc, *nbtarg->uh_sum);
|
||||||
}
|
}
|
||||||
|
|
||||||
a->addr = nbtarg->newaddr;
|
a->addr = nbtarg->newaddr;
|
||||||
}
|
}
|
||||||
a++; /*XXXX*/
|
a++; /* XXXX */
|
||||||
bcount -= SizeOfResourceA;
|
bcount -= SizeOfResourceA;
|
||||||
}
|
}
|
||||||
if (a == NULL || (char *)(a + 1) > pmax)
|
if (a == NULL || (char *)(a + 1) > pmax)
|
||||||
a = NULL;
|
a = NULL;
|
||||||
return ((u_char *)a);
|
return ((u_char *) a);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u_short opcode:4, flags:8, resv:4;
|
u_short opcode:4, flags:8, resv:4;
|
||||||
} NBTNsResourceNULL;
|
} NBTNsResourceNULL;
|
||||||
|
|
||||||
static u_char *
|
static u_char *
|
||||||
AliasHandleResourceNULL(
|
AliasHandleResourceNULL(
|
||||||
NBTNsResource *q,
|
NBTNsResource * q,
|
||||||
char *pmax,
|
char *pmax,
|
||||||
NBTArguments *nbtarg)
|
NBTArguments * nbtarg)
|
||||||
{
|
{
|
||||||
NBTNsResourceNULL *n;
|
NBTNsResourceNULL *n;
|
||||||
u_short bcount;
|
u_short bcount;
|
||||||
|
|
||||||
if (q == NULL || (char *)(q + 1) > pmax)
|
if (q == NULL || (char *)(q + 1) > pmax)
|
||||||
return(NULL);
|
return (NULL);
|
||||||
|
|
||||||
/* Forward to Resource NULL position */
|
/* Forward to Resource NULL position */
|
||||||
n = (NBTNsResourceNULL *)( (u_char *)q + sizeof(NBTNsResource) );
|
n = (NBTNsResourceNULL *) ((u_char *) q + sizeof(NBTNsResource));
|
||||||
|
|
||||||
/* Check out of length */
|
/* Check out of length */
|
||||||
bcount = ntohs(q->rdlen);
|
bcount = ntohs(q->rdlen);
|
||||||
|
|
||||||
/* Processing all in_addr array */
|
/* Processing all in_addr array */
|
||||||
while ( bcount != 0 ) {
|
while (bcount != 0) {
|
||||||
if ((char *)(n + 1) > pmax) {
|
if ((char *)(n + 1) > pmax) {
|
||||||
n = NULL;
|
n = NULL;
|
||||||
break;
|
break;
|
||||||
@ -484,223 +489,220 @@ AliasHandleResourceNULL(
|
|||||||
if ((char *)(n + 1) > pmax)
|
if ((char *)(n + 1) > pmax)
|
||||||
n = NULL;
|
n = NULL;
|
||||||
|
|
||||||
return ((u_char *)n);
|
return ((u_char *) n);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u_char *
|
static u_char *
|
||||||
AliasHandleResourceNS(
|
AliasHandleResourceNS(
|
||||||
NBTNsResource *q,
|
NBTNsResource * q,
|
||||||
char *pmax,
|
char *pmax,
|
||||||
NBTArguments *nbtarg)
|
NBTArguments * nbtarg)
|
||||||
{
|
{
|
||||||
NBTNsResourceNULL *n;
|
NBTNsResourceNULL *n;
|
||||||
u_short bcount;
|
u_short bcount;
|
||||||
|
|
||||||
if (q == NULL || (char *)(q + 1) > pmax)
|
if (q == NULL || (char *)(q + 1) > pmax)
|
||||||
return(NULL);
|
return (NULL);
|
||||||
|
|
||||||
/* Forward to Resource NULL position */
|
/* Forward to Resource NULL position */
|
||||||
n = (NBTNsResourceNULL *)( (u_char *)q + sizeof(NBTNsResource) );
|
n = (NBTNsResourceNULL *) ((u_char *) q + sizeof(NBTNsResource));
|
||||||
|
|
||||||
/* Check out of length */
|
/* Check out of length */
|
||||||
bcount = ntohs(q->rdlen);
|
bcount = ntohs(q->rdlen);
|
||||||
|
|
||||||
/* Resource Record Name Filed */
|
/* Resource Record Name Filed */
|
||||||
q = (NBTNsResource *)AliasHandleName( (u_char *)n, pmax ); /* XXX */
|
q = (NBTNsResource *) AliasHandleName((u_char *) n, pmax); /* XXX */
|
||||||
|
|
||||||
if (q == NULL || (char *)((u_char *)n + bcount) > pmax)
|
if (q == NULL || (char *)((u_char *) n + bcount) > pmax)
|
||||||
return(NULL);
|
return (NULL);
|
||||||
else
|
else
|
||||||
return ((u_char *)n + bcount);
|
return ((u_char *) n + bcount);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u_short numnames;
|
u_short numnames;
|
||||||
} NBTNsResourceNBSTAT;
|
} NBTNsResourceNBSTAT;
|
||||||
|
|
||||||
static u_char *
|
static u_char *
|
||||||
AliasHandleResourceNBSTAT(
|
AliasHandleResourceNBSTAT(
|
||||||
NBTNsResource *q,
|
NBTNsResource * q,
|
||||||
char *pmax,
|
char *pmax,
|
||||||
NBTArguments *nbtarg)
|
NBTArguments * nbtarg)
|
||||||
{
|
{
|
||||||
NBTNsResourceNBSTAT *n;
|
NBTNsResourceNBSTAT *n;
|
||||||
u_short bcount;
|
u_short bcount;
|
||||||
|
|
||||||
if (q == NULL || (char *)(q + 1) > pmax)
|
if (q == NULL || (char *)(q + 1) > pmax)
|
||||||
return(NULL);
|
return (NULL);
|
||||||
|
|
||||||
/* Forward to Resource NBSTAT position */
|
/* Forward to Resource NBSTAT position */
|
||||||
n = (NBTNsResourceNBSTAT *)( (u_char *)q + sizeof(NBTNsResource) );
|
n = (NBTNsResourceNBSTAT *) ((u_char *) q + sizeof(NBTNsResource));
|
||||||
|
|
||||||
/* Check out of length */
|
/* Check out of length */
|
||||||
bcount = ntohs(q->rdlen);
|
bcount = ntohs(q->rdlen);
|
||||||
|
|
||||||
if (q == NULL || (char *)((u_char *)n + bcount) > pmax)
|
if (q == NULL || (char *)((u_char *) n + bcount) > pmax)
|
||||||
return(NULL);
|
return (NULL);
|
||||||
else
|
else
|
||||||
return ((u_char *)n + bcount);
|
return ((u_char *) n + bcount);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u_char *
|
static u_char *
|
||||||
AliasHandleResource(
|
AliasHandleResource(
|
||||||
u_short count,
|
u_short count,
|
||||||
NBTNsResource *q,
|
NBTNsResource * q,
|
||||||
char *pmax,
|
char *pmax,
|
||||||
NBTArguments
|
NBTArguments
|
||||||
*nbtarg)
|
* nbtarg)
|
||||||
{
|
{
|
||||||
while ( count != 0 ) {
|
while (count != 0) {
|
||||||
/* Resource Record Name Filed */
|
/* Resource Record Name Filed */
|
||||||
q = (NBTNsResource *)AliasHandleName( (u_char *)q, pmax );
|
q = (NBTNsResource *) AliasHandleName((u_char *) q, pmax);
|
||||||
|
|
||||||
if (q == NULL || (char *)(q + 1) > pmax)
|
if (q == NULL || (char *)(q + 1) > pmax)
|
||||||
break;
|
break;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("type=%02x, count=%d\n", ntohs(q->type), count );
|
printf("type=%02x, count=%d\n", ntohs(q->type), count);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Type and Class filed */
|
/* Type and Class filed */
|
||||||
switch ( ntohs(q->type) ) {
|
switch (ntohs(q->type)) {
|
||||||
case RR_TYPE_NB:
|
case RR_TYPE_NB:
|
||||||
q = (NBTNsResource *)AliasHandleResourceNB(
|
q = (NBTNsResource *) AliasHandleResourceNB(
|
||||||
q,
|
q,
|
||||||
pmax,
|
pmax,
|
||||||
nbtarg
|
nbtarg
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case RR_TYPE_A:
|
case RR_TYPE_A:
|
||||||
q = (NBTNsResource *)AliasHandleResourceA(
|
q = (NBTNsResource *) AliasHandleResourceA(
|
||||||
q,
|
q,
|
||||||
pmax,
|
pmax,
|
||||||
nbtarg
|
nbtarg
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case RR_TYPE_NS:
|
case RR_TYPE_NS:
|
||||||
q = (NBTNsResource *)AliasHandleResourceNS(
|
q = (NBTNsResource *) AliasHandleResourceNS(
|
||||||
q,
|
q,
|
||||||
pmax,
|
pmax,
|
||||||
nbtarg
|
nbtarg
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case RR_TYPE_NULL:
|
case RR_TYPE_NULL:
|
||||||
q = (NBTNsResource *)AliasHandleResourceNULL(
|
q = (NBTNsResource *) AliasHandleResourceNULL(
|
||||||
q,
|
q,
|
||||||
pmax,
|
pmax,
|
||||||
nbtarg
|
nbtarg
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case RR_TYPE_NBSTAT:
|
case RR_TYPE_NBSTAT:
|
||||||
q = (NBTNsResource *)AliasHandleResourceNBSTAT(
|
q = (NBTNsResource *) AliasHandleResourceNBSTAT(
|
||||||
q,
|
q,
|
||||||
pmax,
|
pmax,
|
||||||
nbtarg
|
nbtarg
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf(
|
printf(
|
||||||
"\nUnknown Type of Resource %0x\n",
|
"\nUnknown Type of Resource %0x\n",
|
||||||
ntohs(q->type)
|
ntohs(q->type)
|
||||||
);
|
);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
count--;
|
count--;
|
||||||
}
|
}
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
return ((u_char *)q);
|
return ((u_char *) q);
|
||||||
}
|
}
|
||||||
|
|
||||||
int AliasHandleUdpNbtNS(
|
int
|
||||||
struct libalias *la,
|
AliasHandleUdpNbtNS(
|
||||||
struct ip *pip, /* IP packet to examine/patch */
|
struct libalias *la,
|
||||||
struct alias_link *link,
|
struct ip *pip, /* IP packet to examine/patch */
|
||||||
struct in_addr *alias_address,
|
struct alias_link *link,
|
||||||
u_short *alias_port,
|
struct in_addr *alias_address,
|
||||||
struct in_addr *original_address,
|
u_short * alias_port,
|
||||||
u_short *original_port )
|
struct in_addr *original_address,
|
||||||
|
u_short * original_port)
|
||||||
{
|
{
|
||||||
struct udphdr * uh;
|
struct udphdr *uh;
|
||||||
NbtNSHeader * nsh;
|
NbtNSHeader *nsh;
|
||||||
u_char * p;
|
u_char *p;
|
||||||
char *pmax;
|
char *pmax;
|
||||||
NBTArguments nbtarg;
|
NBTArguments nbtarg;
|
||||||
|
|
||||||
/* Set up Common Parameter */
|
/* Set up Common Parameter */
|
||||||
nbtarg.oldaddr = *alias_address;
|
nbtarg.oldaddr = *alias_address;
|
||||||
nbtarg.oldport = *alias_port;
|
nbtarg.oldport = *alias_port;
|
||||||
nbtarg.newaddr = *original_address;
|
nbtarg.newaddr = *original_address;
|
||||||
nbtarg.newport = *original_port;
|
nbtarg.newport = *original_port;
|
||||||
|
|
||||||
/* Calculate data length of UDP packet */
|
/* Calculate data length of UDP packet */
|
||||||
uh = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2));
|
uh = (struct udphdr *)((char *)pip + (pip->ip_hl << 2));
|
||||||
nbtarg.uh_sum = &(uh->uh_sum);
|
nbtarg.uh_sum = &(uh->uh_sum);
|
||||||
nsh = (NbtNSHeader *)((char *)uh + (sizeof(struct udphdr)));
|
nsh = (NbtNSHeader *) ((char *)uh + (sizeof(struct udphdr)));
|
||||||
p = (u_char *)(nsh + 1);
|
p = (u_char *) (nsh + 1);
|
||||||
pmax = (char *)uh + ntohs( uh->uh_ulen );
|
pmax = (char *)uh + ntohs(uh->uh_ulen);
|
||||||
|
|
||||||
if ((char *)(nsh + 1) > pmax)
|
if ((char *)(nsh + 1) > pmax)
|
||||||
return(-1);
|
return (-1);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf(" [%s] ID=%02x, op=%01x, flag=%02x, rcode=%01x, qd=%04x"
|
printf(" [%s] ID=%02x, op=%01x, flag=%02x, rcode=%01x, qd=%04x"
|
||||||
", an=%04x, ns=%04x, ar=%04x, [%d]-->",
|
", an=%04x, ns=%04x, ar=%04x, [%d]-->",
|
||||||
nsh->dir ? "Response": "Request",
|
nsh->dir ? "Response" : "Request",
|
||||||
nsh->nametrid,
|
nsh->nametrid,
|
||||||
nsh->opcode,
|
nsh->opcode,
|
||||||
nsh->nmflags,
|
nsh->nmflags,
|
||||||
nsh->rcode,
|
nsh->rcode,
|
||||||
ntohs(nsh->qdcount),
|
ntohs(nsh->qdcount),
|
||||||
ntohs(nsh->ancount),
|
ntohs(nsh->ancount),
|
||||||
ntohs(nsh->nscount),
|
ntohs(nsh->nscount),
|
||||||
ntohs(nsh->arcount),
|
ntohs(nsh->arcount),
|
||||||
(u_char *)p -(u_char *)nsh
|
(u_char *) p - (u_char *) nsh
|
||||||
);
|
);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Question Entries */
|
/* Question Entries */
|
||||||
if (ntohs(nsh->qdcount) !=0 ) {
|
if (ntohs(nsh->qdcount) != 0) {
|
||||||
p = AliasHandleQuestion(
|
p = AliasHandleQuestion(
|
||||||
ntohs(nsh->qdcount),
|
ntohs(nsh->qdcount),
|
||||||
(NBTNsQuestion *)p,
|
(NBTNsQuestion *) p,
|
||||||
pmax,
|
pmax,
|
||||||
&nbtarg
|
&nbtarg
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Answer Resource Records */
|
/* Answer Resource Records */
|
||||||
if (ntohs(nsh->ancount) !=0 ) {
|
if (ntohs(nsh->ancount) != 0) {
|
||||||
p = AliasHandleResource(
|
p = AliasHandleResource(
|
||||||
ntohs(nsh->ancount),
|
ntohs(nsh->ancount),
|
||||||
(NBTNsResource *)p,
|
(NBTNsResource *) p,
|
||||||
pmax,
|
pmax,
|
||||||
&nbtarg
|
&nbtarg
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Authority Resource Recodrs */
|
/* Authority Resource Recodrs */
|
||||||
if (ntohs(nsh->nscount) !=0 ) {
|
if (ntohs(nsh->nscount) != 0) {
|
||||||
p = AliasHandleResource(
|
p = AliasHandleResource(
|
||||||
ntohs(nsh->nscount),
|
ntohs(nsh->nscount),
|
||||||
(NBTNsResource *)p,
|
(NBTNsResource *) p,
|
||||||
pmax,
|
pmax,
|
||||||
&nbtarg
|
&nbtarg
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Additional Resource Recodrs */
|
/* Additional Resource Recodrs */
|
||||||
if (ntohs(nsh->arcount) !=0 ) {
|
if (ntohs(nsh->arcount) != 0) {
|
||||||
p = AliasHandleResource(
|
p = AliasHandleResource(
|
||||||
ntohs(nsh->arcount),
|
ntohs(nsh->arcount),
|
||||||
(NBTNsResource *)p,
|
(NBTNsResource *) p,
|
||||||
pmax,
|
pmax,
|
||||||
&nbtarg
|
&nbtarg
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
PrintRcode(nsh->rcode);
|
PrintRcode(nsh->rcode);
|
||||||
#endif
|
#endif
|
||||||
return ((p == NULL) ? -1 : 0);
|
return ((p == NULL) ? -1 : 0);
|
||||||
}
|
}
|
||||||
|
@ -113,7 +113,7 @@ PacketAliasAddServer(struct alias_link *_link,
|
|||||||
|
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
PacketAliasRedirectAddr(struct in_addr _src_addr,
|
PacketAliasRedirectAddr(struct in_addr _src_addr,
|
||||||
struct in_addr _alias_addr)
|
struct in_addr _alias_addr)
|
||||||
{
|
{
|
||||||
|
|
||||||
return LibAliasRedirectAddr(la, _src_addr, _alias_addr);
|
return LibAliasRedirectAddr(la, _src_addr, _alias_addr);
|
||||||
@ -152,7 +152,7 @@ PacketAliasRedirectProto(struct in_addr _src_addr,
|
|||||||
{
|
{
|
||||||
|
|
||||||
return LibAliasRedirectProto(la, _src_addr, _dst_addr, _alias_addr,
|
return LibAliasRedirectProto(la, _src_addr, _dst_addr, _alias_addr,
|
||||||
_proto);
|
_proto);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -162,7 +162,7 @@ PacketAliasFragmentIn(char *_ptr, char *_ptr_fragment)
|
|||||||
LibAliasFragmentIn(la, _ptr, _ptr_fragment);
|
LibAliasFragmentIn(la, _ptr, _ptr_fragment);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
PacketAliasGetFragment(char *_ptr)
|
PacketAliasGetFragment(char *_ptr)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -80,16 +80,16 @@ __FBSDID("$FreeBSD$");
|
|||||||
* PPTP definitions
|
* PPTP definitions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct grehdr /* Enhanced GRE header. */
|
struct grehdr { /* Enhanced GRE header. */
|
||||||
{
|
u_int16_t gh_flags; /* Flags. */
|
||||||
u_int16_t gh_flags; /* Flags. */
|
u_int16_t gh_protocol; /* Protocol type. */
|
||||||
u_int16_t gh_protocol; /* Protocol type. */
|
u_int16_t gh_length; /* Payload length. */
|
||||||
u_int16_t gh_length; /* Payload length. */
|
u_int16_t gh_call_id; /* Call ID. */
|
||||||
u_int16_t gh_call_id; /* Call ID. */
|
u_int32_t gh_seq_no; /* Sequence number (optional). */
|
||||||
u_int32_t gh_seq_no; /* Sequence number (optional). */
|
u_int32_t gh_ack_no; /* Acknowledgment number
|
||||||
u_int32_t gh_ack_no; /* Acknowledgment number (optional). */
|
* (optional). */
|
||||||
};
|
};
|
||||||
typedef struct grehdr GreHdr;
|
typedef struct grehdr GreHdr;
|
||||||
|
|
||||||
/* The PPTP protocol ID used in the GRE 'proto' field. */
|
/* The PPTP protocol ID used in the GRE 'proto' field. */
|
||||||
#define PPTP_GRE_PROTO 0x880b
|
#define PPTP_GRE_PROTO 0x880b
|
||||||
@ -102,270 +102,276 @@ typedef struct grehdr GreHdr;
|
|||||||
#define PPTP_CTRL_MSG_TYPE 1
|
#define PPTP_CTRL_MSG_TYPE 1
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PPTP_StartCtrlConnRequest = 1,
|
PPTP_StartCtrlConnRequest = 1,
|
||||||
PPTP_StartCtrlConnReply = 2,
|
PPTP_StartCtrlConnReply = 2,
|
||||||
PPTP_StopCtrlConnRequest = 3,
|
PPTP_StopCtrlConnRequest = 3,
|
||||||
PPTP_StopCtrlConnReply = 4,
|
PPTP_StopCtrlConnReply = 4,
|
||||||
PPTP_EchoRequest = 5,
|
PPTP_EchoRequest = 5,
|
||||||
PPTP_EchoReply = 6,
|
PPTP_EchoReply = 6,
|
||||||
PPTP_OutCallRequest = 7,
|
PPTP_OutCallRequest = 7,
|
||||||
PPTP_OutCallReply = 8,
|
PPTP_OutCallReply = 8,
|
||||||
PPTP_InCallRequest = 9,
|
PPTP_InCallRequest = 9,
|
||||||
PPTP_InCallReply = 10,
|
PPTP_InCallReply = 10,
|
||||||
PPTP_InCallConn = 11,
|
PPTP_InCallConn = 11,
|
||||||
PPTP_CallClearRequest = 12,
|
PPTP_CallClearRequest = 12,
|
||||||
PPTP_CallDiscNotify = 13,
|
PPTP_CallDiscNotify = 13,
|
||||||
PPTP_WanErrorNotify = 14,
|
PPTP_WanErrorNotify = 14,
|
||||||
PPTP_SetLinkInfo = 15
|
PPTP_SetLinkInfo = 15
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Message structures */
|
/* Message structures */
|
||||||
struct pptpMsgHead {
|
struct pptpMsgHead {
|
||||||
u_int16_t length; /* total length */
|
u_int16_t length; /* total length */
|
||||||
u_int16_t msgType; /* PPTP message type */
|
u_int16_t msgType;/* PPTP message type */
|
||||||
u_int32_t magic; /* magic cookie */
|
u_int32_t magic; /* magic cookie */
|
||||||
u_int16_t type; /* control message type */
|
u_int16_t type; /* control message type */
|
||||||
u_int16_t resv0; /* reserved */
|
u_int16_t resv0; /* reserved */
|
||||||
};
|
};
|
||||||
typedef struct pptpMsgHead *PptpMsgHead;
|
typedef struct pptpMsgHead *PptpMsgHead;
|
||||||
|
|
||||||
struct pptpCodes {
|
struct pptpCodes {
|
||||||
u_int8_t resCode; /* Result Code */
|
u_int8_t resCode;/* Result Code */
|
||||||
u_int8_t errCode; /* Error Code */
|
u_int8_t errCode;/* Error Code */
|
||||||
};
|
};
|
||||||
typedef struct pptpCodes *PptpCode;
|
typedef struct pptpCodes *PptpCode;
|
||||||
|
|
||||||
struct pptpCallIds {
|
struct pptpCallIds {
|
||||||
u_int16_t cid1; /* Call ID field #1 */
|
u_int16_t cid1; /* Call ID field #1 */
|
||||||
u_int16_t cid2; /* Call ID field #2 */
|
u_int16_t cid2; /* Call ID field #2 */
|
||||||
};
|
};
|
||||||
typedef struct pptpCallIds *PptpCallId;
|
typedef struct pptpCallIds *PptpCallId;
|
||||||
|
|
||||||
static PptpCallId AliasVerifyPptp(struct ip *, u_int16_t *);
|
static PptpCallId AliasVerifyPptp(struct ip *, u_int16_t *);
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
AliasHandlePptpOut(struct libalias *la,
|
AliasHandlePptpOut(struct libalias *la,
|
||||||
struct ip *pip, /* IP packet to examine/patch */
|
struct ip *pip, /* IP packet to examine/patch */
|
||||||
struct alias_link *link) /* The PPTP control link */
|
struct alias_link *link)
|
||||||
{
|
{ /* The PPTP control link */
|
||||||
struct alias_link *pptp_link;
|
struct alias_link *pptp_link;
|
||||||
PptpCallId cptr;
|
PptpCallId cptr;
|
||||||
PptpCode codes;
|
PptpCode codes;
|
||||||
u_int16_t ctl_type; /* control message type */
|
u_int16_t ctl_type; /* control message type */
|
||||||
struct tcphdr *tc;
|
struct tcphdr *tc;
|
||||||
|
|
||||||
/* Verify valid PPTP control message */
|
/* Verify valid PPTP control message */
|
||||||
if ((cptr = AliasVerifyPptp(pip, &ctl_type)) == NULL)
|
if ((cptr = AliasVerifyPptp(pip, &ctl_type)) == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Modify certain PPTP messages */
|
|
||||||
switch (ctl_type) {
|
|
||||||
case PPTP_OutCallRequest:
|
|
||||||
case PPTP_OutCallReply:
|
|
||||||
case PPTP_InCallRequest:
|
|
||||||
case PPTP_InCallReply:
|
|
||||||
/* Establish PPTP link for address and Call ID found in control message. */
|
|
||||||
pptp_link = AddPptp(la, GetOriginalAddress(link), GetDestAddress(link),
|
|
||||||
GetAliasAddress(link), cptr->cid1);
|
|
||||||
break;
|
|
||||||
case PPTP_CallClearRequest:
|
|
||||||
case PPTP_CallDiscNotify:
|
|
||||||
/* Find PPTP link for address and Call ID found in control message. */
|
|
||||||
pptp_link = FindPptpOutByCallId(la, GetOriginalAddress(link),
|
|
||||||
GetDestAddress(link),
|
|
||||||
cptr->cid1);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pptp_link != NULL) {
|
|
||||||
int accumulate = cptr->cid1;
|
|
||||||
|
|
||||||
/* alias the Call Id */
|
|
||||||
cptr->cid1 = GetAliasPort(pptp_link);
|
|
||||||
|
|
||||||
/* Compute TCP checksum for revised packet */
|
|
||||||
tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
|
|
||||||
accumulate -= cptr->cid1;
|
|
||||||
ADJUST_CHECKSUM(accumulate, tc->th_sum);
|
|
||||||
|
|
||||||
|
/* Modify certain PPTP messages */
|
||||||
switch (ctl_type) {
|
switch (ctl_type) {
|
||||||
|
case PPTP_OutCallRequest:
|
||||||
case PPTP_OutCallReply:
|
case PPTP_OutCallReply:
|
||||||
|
case PPTP_InCallRequest:
|
||||||
case PPTP_InCallReply:
|
case PPTP_InCallReply:
|
||||||
codes = (PptpCode)(cptr + 1);
|
/*
|
||||||
if (codes->resCode == 1) /* Connection established, */
|
* Establish PPTP link for address and Call ID found in
|
||||||
SetDestCallId(pptp_link, /* note the Peer's Call ID. */
|
* control message.
|
||||||
cptr->cid2);
|
*/
|
||||||
else
|
pptp_link = AddPptp(la, GetOriginalAddress(link), GetDestAddress(link),
|
||||||
SetExpire(pptp_link, 0); /* Connection refused. */
|
GetAliasAddress(link), cptr->cid1);
|
||||||
break;
|
break;
|
||||||
case PPTP_CallDiscNotify: /* Connection closed. */
|
case PPTP_CallClearRequest:
|
||||||
SetExpire(pptp_link, 0);
|
case PPTP_CallDiscNotify:
|
||||||
break;
|
/*
|
||||||
|
* Find PPTP link for address and Call ID found in control
|
||||||
|
* message.
|
||||||
|
*/
|
||||||
|
pptp_link = FindPptpOutByCallId(la, GetOriginalAddress(link),
|
||||||
|
GetDestAddress(link),
|
||||||
|
cptr->cid1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pptp_link != NULL) {
|
||||||
|
int accumulate = cptr->cid1;
|
||||||
|
|
||||||
|
/* alias the Call Id */
|
||||||
|
cptr->cid1 = GetAliasPort(pptp_link);
|
||||||
|
|
||||||
|
/* Compute TCP checksum for revised packet */
|
||||||
|
tc = (struct tcphdr *)((char *)pip + (pip->ip_hl << 2));
|
||||||
|
accumulate -= cptr->cid1;
|
||||||
|
ADJUST_CHECKSUM(accumulate, tc->th_sum);
|
||||||
|
|
||||||
|
switch (ctl_type) {
|
||||||
|
case PPTP_OutCallReply:
|
||||||
|
case PPTP_InCallReply:
|
||||||
|
codes = (PptpCode) (cptr + 1);
|
||||||
|
if (codes->resCode == 1) /* Connection
|
||||||
|
* established, */
|
||||||
|
SetDestCallId(pptp_link, /* note the Peer's Call
|
||||||
|
* ID. */
|
||||||
|
cptr->cid2);
|
||||||
|
else
|
||||||
|
SetExpire(pptp_link, 0); /* Connection refused. */
|
||||||
|
break;
|
||||||
|
case PPTP_CallDiscNotify: /* Connection closed. */
|
||||||
|
SetExpire(pptp_link, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
AliasHandlePptpIn(struct libalias *la,
|
AliasHandlePptpIn(struct libalias *la,
|
||||||
struct ip *pip, /* IP packet to examine/patch */
|
struct ip *pip, /* IP packet to examine/patch */
|
||||||
struct alias_link *link) /* The PPTP control link */
|
struct alias_link *link)
|
||||||
{
|
{ /* The PPTP control link */
|
||||||
struct alias_link *pptp_link;
|
struct alias_link *pptp_link;
|
||||||
PptpCallId cptr;
|
PptpCallId cptr;
|
||||||
u_int16_t *pcall_id;
|
u_int16_t *pcall_id;
|
||||||
u_int16_t ctl_type; /* control message type */
|
u_int16_t ctl_type; /* control message type */
|
||||||
struct tcphdr *tc;
|
struct tcphdr *tc;
|
||||||
|
|
||||||
/* Verify valid PPTP control message */
|
/* Verify valid PPTP control message */
|
||||||
if ((cptr = AliasVerifyPptp(pip, &ctl_type)) == NULL)
|
if ((cptr = AliasVerifyPptp(pip, &ctl_type)) == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Modify certain PPTP messages */
|
/* Modify certain PPTP messages */
|
||||||
switch (ctl_type)
|
switch (ctl_type) {
|
||||||
{
|
case PPTP_InCallConn:
|
||||||
case PPTP_InCallConn:
|
case PPTP_WanErrorNotify:
|
||||||
case PPTP_WanErrorNotify:
|
case PPTP_SetLinkInfo:
|
||||||
case PPTP_SetLinkInfo:
|
pcall_id = &cptr->cid1;
|
||||||
pcall_id = &cptr->cid1;
|
break;
|
||||||
break;
|
case PPTP_OutCallReply:
|
||||||
case PPTP_OutCallReply:
|
case PPTP_InCallReply:
|
||||||
case PPTP_InCallReply:
|
pcall_id = &cptr->cid2;
|
||||||
pcall_id = &cptr->cid2;
|
break;
|
||||||
break;
|
case PPTP_CallDiscNotify: /* Connection closed. */
|
||||||
case PPTP_CallDiscNotify: /* Connection closed. */
|
pptp_link = FindPptpInByCallId(la, GetDestAddress(link),
|
||||||
pptp_link = FindPptpInByCallId(la, GetDestAddress(link),
|
GetAliasAddress(link),
|
||||||
GetAliasAddress(link),
|
cptr->cid1);
|
||||||
cptr->cid1);
|
if (pptp_link != NULL)
|
||||||
if (pptp_link != NULL)
|
SetExpire(pptp_link, 0);
|
||||||
SetExpire(pptp_link, 0);
|
return;
|
||||||
return;
|
default:
|
||||||
default:
|
return;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Find PPTP link for address and Call ID found in PPTP Control Msg */
|
/* Find PPTP link for address and Call ID found in PPTP Control Msg */
|
||||||
pptp_link = FindPptpInByPeerCallId(la, GetDestAddress(link),
|
pptp_link = FindPptpInByPeerCallId(la, GetDestAddress(link),
|
||||||
GetAliasAddress(link),
|
GetAliasAddress(link),
|
||||||
*pcall_id);
|
*pcall_id);
|
||||||
|
|
||||||
if (pptp_link != NULL) {
|
if (pptp_link != NULL) {
|
||||||
int accumulate = *pcall_id;
|
int accumulate = *pcall_id;
|
||||||
|
|
||||||
/* De-alias the Peer's Call Id. */
|
/* De-alias the Peer's Call Id. */
|
||||||
*pcall_id = GetOriginalPort(pptp_link);
|
*pcall_id = GetOriginalPort(pptp_link);
|
||||||
|
|
||||||
/* Compute TCP checksum for modified packet */
|
/* Compute TCP checksum for modified packet */
|
||||||
tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
|
tc = (struct tcphdr *)((char *)pip + (pip->ip_hl << 2));
|
||||||
accumulate -= *pcall_id;
|
accumulate -= *pcall_id;
|
||||||
ADJUST_CHECKSUM(accumulate, tc->th_sum);
|
ADJUST_CHECKSUM(accumulate, tc->th_sum);
|
||||||
|
|
||||||
if (ctl_type == PPTP_OutCallReply || ctl_type == PPTP_InCallReply) {
|
if (ctl_type == PPTP_OutCallReply || ctl_type == PPTP_InCallReply) {
|
||||||
PptpCode codes = (PptpCode)(cptr + 1);
|
PptpCode codes = (PptpCode) (cptr + 1);
|
||||||
|
|
||||||
if (codes->resCode == 1) /* Connection established, */
|
if (codes->resCode == 1) /* Connection
|
||||||
SetDestCallId(pptp_link, /* note the Call ID. */
|
* established, */
|
||||||
cptr->cid1);
|
SetDestCallId(pptp_link, /* note the Call ID. */
|
||||||
else
|
cptr->cid1);
|
||||||
SetExpire(pptp_link, 0); /* Connection refused. */
|
else
|
||||||
}
|
SetExpire(pptp_link, 0); /* Connection refused. */
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static PptpCallId
|
static PptpCallId
|
||||||
AliasVerifyPptp(struct ip *pip, u_int16_t *ptype) /* IP packet to examine/patch */
|
AliasVerifyPptp(struct ip *pip, u_int16_t * ptype)
|
||||||
{
|
{ /* IP packet to examine/patch */
|
||||||
int hlen, tlen, dlen;
|
int hlen, tlen, dlen;
|
||||||
PptpMsgHead hptr;
|
PptpMsgHead hptr;
|
||||||
struct tcphdr *tc;
|
struct tcphdr *tc;
|
||||||
|
|
||||||
/* Calculate some lengths */
|
/* Calculate some lengths */
|
||||||
tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
|
tc = (struct tcphdr *)((char *)pip + (pip->ip_hl << 2));
|
||||||
hlen = (pip->ip_hl + tc->th_off) << 2;
|
hlen = (pip->ip_hl + tc->th_off) << 2;
|
||||||
tlen = ntohs(pip->ip_len);
|
tlen = ntohs(pip->ip_len);
|
||||||
dlen = tlen - hlen;
|
dlen = tlen - hlen;
|
||||||
|
|
||||||
/* Verify data length */
|
/* Verify data length */
|
||||||
if (dlen < (sizeof(struct pptpMsgHead) + sizeof(struct pptpCallIds)))
|
if (dlen < (sizeof(struct pptpMsgHead) + sizeof(struct pptpCallIds)))
|
||||||
return(NULL);
|
return (NULL);
|
||||||
|
|
||||||
/* Move up to PPTP message header */
|
/* Move up to PPTP message header */
|
||||||
hptr = (PptpMsgHead)(((char *) pip) + hlen);
|
hptr = (PptpMsgHead) (((char *)pip) + hlen);
|
||||||
|
|
||||||
/* Return the control message type */
|
/* Return the control message type */
|
||||||
*ptype = ntohs(hptr->type);
|
*ptype = ntohs(hptr->type);
|
||||||
|
|
||||||
/* Verify PPTP Control Message */
|
/* Verify PPTP Control Message */
|
||||||
if ((ntohs(hptr->msgType) != PPTP_CTRL_MSG_TYPE) ||
|
if ((ntohs(hptr->msgType) != PPTP_CTRL_MSG_TYPE) ||
|
||||||
(ntohl(hptr->magic) != PPTP_MAGIC))
|
(ntohl(hptr->magic) != PPTP_MAGIC))
|
||||||
return(NULL);
|
return (NULL);
|
||||||
|
|
||||||
/* Verify data length. */
|
/* Verify data length. */
|
||||||
if ((*ptype == PPTP_OutCallReply || *ptype == PPTP_InCallReply) &&
|
if ((*ptype == PPTP_OutCallReply || *ptype == PPTP_InCallReply) &&
|
||||||
(dlen < sizeof(struct pptpMsgHead) + sizeof(struct pptpCallIds) +
|
(dlen < sizeof(struct pptpMsgHead) + sizeof(struct pptpCallIds) +
|
||||||
sizeof(struct pptpCodes)))
|
sizeof(struct pptpCodes)))
|
||||||
return (NULL);
|
return (NULL);
|
||||||
else
|
else
|
||||||
return (PptpCallId)(hptr + 1);
|
return (PptpCallId) (hptr + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
AliasHandlePptpGreOut(struct libalias *la, struct ip *pip)
|
AliasHandlePptpGreOut(struct libalias *la, struct ip *pip)
|
||||||
{
|
{
|
||||||
GreHdr *gr;
|
GreHdr *gr;
|
||||||
struct alias_link *link;
|
struct alias_link *link;
|
||||||
|
|
||||||
gr = (GreHdr *)((char *)pip + (pip->ip_hl << 2));
|
gr = (GreHdr *) ((char *)pip + (pip->ip_hl << 2));
|
||||||
|
|
||||||
/* Check GRE header bits. */
|
/* Check GRE header bits. */
|
||||||
if ((ntohl(*((u_int32_t *)gr)) & PPTP_INIT_MASK) != PPTP_INIT_VALUE)
|
if ((ntohl(*((u_int32_t *) gr)) & PPTP_INIT_MASK) != PPTP_INIT_VALUE)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
|
||||||
link = FindPptpOutByPeerCallId(la, pip->ip_src, pip->ip_dst, gr->gh_call_id);
|
link = FindPptpOutByPeerCallId(la, pip->ip_src, pip->ip_dst, gr->gh_call_id);
|
||||||
if (link != NULL) {
|
if (link != NULL) {
|
||||||
struct in_addr alias_addr = GetAliasAddress(link);
|
struct in_addr alias_addr = GetAliasAddress(link);
|
||||||
|
|
||||||
/* Change source IP address. */
|
/* Change source IP address. */
|
||||||
DifferentialChecksum(&pip->ip_sum,
|
DifferentialChecksum(&pip->ip_sum,
|
||||||
(u_short *)&alias_addr,
|
(u_short *) & alias_addr,
|
||||||
(u_short *)&pip->ip_src,
|
(u_short *) & pip->ip_src,
|
||||||
2);
|
2);
|
||||||
pip->ip_src = alias_addr;
|
pip->ip_src = alias_addr;
|
||||||
}
|
}
|
||||||
|
return (0);
|
||||||
return (0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
AliasHandlePptpGreIn(struct libalias *la, struct ip *pip)
|
AliasHandlePptpGreIn(struct libalias *la, struct ip *pip)
|
||||||
{
|
{
|
||||||
GreHdr *gr;
|
GreHdr *gr;
|
||||||
struct alias_link *link;
|
struct alias_link *link;
|
||||||
|
|
||||||
gr = (GreHdr *)((char *)pip + (pip->ip_hl << 2));
|
gr = (GreHdr *) ((char *)pip + (pip->ip_hl << 2));
|
||||||
|
|
||||||
/* Check GRE header bits. */
|
/* Check GRE header bits. */
|
||||||
if ((ntohl(*((u_int32_t *)gr)) & PPTP_INIT_MASK) != PPTP_INIT_VALUE)
|
if ((ntohl(*((u_int32_t *) gr)) & PPTP_INIT_MASK) != PPTP_INIT_VALUE)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
|
||||||
link = FindPptpInByPeerCallId(la, pip->ip_src, pip->ip_dst, gr->gh_call_id);
|
link = FindPptpInByPeerCallId(la, pip->ip_src, pip->ip_dst, gr->gh_call_id);
|
||||||
if (link != NULL) {
|
if (link != NULL) {
|
||||||
struct in_addr src_addr = GetOriginalAddress(link);
|
struct in_addr src_addr = GetOriginalAddress(link);
|
||||||
|
|
||||||
/* De-alias the Peer's Call Id. */
|
/* De-alias the Peer's Call Id. */
|
||||||
gr->gh_call_id = GetOriginalPort(link);
|
gr->gh_call_id = GetOriginalPort(link);
|
||||||
|
|
||||||
/* Restore original IP address. */
|
/* Restore original IP address. */
|
||||||
DifferentialChecksum(&pip->ip_sum,
|
DifferentialChecksum(&pip->ip_sum,
|
||||||
(u_short *)&src_addr,
|
(u_short *) & src_addr,
|
||||||
(u_short *)&pip->ip_dst,
|
(u_short *) & pip->ip_dst,
|
||||||
2);
|
2);
|
||||||
pip->ip_dst = src_addr;
|
pip->ip_dst = src_addr;
|
||||||
}
|
}
|
||||||
|
return (0);
|
||||||
return (0);
|
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -60,10 +60,10 @@
|
|||||||
* has answered. The phone then sends back an Open Receive Channel
|
* has answered. The phone then sends back an Open Receive Channel
|
||||||
* Acknowledgement. In this packet, the phone sends its IP address again,
|
* Acknowledgement. In this packet, the phone sends its IP address again,
|
||||||
* and the UDP port over which the voice traffic should flow. These values
|
* and the UDP port over which the voice traffic should flow. These values
|
||||||
* need translation. Right after the Open Receive Channel Acknowledgement,
|
* need translation. Right after the Open Receive Channel Acknowledgement,
|
||||||
* the Call Manager sends a Start Media Transmission message indicating the
|
* the Call Manager sends a Start Media Transmission message indicating the
|
||||||
* call is connected. This message contains the IP address and UDP port
|
* call is connected. This message contains the IP address and UDP port
|
||||||
* number of the remote (called) party. Once this message is translated, the
|
* number of the remote (called) party. Once this message is translated, the
|
||||||
* call can commence. The called part sends the first UDP packet to the
|
* call can commence. The called part sends the first UDP packet to the
|
||||||
* calling phone at the pre-arranged UDP port in the Open Receive Channel
|
* calling phone at the pre-arranged UDP port in the Open Receive Channel
|
||||||
* Acknowledgement.
|
* Acknowledgement.
|
||||||
@ -81,258 +81,258 @@
|
|||||||
#define START_MEDIATX 0x0000008a
|
#define START_MEDIATX 0x0000008a
|
||||||
|
|
||||||
struct skinny_header {
|
struct skinny_header {
|
||||||
u_int32_t len;
|
u_int32_t len;
|
||||||
u_int32_t reserved;
|
u_int32_t reserved;
|
||||||
u_int32_t msgId;
|
u_int32_t msgId;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RegisterMessage {
|
struct RegisterMessage {
|
||||||
u_int32_t msgId;
|
u_int32_t msgId;
|
||||||
char devName[16];
|
char devName [16];
|
||||||
u_int32_t uid;
|
u_int32_t uid;
|
||||||
u_int32_t instance;
|
u_int32_t instance;
|
||||||
u_int32_t ipAddr;
|
u_int32_t ipAddr;
|
||||||
u_char devType;
|
u_char devType;
|
||||||
u_int32_t maxStreams;
|
u_int32_t maxStreams;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IpPortMessage {
|
struct IpPortMessage {
|
||||||
u_int32_t msgId;
|
u_int32_t msgId;
|
||||||
u_int32_t stationIpPort; /* Note: Skinny uses 32-bit port
|
u_int32_t stationIpPort; /* Note: Skinny uses 32-bit port
|
||||||
* numbers */
|
* numbers */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct OpenReceiveChannelAck {
|
struct OpenReceiveChannelAck {
|
||||||
u_int32_t msgId;
|
u_int32_t msgId;
|
||||||
u_int32_t status;
|
u_int32_t status;
|
||||||
u_int32_t ipAddr;
|
u_int32_t ipAddr;
|
||||||
u_int32_t port;
|
u_int32_t port;
|
||||||
u_int32_t passThruPartyID;
|
u_int32_t passThruPartyID;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct StartMediaTransmission {
|
struct StartMediaTransmission {
|
||||||
u_int32_t msgId;
|
u_int32_t msgId;
|
||||||
u_int32_t conferenceID;
|
u_int32_t conferenceID;
|
||||||
u_int32_t passThruPartyID;
|
u_int32_t passThruPartyID;
|
||||||
u_int32_t remoteIpAddr;
|
u_int32_t remoteIpAddr;
|
||||||
u_int32_t remotePort;
|
u_int32_t remotePort;
|
||||||
u_int32_t MSPacket;
|
u_int32_t MSPacket;
|
||||||
u_int32_t payloadCap;
|
u_int32_t payloadCap;
|
||||||
u_int32_t precedence;
|
u_int32_t precedence;
|
||||||
u_int32_t silenceSuppression;
|
u_int32_t silenceSuppression;
|
||||||
u_short maxFramesPerPacket;
|
u_short maxFramesPerPacket;
|
||||||
u_int32_t G723BitRate;
|
u_int32_t G723BitRate;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ClientToServer = 0,
|
ClientToServer = 0,
|
||||||
ServerToClient = 1
|
ServerToClient = 1
|
||||||
} ConvDirection;
|
} ConvDirection;
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
alias_skinny_reg_msg(struct RegisterMessage *reg_msg, struct ip *pip,
|
alias_skinny_reg_msg(struct RegisterMessage *reg_msg, struct ip *pip,
|
||||||
struct tcphdr *tc, struct alias_link *link,
|
struct tcphdr *tc, struct alias_link *link,
|
||||||
ConvDirection direction)
|
ConvDirection direction)
|
||||||
{
|
{
|
||||||
reg_msg->ipAddr = (u_int32_t) GetAliasAddress(link).s_addr;
|
reg_msg->ipAddr = (u_int32_t) GetAliasAddress(link).s_addr;
|
||||||
|
|
||||||
tc->th_sum = 0;
|
tc->th_sum = 0;
|
||||||
tc->th_sum = TcpChecksum(pip);
|
tc->th_sum = TcpChecksum(pip);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
alias_skinny_startmedia(struct StartMediaTransmission *start_media,
|
alias_skinny_startmedia(struct StartMediaTransmission *start_media,
|
||||||
struct ip *pip, struct tcphdr *tc,
|
struct ip *pip, struct tcphdr *tc,
|
||||||
struct alias_link *link, u_int32_t localIpAddr,
|
struct alias_link *link, u_int32_t localIpAddr,
|
||||||
ConvDirection direction)
|
ConvDirection direction)
|
||||||
{
|
{
|
||||||
struct in_addr dst, src;
|
struct in_addr dst, src;
|
||||||
|
|
||||||
dst.s_addr = start_media->remoteIpAddr;
|
dst.s_addr = start_media->remoteIpAddr;
|
||||||
src.s_addr = localIpAddr;
|
src.s_addr = localIpAddr;
|
||||||
|
|
||||||
/* XXX I should probably handle in bound global translations as well. */
|
/*
|
||||||
|
* XXX I should probably handle in bound global translations as
|
||||||
|
* well.
|
||||||
|
*/
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
alias_skinny_port_msg(struct IpPortMessage *port_msg, struct ip *pip,
|
alias_skinny_port_msg(struct IpPortMessage *port_msg, struct ip *pip,
|
||||||
struct tcphdr *tc, struct alias_link *link,
|
struct tcphdr *tc, struct alias_link *link,
|
||||||
ConvDirection direction)
|
ConvDirection direction)
|
||||||
{
|
{
|
||||||
port_msg->stationIpPort = (u_int32_t) ntohs(GetAliasPort(link));
|
port_msg->stationIpPort = (u_int32_t) ntohs(GetAliasPort(link));
|
||||||
|
|
||||||
tc->th_sum = 0;
|
tc->th_sum = 0;
|
||||||
tc->th_sum = TcpChecksum(pip);
|
tc->th_sum = TcpChecksum(pip);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
alias_skinny_opnrcvch_ack(struct libalias *la, struct OpenReceiveChannelAck *opnrcvch_ack,
|
alias_skinny_opnrcvch_ack(struct libalias *la, struct OpenReceiveChannelAck *opnrcvch_ack,
|
||||||
struct ip * pip, struct tcphdr *tc,
|
struct ip *pip, struct tcphdr *tc,
|
||||||
struct alias_link *link, u_int32_t *localIpAddr,
|
struct alias_link *link, u_int32_t * localIpAddr,
|
||||||
ConvDirection direction)
|
ConvDirection direction)
|
||||||
{
|
{
|
||||||
struct in_addr null_addr;
|
struct in_addr null_addr;
|
||||||
struct alias_link *opnrcv_link;
|
struct alias_link *opnrcv_link;
|
||||||
u_int32_t localPort;
|
u_int32_t localPort;
|
||||||
|
|
||||||
*localIpAddr = (u_int32_t) opnrcvch_ack->ipAddr;
|
*localIpAddr = (u_int32_t) opnrcvch_ack->ipAddr;
|
||||||
localPort = opnrcvch_ack->port;
|
localPort = opnrcvch_ack->port;
|
||||||
|
|
||||||
null_addr.s_addr = INADDR_ANY;
|
null_addr.s_addr = INADDR_ANY;
|
||||||
opnrcv_link = FindUdpTcpOut(la, pip->ip_src, null_addr,
|
opnrcv_link = FindUdpTcpOut(la, pip->ip_src, null_addr,
|
||||||
htons((u_short) opnrcvch_ack->port), 0,
|
htons((u_short) opnrcvch_ack->port), 0,
|
||||||
IPPROTO_UDP, 1);
|
IPPROTO_UDP, 1);
|
||||||
opnrcvch_ack->ipAddr = (u_int32_t) GetAliasAddress(opnrcv_link).s_addr;
|
opnrcvch_ack->ipAddr = (u_int32_t) GetAliasAddress(opnrcv_link).s_addr;
|
||||||
opnrcvch_ack->port = (u_int32_t) ntohs(GetAliasPort(opnrcv_link));
|
opnrcvch_ack->port = (u_int32_t) ntohs(GetAliasPort(opnrcv_link));
|
||||||
|
|
||||||
tc->th_sum = 0;
|
tc->th_sum = 0;
|
||||||
tc->th_sum = TcpChecksum(pip);
|
tc->th_sum = TcpChecksum(pip);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
AliasHandleSkinny(struct libalias *la, struct ip *pip, struct alias_link *link)
|
AliasHandleSkinny(struct libalias *la, struct ip *pip, struct alias_link *link)
|
||||||
{
|
{
|
||||||
int hlen, tlen, dlen;
|
int hlen, tlen, dlen;
|
||||||
struct tcphdr *tc;
|
struct tcphdr *tc;
|
||||||
u_int32_t msgId, len, t, lip;
|
u_int32_t msgId, len, t, lip;
|
||||||
struct skinny_header *sd;
|
struct skinny_header *sd;
|
||||||
int orig_len, skinny_hdr_len = sizeof(struct skinny_header);
|
int orig_len, skinny_hdr_len = sizeof(struct skinny_header);
|
||||||
ConvDirection direction;
|
ConvDirection direction;
|
||||||
|
|
||||||
tc = (struct tcphdr *) ((char *)pip + (pip->ip_hl << 2));
|
tc = (struct tcphdr *)((char *)pip + (pip->ip_hl << 2));
|
||||||
hlen = (pip->ip_hl + tc->th_off) << 2;
|
hlen = (pip->ip_hl + tc->th_off) << 2;
|
||||||
tlen = ntohs(pip->ip_len);
|
tlen = ntohs(pip->ip_len);
|
||||||
dlen = tlen - hlen;
|
dlen = tlen - hlen;
|
||||||
|
|
||||||
sd = (struct skinny_header *) ((char *)pip + hlen);
|
sd = (struct skinny_header *)((char *)pip + hlen);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX This direction is reserved for future use. I still need to
|
* XXX This direction is reserved for future use. I still need to
|
||||||
* handle the scenario where the call manager is on the inside, and
|
* handle the scenario where the call manager is on the inside, and
|
||||||
* the calling phone is on the global outside.
|
* the calling phone is on the global outside.
|
||||||
*/
|
*/
|
||||||
if (ntohs(tc->th_dport) == la->skinnyPort) {
|
if (ntohs(tc->th_dport) == la->skinnyPort) {
|
||||||
direction = ClientToServer;
|
direction = ClientToServer;
|
||||||
} else if (ntohs(tc->th_sport) == la->skinnyPort) {
|
} else if (ntohs(tc->th_sport) == la->skinnyPort) {
|
||||||
direction = ServerToClient;
|
direction = ServerToClient;
|
||||||
} else {
|
} else {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"PacketAlias/Skinny: Invalid port number, not a Skinny packet\n");
|
"PacketAlias/Skinny: Invalid port number, not a Skinny packet\n");
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
orig_len = dlen;
|
orig_len = dlen;
|
||||||
/*
|
/*
|
||||||
* Skinny packets can contain many messages. We need to loop through
|
* Skinny packets can contain many messages. We need to loop
|
||||||
* the packet using len to determine message boundaries. This comes
|
* through the packet using len to determine message boundaries.
|
||||||
* into play big time with port messages being in the same packet as
|
* This comes into play big time with port messages being in the
|
||||||
* register messages. Also, open receive channel acks are
|
* same packet as register messages. Also, open receive channel
|
||||||
* usually buried in a pakcet some 400 bytes long.
|
* acks are usually buried in a pakcet some 400 bytes long.
|
||||||
*/
|
*/
|
||||||
while (dlen >= skinny_hdr_len) {
|
while (dlen >= skinny_hdr_len) {
|
||||||
len = (sd->len);
|
len = (sd->len);
|
||||||
msgId = (sd->msgId);
|
msgId = (sd->msgId);
|
||||||
t = len;
|
t = len;
|
||||||
|
|
||||||
if (t < 0 || t > orig_len || t > dlen) {
|
if (t < 0 || t > orig_len || t > dlen) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"PacketAlias/Skinny: Not a skinny packet, invalid length \n");
|
"PacketAlias/Skinny: Not a skinny packet, invalid length \n");
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switch (msgId) {
|
switch (msgId) {
|
||||||
case REG_MSG:
|
case REG_MSG: {
|
||||||
{
|
struct RegisterMessage *reg_mesg;
|
||||||
struct RegisterMessage *reg_mesg;
|
|
||||||
|
|
||||||
if (len < sizeof(struct RegisterMessage)) {
|
if (len < sizeof(struct RegisterMessage)) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"PacketAlias/Skinny: Not a skinny packet, bad registration message\n");
|
"PacketAlias/Skinny: Not a skinny packet, bad registration message\n");
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
reg_mesg = (struct RegisterMessage *) & sd->msgId;
|
reg_mesg = (struct RegisterMessage *)&sd->msgId;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"PacketAlias/Skinny: Received a register message");
|
"PacketAlias/Skinny: Received a register message");
|
||||||
#endif
|
#endif
|
||||||
alias_skinny_reg_msg(reg_mesg, pip, tc, link, direction);
|
alias_skinny_reg_msg(reg_mesg, pip, tc, link, direction);
|
||||||
}
|
break;
|
||||||
break;
|
}
|
||||||
case IP_PORT_MSG:
|
case IP_PORT_MSG: {
|
||||||
{
|
struct IpPortMessage *port_mesg;
|
||||||
struct IpPortMessage *port_mesg;
|
|
||||||
if (len < sizeof(struct IpPortMessage)) {
|
|
||||||
#ifdef DEBUG
|
|
||||||
fprintf(stderr,
|
|
||||||
"PacketAlias/Skinny: Not a skinny packet, port message\n");
|
|
||||||
#endif
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#ifdef DEBUG
|
|
||||||
fprintf(stderr
|
|
||||||
"PacketAlias/Skinny: Received ipport message\n");
|
|
||||||
#endif
|
|
||||||
port_mesg = (struct IpPortMessage *) & sd->msgId;
|
|
||||||
alias_skinny_port_msg(port_mesg, pip, tc, link, direction);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case OPNRCVCH_ACK:
|
|
||||||
{
|
|
||||||
struct OpenReceiveChannelAck *opnrcvchn_ack;
|
|
||||||
|
|
||||||
if (len < sizeof(struct OpenReceiveChannelAck)) {
|
if (len < sizeof(struct IpPortMessage)) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"PacketAlias/Skinny: Not a skinny packet, packet,OpnRcvChnAckMsg\n");
|
"PacketAlias/Skinny: Not a skinny packet, port message\n");
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr,
|
fprintf(stderr
|
||||||
"PacketAlias/Skinny: Received open rcv channel msg\n");
|
"PacketAlias/Skinny: Received ipport message\n");
|
||||||
#endif
|
#endif
|
||||||
opnrcvchn_ack = (struct OpenReceiveChannelAck *) & sd->msgId;
|
port_mesg = (struct IpPortMessage *)&sd->msgId;
|
||||||
alias_skinny_opnrcvch_ack(la, opnrcvchn_ack, pip, tc, link, &lip, direction);
|
alias_skinny_port_msg(port_mesg, pip, tc, link, direction);
|
||||||
}
|
break;
|
||||||
break;
|
}
|
||||||
case START_MEDIATX:
|
case OPNRCVCH_ACK: {
|
||||||
{
|
struct OpenReceiveChannelAck *opnrcvchn_ack;
|
||||||
struct StartMediaTransmission *startmedia_tx;
|
|
||||||
|
|
||||||
if (len < sizeof(struct StartMediaTransmission)) {
|
if (len < sizeof(struct OpenReceiveChannelAck)) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"PacketAlias/Skinny: Not a skinny packet,StartMediaTx Message\n");
|
"PacketAlias/Skinny: Not a skinny packet, packet,OpnRcvChnAckMsg\n");
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"PacketAlias/Skinny: Received start media trans msg\n");
|
"PacketAlias/Skinny: Received open rcv channel msg\n");
|
||||||
#endif
|
#endif
|
||||||
startmedia_tx = (struct StartMediaTransmission *) & sd->msgId;
|
opnrcvchn_ack = (struct OpenReceiveChannelAck *)&sd->msgId;
|
||||||
alias_skinny_startmedia(startmedia_tx, pip, tc, link, lip, direction);
|
alias_skinny_opnrcvch_ack(la, opnrcvchn_ack, pip, tc, link, &lip, direction);
|
||||||
}
|
break;
|
||||||
break;
|
}
|
||||||
default:
|
case START_MEDIATX: {
|
||||||
break;
|
struct StartMediaTransmission *startmedia_tx;
|
||||||
}
|
|
||||||
/* Place the pointer at the next message in the packet. */
|
if (len < sizeof(struct StartMediaTransmission)) {
|
||||||
dlen -= len + (skinny_hdr_len - sizeof(msgId));
|
#ifdef DEBUG
|
||||||
sd = (struct skinny_header *) (((char *)&sd->msgId) + len);
|
fprintf(stderr,
|
||||||
}
|
"PacketAlias/Skinny: Not a skinny packet,StartMediaTx Message\n");
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf(stderr,
|
||||||
|
"PacketAlias/Skinny: Received start media trans msg\n");
|
||||||
|
#endif
|
||||||
|
startmedia_tx = (struct StartMediaTransmission *)&sd->msgId;
|
||||||
|
alias_skinny_startmedia(startmedia_tx, pip, tc, link, lip, direction);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* Place the pointer at the next message in the packet. */
|
||||||
|
dlen -= len + (skinny_hdr_len - sizeof(msgId));
|
||||||
|
sd = (struct skinny_header *)(((char *)&sd->msgId) + len);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -118,316 +118,326 @@ __FBSDID("$FreeBSD$");
|
|||||||
static int
|
static int
|
||||||
search_string(char *data, int dlen, const char *search_str)
|
search_string(char *data, int dlen, const char *search_str)
|
||||||
{
|
{
|
||||||
int i, j, k;
|
int i, j, k;
|
||||||
int search_str_len;
|
int search_str_len;
|
||||||
|
|
||||||
search_str_len = strlen(search_str);
|
search_str_len = strlen(search_str);
|
||||||
for (i = 0; i < dlen - search_str_len; i++) {
|
for (i = 0; i < dlen - search_str_len; i++) {
|
||||||
for (j = i, k = 0; j < dlen - search_str_len; j++, k++) {
|
for (j = i, k = 0; j < dlen - search_str_len; j++, k++) {
|
||||||
if (data[j] != search_str[k] &&
|
if (data[j] != search_str[k] &&
|
||||||
data[j] != search_str[k] - ('a' - 'A')) {
|
data[j] != search_str[k] - ('a' - 'A')) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (k == search_str_len - 1) {
|
if (k == search_str_len - 1) {
|
||||||
return j + 1;
|
return j + 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
return -1;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
alias_rtsp_out(struct libalias *la, struct ip *pip,
|
alias_rtsp_out(struct libalias *la, struct ip *pip,
|
||||||
struct alias_link *link,
|
struct alias_link *link,
|
||||||
char *data,
|
char *data,
|
||||||
const char *port_str)
|
const char *port_str)
|
||||||
{
|
{
|
||||||
int hlen, tlen, dlen;
|
int hlen, tlen, dlen;
|
||||||
struct tcphdr *tc;
|
struct tcphdr *tc;
|
||||||
int i, j, pos, state, port_dlen, new_dlen, delta;
|
int i, j, pos, state, port_dlen, new_dlen, delta;
|
||||||
u_short p[2], new_len;
|
u_short p[2], new_len;
|
||||||
u_short sport, eport, base_port;
|
u_short sport, eport, base_port;
|
||||||
u_short salias = 0, ealias = 0, base_alias = 0;
|
u_short salias = 0, ealias = 0, base_alias = 0;
|
||||||
const char *transport_str = "transport:";
|
const char *transport_str = "transport:";
|
||||||
char newdata[2048], *port_data, *port_newdata, stemp[80];
|
char newdata[2048], *port_data, *port_newdata, stemp[80];
|
||||||
int links_created = 0, pkt_updated = 0;
|
int links_created = 0, pkt_updated = 0;
|
||||||
struct alias_link *rtsp_link = NULL;
|
struct alias_link *rtsp_link = NULL;
|
||||||
struct in_addr null_addr;
|
struct in_addr null_addr;
|
||||||
|
|
||||||
/* Calculate data length of TCP packet */
|
/* Calculate data length of TCP packet */
|
||||||
tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
|
tc = (struct tcphdr *)((char *)pip + (pip->ip_hl << 2));
|
||||||
hlen = (pip->ip_hl + tc->th_off) << 2;
|
hlen = (pip->ip_hl + tc->th_off) << 2;
|
||||||
tlen = ntohs(pip->ip_len);
|
tlen = ntohs(pip->ip_len);
|
||||||
dlen = tlen - hlen;
|
dlen = tlen - hlen;
|
||||||
|
|
||||||
/* Find keyword, "Transport: " */
|
/* Find keyword, "Transport: " */
|
||||||
pos = search_string(data, dlen, transport_str);
|
pos = search_string(data, dlen, transport_str);
|
||||||
if (pos < 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
port_data = data + pos;
|
|
||||||
port_dlen = dlen - pos;
|
|
||||||
|
|
||||||
memcpy(newdata, data, pos);
|
|
||||||
port_newdata = newdata + pos;
|
|
||||||
|
|
||||||
while (port_dlen > strlen(port_str)) {
|
|
||||||
/* Find keyword, appropriate port string */
|
|
||||||
pos = search_string(port_data, port_dlen, port_str);
|
|
||||||
if (pos < 0) {
|
if (pos < 0) {
|
||||||
break;
|
return -1;
|
||||||
}
|
}
|
||||||
|
port_data = data + pos;
|
||||||
|
port_dlen = dlen - pos;
|
||||||
|
|
||||||
memcpy (port_newdata, port_data, pos + 1);
|
memcpy(newdata, data, pos);
|
||||||
port_newdata += (pos + 1);
|
port_newdata = newdata + pos;
|
||||||
|
|
||||||
p[0] = p[1] = 0;
|
while (port_dlen > strlen(port_str)) {
|
||||||
sport = eport = 0;
|
/* Find keyword, appropriate port string */
|
||||||
state = 0;
|
pos = search_string(port_data, port_dlen, port_str);
|
||||||
for (i = pos; i < port_dlen; i++) {
|
if (pos < 0) {
|
||||||
switch(state) {
|
break;
|
||||||
case 0:
|
|
||||||
if (port_data[i] == '=') {
|
|
||||||
state++;
|
|
||||||
}
|
}
|
||||||
break;
|
memcpy(port_newdata, port_data, pos + 1);
|
||||||
case 1:
|
port_newdata += (pos + 1);
|
||||||
if (ISDIGIT(port_data[i])) {
|
|
||||||
p[0] = p[0] * 10 + port_data[i] - '0';
|
|
||||||
} else {
|
|
||||||
if (port_data[i] == ';') {
|
|
||||||
state = 3;
|
|
||||||
}
|
|
||||||
if (port_data[i] == '-') {
|
|
||||||
state++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
if (ISDIGIT(port_data[i])) {
|
|
||||||
p[1] = p[1] * 10 + port_data[i] - '0';
|
|
||||||
} else {
|
|
||||||
state++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
base_port = p[0];
|
|
||||||
sport = htons(p[0]);
|
|
||||||
eport = htons(p[1]);
|
|
||||||
|
|
||||||
if (!links_created) {
|
p[0] = p[1] = 0;
|
||||||
|
sport = eport = 0;
|
||||||
|
state = 0;
|
||||||
|
for (i = pos; i < port_dlen; i++) {
|
||||||
|
switch (state) {
|
||||||
|
case 0:
|
||||||
|
if (port_data[i] == '=') {
|
||||||
|
state++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (ISDIGIT(port_data[i])) {
|
||||||
|
p[0] = p[0] * 10 + port_data[i] - '0';
|
||||||
|
} else {
|
||||||
|
if (port_data[i] == ';') {
|
||||||
|
state = 3;
|
||||||
|
}
|
||||||
|
if (port_data[i] == '-') {
|
||||||
|
state++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (ISDIGIT(port_data[i])) {
|
||||||
|
p[1] = p[1] * 10 + port_data[i] - '0';
|
||||||
|
} else {
|
||||||
|
state++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
base_port = p[0];
|
||||||
|
sport = htons(p[0]);
|
||||||
|
eport = htons(p[1]);
|
||||||
|
|
||||||
links_created = 1;
|
if (!links_created) {
|
||||||
/* Find an even numbered port number base that
|
|
||||||
satisfies the contiguous number of ports we need */
|
links_created = 1;
|
||||||
null_addr.s_addr = 0;
|
/*
|
||||||
if (0 == (salias = FindNewPortGroup(la, null_addr,
|
* Find an even numbered port
|
||||||
FindAliasAddress(la, pip->ip_src),
|
* number base that satisfies the
|
||||||
sport, 0,
|
* contiguous number of ports we
|
||||||
RTSP_PORT_GROUP,
|
* need
|
||||||
IPPROTO_UDP, 1))) {
|
*/
|
||||||
|
null_addr.s_addr = 0;
|
||||||
|
if (0 == (salias = FindNewPortGroup(la, null_addr,
|
||||||
|
FindAliasAddress(la, pip->ip_src),
|
||||||
|
sport, 0,
|
||||||
|
RTSP_PORT_GROUP,
|
||||||
|
IPPROTO_UDP, 1))) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"PacketAlias/RTSP: Cannot find contiguous RTSP data ports\n");
|
"PacketAlias/RTSP: Cannot find contiguous RTSP data ports\n");
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
base_alias = ntohs(salias);
|
base_alias = ntohs(salias);
|
||||||
for (j = 0; j < RTSP_PORT_GROUP; j++) {
|
for (j = 0; j < RTSP_PORT_GROUP; j++) {
|
||||||
/* Establish link to port found in RTSP packet */
|
/*
|
||||||
rtsp_link = FindRtspOut(la, GetOriginalAddress(link), null_addr,
|
* Establish link
|
||||||
htons(base_port + j), htons(base_alias + j),
|
* to port found in
|
||||||
IPPROTO_UDP);
|
* RTSP packet
|
||||||
if (rtsp_link != NULL) {
|
*/
|
||||||
|
rtsp_link = FindRtspOut(la, GetOriginalAddress(link), null_addr,
|
||||||
|
htons(base_port + j), htons(base_alias + j),
|
||||||
|
IPPROTO_UDP);
|
||||||
|
if (rtsp_link != NULL) {
|
||||||
#ifndef NO_FW_PUNCH
|
#ifndef NO_FW_PUNCH
|
||||||
/* Punch hole in firewall */
|
/*
|
||||||
PunchFWHole(rtsp_link);
|
* Punch
|
||||||
|
* hole in
|
||||||
|
* firewall
|
||||||
|
*/
|
||||||
|
PunchFWHole(rtsp_link);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"PacketAlias/RTSP: Cannot allocate RTSP data ports\n");
|
"PacketAlias/RTSP: Cannot allocate RTSP data ports\n");
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ealias = htons(base_alias + (RTSP_PORT_GROUP - 1));
|
ealias = htons(base_alias + (RTSP_PORT_GROUP - 1));
|
||||||
|
}
|
||||||
|
if (salias && rtsp_link) {
|
||||||
|
|
||||||
|
pkt_updated = 1;
|
||||||
|
|
||||||
|
/* Copy into IP packet */
|
||||||
|
sprintf(stemp, "%d", ntohs(salias));
|
||||||
|
memcpy(port_newdata, stemp, strlen(stemp));
|
||||||
|
port_newdata += strlen(stemp);
|
||||||
|
|
||||||
|
if (eport != 0) {
|
||||||
|
*port_newdata = '-';
|
||||||
|
port_newdata++;
|
||||||
|
|
||||||
|
/* Copy into IP packet */
|
||||||
|
sprintf(stemp, "%d", ntohs(ealias));
|
||||||
|
memcpy(port_newdata, stemp, strlen(stemp));
|
||||||
|
port_newdata += strlen(stemp);
|
||||||
|
}
|
||||||
|
*port_newdata = ';';
|
||||||
|
port_newdata++;
|
||||||
|
}
|
||||||
|
state++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (state > 3) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
port_data += i;
|
||||||
if (salias && rtsp_link) {
|
port_dlen -= i;
|
||||||
|
|
||||||
pkt_updated = 1;
|
|
||||||
|
|
||||||
/* Copy into IP packet */
|
|
||||||
sprintf(stemp, "%d", ntohs(salias));
|
|
||||||
memcpy(port_newdata, stemp, strlen(stemp));
|
|
||||||
port_newdata += strlen(stemp);
|
|
||||||
|
|
||||||
if (eport != 0) {
|
|
||||||
*port_newdata = '-';
|
|
||||||
port_newdata++;
|
|
||||||
|
|
||||||
/* Copy into IP packet */
|
|
||||||
sprintf(stemp, "%d", ntohs(ealias));
|
|
||||||
memcpy(port_newdata, stemp, strlen(stemp));
|
|
||||||
port_newdata += strlen(stemp);
|
|
||||||
}
|
|
||||||
|
|
||||||
*port_newdata = ';';
|
|
||||||
port_newdata++;
|
|
||||||
}
|
|
||||||
state++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (state > 3) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
port_data += i;
|
|
||||||
port_dlen -= i;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!pkt_updated)
|
if (!pkt_updated)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
memcpy (port_newdata, port_data, port_dlen);
|
memcpy(port_newdata, port_data, port_dlen);
|
||||||
port_newdata += port_dlen;
|
port_newdata += port_dlen;
|
||||||
*port_newdata = '\0';
|
*port_newdata = '\0';
|
||||||
|
|
||||||
/* Create new packet */
|
/* Create new packet */
|
||||||
new_dlen = port_newdata - newdata;
|
new_dlen = port_newdata - newdata;
|
||||||
memcpy (data, newdata, new_dlen);
|
memcpy(data, newdata, new_dlen);
|
||||||
|
|
||||||
SetAckModified(link);
|
SetAckModified(link);
|
||||||
delta = GetDeltaSeqOut(pip, link);
|
delta = GetDeltaSeqOut(pip, link);
|
||||||
AddSeq(pip, link, delta + new_dlen - dlen);
|
AddSeq(pip, link, delta + new_dlen - dlen);
|
||||||
|
|
||||||
new_len = htons(hlen + new_dlen);
|
new_len = htons(hlen + new_dlen);
|
||||||
DifferentialChecksum(&pip->ip_sum,
|
DifferentialChecksum(&pip->ip_sum,
|
||||||
&new_len,
|
&new_len,
|
||||||
&pip->ip_len,
|
&pip->ip_len,
|
||||||
1);
|
1);
|
||||||
pip->ip_len = new_len;
|
pip->ip_len = new_len;
|
||||||
|
|
||||||
tc->th_sum = 0;
|
tc->th_sum = 0;
|
||||||
tc->th_sum = TcpChecksum(pip);
|
tc->th_sum = TcpChecksum(pip);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Support the protocol used by early versions of RealPlayer */
|
/* Support the protocol used by early versions of RealPlayer */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
alias_pna_out(struct libalias *la, struct ip *pip,
|
alias_pna_out(struct libalias *la, struct ip *pip,
|
||||||
struct alias_link *link,
|
struct alias_link *link,
|
||||||
char *data,
|
char *data,
|
||||||
int dlen)
|
int dlen)
|
||||||
{
|
{
|
||||||
struct alias_link *pna_links;
|
struct alias_link *pna_links;
|
||||||
u_short msg_id, msg_len;
|
u_short msg_id, msg_len;
|
||||||
char *work;
|
char *work;
|
||||||
u_short alias_port, port;
|
u_short alias_port, port;
|
||||||
struct tcphdr *tc;
|
struct tcphdr *tc;
|
||||||
|
|
||||||
work = data;
|
work = data;
|
||||||
work += 5;
|
work += 5;
|
||||||
while (work + 4 < data + dlen) {
|
while (work + 4 < data + dlen) {
|
||||||
memcpy(&msg_id, work, 2);
|
memcpy(&msg_id, work, 2);
|
||||||
work += 2;
|
work += 2;
|
||||||
memcpy(&msg_len, work, 2);
|
memcpy(&msg_len, work, 2);
|
||||||
work += 2;
|
work += 2;
|
||||||
if (ntohs(msg_id) == 0) {
|
if (ntohs(msg_id) == 0) {
|
||||||
/* end of options */
|
/* end of options */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if ((ntohs(msg_id) == 1) || (ntohs(msg_id) == 7)) {
|
if ((ntohs(msg_id) == 1) || (ntohs(msg_id) == 7)) {
|
||||||
memcpy(&port, work, 2);
|
memcpy(&port, work, 2);
|
||||||
pna_links = FindUdpTcpOut(la, pip->ip_src, GetDestAddress(link),
|
pna_links = FindUdpTcpOut(la, pip->ip_src, GetDestAddress(link),
|
||||||
port, 0, IPPROTO_UDP, 1);
|
port, 0, IPPROTO_UDP, 1);
|
||||||
if (pna_links != NULL) {
|
if (pna_links != NULL) {
|
||||||
#ifndef NO_FW_PUNCH
|
#ifndef NO_FW_PUNCH
|
||||||
/* Punch hole in firewall */
|
/* Punch hole in firewall */
|
||||||
PunchFWHole(pna_links);
|
PunchFWHole(pna_links);
|
||||||
#endif
|
#endif
|
||||||
tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
|
tc = (struct tcphdr *)((char *)pip + (pip->ip_hl << 2));
|
||||||
alias_port = GetAliasPort(pna_links);
|
alias_port = GetAliasPort(pna_links);
|
||||||
memcpy(work, &alias_port, 2);
|
memcpy(work, &alias_port, 2);
|
||||||
|
|
||||||
/* Compute TCP checksum for revised packet */
|
/* Compute TCP checksum for revised packet */
|
||||||
tc->th_sum = 0;
|
tc->th_sum = 0;
|
||||||
tc->th_sum = TcpChecksum(pip);
|
tc->th_sum = TcpChecksum(pip);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
work += ntohs(msg_len);
|
||||||
}
|
}
|
||||||
work += ntohs(msg_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
AliasHandleRtspOut(struct libalias *la, struct ip *pip, struct alias_link *link, int maxpacketsize)
|
AliasHandleRtspOut(struct libalias *la, struct ip *pip, struct alias_link *link, int maxpacketsize)
|
||||||
{
|
{
|
||||||
int hlen, tlen, dlen;
|
int hlen, tlen, dlen;
|
||||||
struct tcphdr *tc;
|
struct tcphdr *tc;
|
||||||
char *data;
|
char *data;
|
||||||
const char *setup = "SETUP", *pna = "PNA", *str200 = "200";
|
const char *setup = "SETUP", *pna = "PNA", *str200 = "200";
|
||||||
const char *okstr = "OK", *client_port_str = "client_port";
|
const char *okstr = "OK", *client_port_str = "client_port";
|
||||||
const char *server_port_str = "server_port";
|
const char *server_port_str = "server_port";
|
||||||
int i, parseOk;
|
int i, parseOk;
|
||||||
|
|
||||||
tc = (struct tcphdr *)((char *)pip + (pip->ip_hl << 2));
|
tc = (struct tcphdr *)((char *)pip + (pip->ip_hl << 2));
|
||||||
hlen = (pip->ip_hl + tc->th_off) << 2;
|
hlen = (pip->ip_hl + tc->th_off) << 2;
|
||||||
tlen = ntohs(pip->ip_len);
|
tlen = ntohs(pip->ip_len);
|
||||||
dlen = tlen - hlen;
|
dlen = tlen - hlen;
|
||||||
|
|
||||||
data = (char*)pip;
|
data = (char *)pip;
|
||||||
data += hlen;
|
data += hlen;
|
||||||
|
|
||||||
/* When aliasing a client, check for the SETUP request */
|
/* When aliasing a client, check for the SETUP request */
|
||||||
if ((ntohs(tc->th_dport) == RTSP_CONTROL_PORT_NUMBER_1) ||
|
if ((ntohs(tc->th_dport) == RTSP_CONTROL_PORT_NUMBER_1) ||
|
||||||
(ntohs(tc->th_dport) == RTSP_CONTROL_PORT_NUMBER_2)) {
|
(ntohs(tc->th_dport) == RTSP_CONTROL_PORT_NUMBER_2)) {
|
||||||
|
|
||||||
if (dlen >= strlen(setup)) {
|
if (dlen >= strlen(setup)) {
|
||||||
if (memcmp(data, setup, strlen(setup)) == 0) {
|
if (memcmp(data, setup, strlen(setup)) == 0) {
|
||||||
alias_rtsp_out(la, pip, link, data, client_port_str);
|
alias_rtsp_out(la, pip, link, data, client_port_str);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dlen >= strlen(pna)) {
|
||||||
|
if (memcmp(data, pna, strlen(pna)) == 0) {
|
||||||
|
alias_pna_out(la, pip, link, data, dlen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When aliasing a server, check for the 200 reply
|
||||||
|
* Accomodate varying number of blanks between 200 & OK
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (dlen >= strlen(str200)) {
|
||||||
|
|
||||||
|
for (parseOk = 0, i = 0;
|
||||||
|
i <= dlen - strlen(str200);
|
||||||
|
i++) {
|
||||||
|
if (memcmp(&data[i], str200, strlen(str200)) == 0) {
|
||||||
|
parseOk = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (parseOk) {
|
||||||
|
|
||||||
|
i += strlen(str200); /* skip string found */
|
||||||
|
while (data[i] == ' ') /* skip blank(s) */
|
||||||
|
i++;
|
||||||
|
|
||||||
|
if ((dlen - i) >= strlen(okstr)) {
|
||||||
|
|
||||||
|
if (memcmp(&data[i], okstr, strlen(okstr)) == 0)
|
||||||
|
alias_rtsp_out(la, pip, link, data, server_port_str);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (dlen >= strlen(pna)) {
|
|
||||||
if (memcmp(data, pna, strlen(pna)) == 0) {
|
|
||||||
alias_pna_out(la, pip, link, data, dlen);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
/* When aliasing a server, check for the 200 reply
|
|
||||||
Accomodate varying number of blanks between 200 & OK */
|
|
||||||
|
|
||||||
if (dlen >= strlen(str200)) {
|
|
||||||
|
|
||||||
for (parseOk = 0, i = 0;
|
|
||||||
i <= dlen - strlen(str200);
|
|
||||||
i++) {
|
|
||||||
if (memcmp(&data[i], str200, strlen(str200)) == 0) {
|
|
||||||
parseOk = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (parseOk) {
|
|
||||||
|
|
||||||
i += strlen(str200); /* skip string found */
|
|
||||||
while(data[i] == ' ') /* skip blank(s) */
|
|
||||||
i++;
|
|
||||||
|
|
||||||
if ((dlen - i) >= strlen(okstr)) {
|
|
||||||
|
|
||||||
if (memcmp(&data[i], okstr, strlen(okstr)) == 0)
|
|
||||||
alias_rtsp_out(la, pip, link, data, server_port_str);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -61,110 +61,100 @@ purposes);
|
|||||||
#include "alias_local.h"
|
#include "alias_local.h"
|
||||||
|
|
||||||
u_short
|
u_short
|
||||||
LibAliasInternetChecksum(struct libalias *la, u_short *ptr, int nbytes)
|
LibAliasInternetChecksum(struct libalias *la, u_short * ptr, int nbytes)
|
||||||
{
|
{
|
||||||
int sum, oddbyte;
|
int sum, oddbyte;
|
||||||
|
|
||||||
sum = 0;
|
sum = 0;
|
||||||
while (nbytes > 1)
|
while (nbytes > 1) {
|
||||||
{
|
sum += *ptr++;
|
||||||
sum += *ptr++;
|
nbytes -= 2;
|
||||||
nbytes -= 2;
|
}
|
||||||
}
|
if (nbytes == 1) {
|
||||||
if (nbytes == 1)
|
oddbyte = 0;
|
||||||
{
|
((u_char *) & oddbyte)[0] = *(u_char *) ptr;
|
||||||
oddbyte = 0;
|
((u_char *) & oddbyte)[1] = 0;
|
||||||
((u_char *) &oddbyte)[0] = *(u_char *) ptr;
|
sum += oddbyte;
|
||||||
((u_char *) &oddbyte)[1] = 0;
|
}
|
||||||
sum += oddbyte;
|
sum = (sum >> 16) + (sum & 0xffff);
|
||||||
}
|
sum += (sum >> 16);
|
||||||
sum = (sum >> 16) + (sum & 0xffff);
|
return (~sum);
|
||||||
sum += (sum >> 16);
|
|
||||||
return(~sum);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u_short
|
u_short
|
||||||
IpChecksum(struct ip *pip)
|
IpChecksum(struct ip *pip)
|
||||||
{
|
{
|
||||||
return( PacketAliasInternetChecksum((u_short *) pip,
|
return (PacketAliasInternetChecksum((u_short *) pip,
|
||||||
(pip->ip_hl << 2)) );
|
(pip->ip_hl << 2)));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u_short
|
u_short
|
||||||
TcpChecksum(struct ip *pip)
|
TcpChecksum(struct ip *pip)
|
||||||
{
|
{
|
||||||
u_short *ptr;
|
u_short *ptr;
|
||||||
struct tcphdr *tc;
|
struct tcphdr *tc;
|
||||||
int nhdr, ntcp, nbytes;
|
int nhdr, ntcp, nbytes;
|
||||||
int sum, oddbyte;
|
int sum, oddbyte;
|
||||||
|
|
||||||
nhdr = pip->ip_hl << 2;
|
nhdr = pip->ip_hl << 2;
|
||||||
ntcp = ntohs(pip->ip_len) - nhdr;
|
ntcp = ntohs(pip->ip_len) - nhdr;
|
||||||
|
|
||||||
tc = (struct tcphdr *) ((char *) pip + nhdr);
|
tc = (struct tcphdr *)((char *)pip + nhdr);
|
||||||
ptr = (u_short *) tc;
|
ptr = (u_short *) tc;
|
||||||
|
|
||||||
/* Add up TCP header and data */
|
/* Add up TCP header and data */
|
||||||
nbytes = ntcp;
|
nbytes = ntcp;
|
||||||
sum = 0;
|
sum = 0;
|
||||||
while (nbytes > 1)
|
while (nbytes > 1) {
|
||||||
{
|
sum += *ptr++;
|
||||||
sum += *ptr++;
|
nbytes -= 2;
|
||||||
nbytes -= 2;
|
}
|
||||||
}
|
if (nbytes == 1) {
|
||||||
if (nbytes == 1)
|
oddbyte = 0;
|
||||||
{
|
((u_char *) & oddbyte)[0] = *(u_char *) ptr;
|
||||||
oddbyte = 0;
|
((u_char *) & oddbyte)[1] = 0;
|
||||||
((u_char *) &oddbyte)[0] = *(u_char *) ptr;
|
sum += oddbyte;
|
||||||
((u_char *) &oddbyte)[1] = 0;
|
}
|
||||||
sum += oddbyte;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* "Pseudo-header" data */
|
/* "Pseudo-header" data */
|
||||||
ptr = (u_short *) &(pip->ip_dst);
|
ptr = (u_short *) & (pip->ip_dst);
|
||||||
sum += *ptr++;
|
sum += *ptr++;
|
||||||
sum += *ptr;
|
sum += *ptr;
|
||||||
ptr = (u_short *) &(pip->ip_src);
|
ptr = (u_short *) & (pip->ip_src);
|
||||||
sum += *ptr++;
|
sum += *ptr++;
|
||||||
sum += *ptr;
|
sum += *ptr;
|
||||||
sum += htons((u_short) ntcp);
|
sum += htons((u_short) ntcp);
|
||||||
sum += htons((u_short) pip->ip_p);
|
sum += htons((u_short) pip->ip_p);
|
||||||
|
|
||||||
/* Roll over carry bits */
|
/* Roll over carry bits */
|
||||||
sum = (sum >> 16) + (sum & 0xffff);
|
sum = (sum >> 16) + (sum & 0xffff);
|
||||||
sum += (sum >> 16);
|
sum += (sum >> 16);
|
||||||
|
|
||||||
/* Return checksum */
|
/* Return checksum */
|
||||||
return((u_short) ~sum);
|
return ((u_short) ~ sum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
DifferentialChecksum(u_short *cksum, u_short *new, u_short *old, int n)
|
DifferentialChecksum(u_short * cksum, u_short * new, u_short * old, int n)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int accumulate;
|
int accumulate;
|
||||||
|
|
||||||
accumulate = *cksum;
|
accumulate = *cksum;
|
||||||
for (i=0; i<n; i++)
|
for (i = 0; i < n; i++) {
|
||||||
{
|
accumulate -= *new++;
|
||||||
accumulate -= *new++;
|
accumulate += *old++;
|
||||||
accumulate += *old++;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (accumulate < 0)
|
if (accumulate < 0) {
|
||||||
{
|
accumulate = -accumulate;
|
||||||
accumulate = -accumulate;
|
accumulate = (accumulate >> 16) + (accumulate & 0xffff);
|
||||||
accumulate = (accumulate >> 16) + (accumulate & 0xffff);
|
accumulate += accumulate >> 16;
|
||||||
accumulate += accumulate >> 16;
|
*cksum = (u_short) ~ accumulate;
|
||||||
*cksum = (u_short) ~accumulate;
|
} else {
|
||||||
}
|
accumulate = (accumulate >> 16) + (accumulate & 0xffff);
|
||||||
else
|
accumulate += accumulate >> 16;
|
||||||
{
|
*cksum = (u_short) accumulate;
|
||||||
accumulate = (accumulate >> 16) + (accumulate & 0xffff);
|
}
|
||||||
accumulate += accumulate >> 16;
|
|
||||||
*cksum = (u_short) accumulate;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -47,11 +47,11 @@
|
|||||||
* PacketAlias*() the old API which doesn't take an instance pointer
|
* PacketAlias*() the old API which doesn't take an instance pointer
|
||||||
* and therefore can only have one packet engine at a time.
|
* and therefore can only have one packet engine at a time.
|
||||||
*
|
*
|
||||||
* LibAlias*() the new API which takes as first argument a pointer to
|
* LibAlias*() the new API which takes as first argument a pointer to
|
||||||
* the instance of the packet aliasing engine.
|
* the instance of the packet aliasing engine.
|
||||||
*
|
*
|
||||||
* The functions otherwise correspond to each other one for one, except
|
* The functions otherwise correspond to each other one for one, except
|
||||||
* for the LibAliasUnaliasOut()/PacketUnaliasOut() function which were
|
* for the LibAliasUnaliasOut()/PacketUnaliasOut() function which were
|
||||||
* were misnamed in the old API.
|
* were misnamed in the old API.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -66,107 +66,109 @@ struct libalias;
|
|||||||
* PacketAliasRedirectProto(), passed to PacketAliasAddServer(),
|
* PacketAliasRedirectProto(), passed to PacketAliasAddServer(),
|
||||||
* and freed by PacketAliasRedirectDelete().
|
* and freed by PacketAliasRedirectDelete().
|
||||||
*/
|
*/
|
||||||
struct alias_link;
|
struct alias_link;
|
||||||
|
|
||||||
|
|
||||||
/* OLD API */
|
/* OLD API */
|
||||||
|
|
||||||
/* Initialization and control functions. */
|
/* Initialization and control functions. */
|
||||||
void PacketAliasInit(void);
|
void PacketAliasInit(void);
|
||||||
void PacketAliasSetAddress(struct in_addr _addr);
|
void PacketAliasSetAddress(struct in_addr _addr);
|
||||||
void PacketAliasSetFWBase(unsigned int _base, unsigned int _num);
|
void PacketAliasSetFWBase(unsigned int _base, unsigned int _num);
|
||||||
void PacketAliasSetSkinnyPort(unsigned int _port);
|
void PacketAliasSetSkinnyPort(unsigned int _port);
|
||||||
unsigned int
|
unsigned int
|
||||||
PacketAliasSetMode(unsigned int _flags, unsigned int _mask);
|
PacketAliasSetMode(unsigned int _flags, unsigned int _mask);
|
||||||
void PacketAliasUninit(void);
|
void PacketAliasUninit(void);
|
||||||
|
|
||||||
/* Packet Handling functions. */
|
/* Packet Handling functions. */
|
||||||
int PacketAliasIn(char *_ptr, int _maxpacketsize);
|
int PacketAliasIn(char *_ptr, int _maxpacketsize);
|
||||||
int PacketAliasOut(char *_ptr, int _maxpacketsize);
|
int PacketAliasOut(char *_ptr, int _maxpacketsize);
|
||||||
int PacketUnaliasOut(char *_ptr, int _maxpacketsize);
|
int PacketUnaliasOut(char *_ptr, int _maxpacketsize);
|
||||||
|
|
||||||
/* Port and address redirection functions. */
|
/* Port and address redirection functions. */
|
||||||
|
|
||||||
|
|
||||||
int PacketAliasAddServer(struct alias_link *_link,
|
int
|
||||||
struct in_addr _addr, unsigned short _port);
|
PacketAliasAddServer(struct alias_link *_link,
|
||||||
|
struct in_addr _addr, unsigned short _port);
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
PacketAliasRedirectAddr(struct in_addr _src_addr,
|
PacketAliasRedirectAddr(struct in_addr _src_addr,
|
||||||
struct in_addr _alias_addr);
|
struct in_addr _alias_addr);
|
||||||
int PacketAliasRedirectDynamic(struct alias_link *_link);
|
int PacketAliasRedirectDynamic(struct alias_link *_link);
|
||||||
void PacketAliasRedirectDelete(struct alias_link *_link);
|
void PacketAliasRedirectDelete(struct alias_link *_link);
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
PacketAliasRedirectPort(struct in_addr _src_addr,
|
PacketAliasRedirectPort(struct in_addr _src_addr,
|
||||||
unsigned short _src_port, struct in_addr _dst_addr,
|
unsigned short _src_port, struct in_addr _dst_addr,
|
||||||
unsigned short _dst_port, struct in_addr _alias_addr,
|
unsigned short _dst_port, struct in_addr _alias_addr,
|
||||||
unsigned short _alias_port, unsigned char _proto);
|
unsigned short _alias_port, unsigned char _proto);
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
PacketAliasRedirectProto(struct in_addr _src_addr,
|
PacketAliasRedirectProto(struct in_addr _src_addr,
|
||||||
struct in_addr _dst_addr, struct in_addr _alias_addr,
|
struct in_addr _dst_addr, struct in_addr _alias_addr,
|
||||||
unsigned char _proto);
|
unsigned char _proto);
|
||||||
|
|
||||||
/* Fragment Handling functions. */
|
/* Fragment Handling functions. */
|
||||||
void PacketAliasFragmentIn(char *_ptr, char *_ptr_fragment);
|
void PacketAliasFragmentIn(char *_ptr, char *_ptr_fragment);
|
||||||
char *PacketAliasGetFragment(char *_ptr);
|
char *PacketAliasGetFragment(char *_ptr);
|
||||||
int PacketAliasSaveFragment(char *_ptr);
|
int PacketAliasSaveFragment(char *_ptr);
|
||||||
|
|
||||||
/* Miscellaneous functions. */
|
/* Miscellaneous functions. */
|
||||||
int PacketAliasCheckNewLink(void);
|
int PacketAliasCheckNewLink(void);
|
||||||
unsigned short
|
unsigned short
|
||||||
PacketAliasInternetChecksum(unsigned short *_ptr, int _nbytes);
|
PacketAliasInternetChecksum(unsigned short *_ptr, int _nbytes);
|
||||||
void PacketAliasSetTarget(struct in_addr _target_addr);
|
void PacketAliasSetTarget(struct in_addr _target_addr);
|
||||||
|
|
||||||
/* Transparent proxying routines. */
|
/* Transparent proxying routines. */
|
||||||
int PacketAliasProxyRule(const char *_cmd);
|
int PacketAliasProxyRule(const char *_cmd);
|
||||||
|
|
||||||
/* NEW API */
|
/* NEW API */
|
||||||
|
|
||||||
/* Initialization and control functions. */
|
/* Initialization and control functions. */
|
||||||
struct libalias *LibAliasInit(struct libalias *);
|
struct libalias *LibAliasInit(struct libalias *);
|
||||||
void LibAliasSetAddress(struct libalias *, struct in_addr _addr);
|
void LibAliasSetAddress(struct libalias *, struct in_addr _addr);
|
||||||
void LibAliasSetFWBase(struct libalias *, unsigned int _base, unsigned int _num);
|
void LibAliasSetFWBase(struct libalias *, unsigned int _base, unsigned int _num);
|
||||||
void LibAliasSetSkinnyPort(struct libalias *, unsigned int _port);
|
void LibAliasSetSkinnyPort(struct libalias *, unsigned int _port);
|
||||||
unsigned int
|
unsigned int
|
||||||
LibAliasSetMode(struct libalias *, unsigned int _flags, unsigned int _mask);
|
LibAliasSetMode(struct libalias *, unsigned int _flags, unsigned int _mask);
|
||||||
void LibAliasUninit(struct libalias *);
|
void LibAliasUninit(struct libalias *);
|
||||||
|
|
||||||
/* Packet Handling functions. */
|
/* Packet Handling functions. */
|
||||||
int LibAliasIn(struct libalias *, char *_ptr, int _maxpacketsize);
|
int LibAliasIn (struct libalias *, char *_ptr, int _maxpacketsize);
|
||||||
int LibAliasOut(struct libalias *, char *_ptr, int _maxpacketsize);
|
int LibAliasOut(struct libalias *, char *_ptr, int _maxpacketsize);
|
||||||
int LibAliasUnaliasOut(struct libalias *, char *_ptr, int _maxpacketsize);
|
int LibAliasUnaliasOut(struct libalias *, char *_ptr, int _maxpacketsize);
|
||||||
|
|
||||||
/* Port and address redirection functions. */
|
/* Port and address redirection functions. */
|
||||||
|
|
||||||
int LibAliasAddServer(struct libalias *, struct alias_link *_link,
|
int
|
||||||
struct in_addr _addr, unsigned short _port);
|
LibAliasAddServer(struct libalias *, struct alias_link *_link,
|
||||||
|
struct in_addr _addr, unsigned short _port);
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
LibAliasRedirectAddr(struct libalias *, struct in_addr _src_addr,
|
LibAliasRedirectAddr(struct libalias *, struct in_addr _src_addr,
|
||||||
struct in_addr _alias_addr);
|
struct in_addr _alias_addr);
|
||||||
int LibAliasRedirectDynamic(struct libalias *, struct alias_link *_link);
|
int LibAliasRedirectDynamic(struct libalias *, struct alias_link *_link);
|
||||||
void LibAliasRedirectDelete(struct libalias *, struct alias_link *_link);
|
void LibAliasRedirectDelete(struct libalias *, struct alias_link *_link);
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
LibAliasRedirectPort(struct libalias *, struct in_addr _src_addr,
|
LibAliasRedirectPort(struct libalias *, struct in_addr _src_addr,
|
||||||
unsigned short _src_port, struct in_addr _dst_addr,
|
unsigned short _src_port, struct in_addr _dst_addr,
|
||||||
unsigned short _dst_port, struct in_addr _alias_addr,
|
unsigned short _dst_port, struct in_addr _alias_addr,
|
||||||
unsigned short _alias_port, unsigned char _proto);
|
unsigned short _alias_port, unsigned char _proto);
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
LibAliasRedirectProto(struct libalias *, struct in_addr _src_addr,
|
LibAliasRedirectProto(struct libalias *, struct in_addr _src_addr,
|
||||||
struct in_addr _dst_addr, struct in_addr _alias_addr,
|
struct in_addr _dst_addr, struct in_addr _alias_addr,
|
||||||
unsigned char _proto);
|
unsigned char _proto);
|
||||||
|
|
||||||
/* Fragment Handling functions. */
|
/* Fragment Handling functions. */
|
||||||
void LibAliasFragmentIn(struct libalias *, char *_ptr, char *_ptr_fragment);
|
void LibAliasFragmentIn(struct libalias *, char *_ptr, char *_ptr_fragment);
|
||||||
char *LibAliasGetFragment(struct libalias *, char *_ptr);
|
char *LibAliasGetFragment(struct libalias *, char *_ptr);
|
||||||
int LibAliasSaveFragment(struct libalias *, char *_ptr);
|
int LibAliasSaveFragment(struct libalias *, char *_ptr);
|
||||||
|
|
||||||
/* Miscellaneous functions. */
|
/* Miscellaneous functions. */
|
||||||
int LibAliasCheckNewLink(struct libalias *);
|
int LibAliasCheckNewLink(struct libalias *);
|
||||||
unsigned short
|
unsigned short
|
||||||
LibAliasInternetChecksum(struct libalias *, unsigned short *_ptr, int _nbytes);
|
LibAliasInternetChecksum(struct libalias *, unsigned short *_ptr, int _nbytes);
|
||||||
void LibAliasSetTarget(struct libalias *, struct in_addr _target_addr);
|
void LibAliasSetTarget(struct libalias *, struct in_addr _target_addr);
|
||||||
|
|
||||||
/* Transparent proxying routines. */
|
/* Transparent proxying routines. */
|
||||||
int LibAliasProxyRule(struct libalias *, const char *_cmd);
|
int LibAliasProxyRule(struct libalias *, const char *_cmd);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -257,6 +259,6 @@ int LibAliasProxyRule(struct libalias *, const char *_cmd);
|
|||||||
#define PKT_ALIAS_UNRESOLVED_FRAGMENT 3
|
#define PKT_ALIAS_UNRESOLVED_FRAGMENT 3
|
||||||
#define PKT_ALIAS_FOUND_HEADER_FRAGMENT 4
|
#define PKT_ALIAS_FOUND_HEADER_FRAGMENT 4
|
||||||
|
|
||||||
#endif /* !_ALIAS_H_ */
|
#endif /* !_ALIAS_H_ */
|
||||||
|
|
||||||
/* lint -restore */
|
/* lint -restore */
|
||||||
|
@ -40,83 +40,84 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
/* CU-SeeMe Data Header */
|
/* CU-SeeMe Data Header */
|
||||||
struct cu_header {
|
struct cu_header {
|
||||||
u_int16_t dest_family;
|
u_int16_t dest_family;
|
||||||
u_int16_t dest_port;
|
u_int16_t dest_port;
|
||||||
u_int32_t dest_addr;
|
u_int32_t dest_addr;
|
||||||
int16_t family;
|
int16_t family;
|
||||||
u_int16_t port;
|
u_int16_t port;
|
||||||
u_int32_t addr;
|
u_int32_t addr;
|
||||||
u_int32_t seq;
|
u_int32_t seq;
|
||||||
u_int16_t msg;
|
u_int16_t msg;
|
||||||
u_int16_t data_type;
|
u_int16_t data_type;
|
||||||
u_int16_t packet_len;
|
u_int16_t packet_len;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Open Continue Header */
|
/* Open Continue Header */
|
||||||
struct oc_header {
|
struct oc_header {
|
||||||
u_int16_t client_count; /* Number of client info structs */
|
u_int16_t client_count; /* Number of client info structs */
|
||||||
u_int32_t seq_no;
|
u_int32_t seq_no;
|
||||||
char user_name[20];
|
char user_name [20];
|
||||||
char reserved[4]; /* flags, version stuff, etc */
|
char reserved [4]; /* flags, version stuff, etc */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* client info structures */
|
/* client info structures */
|
||||||
struct client_info {
|
struct client_info {
|
||||||
u_int32_t address; /* Client address */
|
u_int32_t address;/* Client address */
|
||||||
char reserved[8]; /* Flags, pruning bitfield, packet counts etc */
|
char reserved [8]; /* Flags, pruning bitfield, packet
|
||||||
|
* counts etc */
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
AliasHandleCUSeeMeOut(struct libalias *la, struct ip *pip, struct alias_link *link)
|
AliasHandleCUSeeMeOut(struct libalias *la, struct ip *pip, struct alias_link *link)
|
||||||
{
|
{
|
||||||
struct udphdr *ud;
|
struct udphdr *ud;
|
||||||
|
|
||||||
ud = (struct udphdr *)((char *)pip + (pip->ip_hl << 2));
|
ud = (struct udphdr *)((char *)pip + (pip->ip_hl << 2));
|
||||||
if (ntohs(ud->uh_ulen) - sizeof(struct udphdr) >= sizeof(struct cu_header)) {
|
if (ntohs(ud->uh_ulen) - sizeof(struct udphdr) >= sizeof(struct cu_header)) {
|
||||||
struct cu_header *cu;
|
struct cu_header *cu;
|
||||||
struct alias_link *cu_link;
|
struct alias_link *cu_link;
|
||||||
|
|
||||||
cu = (struct cu_header *)(ud + 1);
|
cu = (struct cu_header *)(ud + 1);
|
||||||
if (cu->addr)
|
if (cu->addr)
|
||||||
cu->addr = (u_int32_t)GetAliasAddress(link).s_addr;
|
cu->addr = (u_int32_t) GetAliasAddress(link).s_addr;
|
||||||
|
|
||||||
cu_link = FindUdpTcpOut(la, pip->ip_src, GetDestAddress(link),
|
cu_link = FindUdpTcpOut(la, pip->ip_src, GetDestAddress(link),
|
||||||
ud->uh_dport, 0, IPPROTO_UDP, 1);
|
ud->uh_dport, 0, IPPROTO_UDP, 1);
|
||||||
|
|
||||||
#ifndef NO_FW_PUNCH
|
#ifndef NO_FW_PUNCH
|
||||||
if (cu_link)
|
if (cu_link)
|
||||||
PunchFWHole(cu_link);
|
PunchFWHole(cu_link);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
AliasHandleCUSeeMeIn(struct libalias *la, struct ip *pip, struct in_addr original_addr)
|
AliasHandleCUSeeMeIn(struct libalias *la, struct ip *pip, struct in_addr original_addr)
|
||||||
{
|
{
|
||||||
struct in_addr alias_addr;
|
struct in_addr alias_addr;
|
||||||
struct udphdr *ud;
|
struct udphdr *ud;
|
||||||
struct cu_header *cu;
|
struct cu_header *cu;
|
||||||
struct oc_header *oc;
|
struct oc_header *oc;
|
||||||
struct client_info *ci;
|
struct client_info *ci;
|
||||||
char *end;
|
char *end;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
alias_addr.s_addr = pip->ip_dst.s_addr;
|
alias_addr.s_addr = pip->ip_dst.s_addr;
|
||||||
ud = (struct udphdr *)((char *)pip + (pip->ip_hl << 2));
|
ud = (struct udphdr *)((char *)pip + (pip->ip_hl << 2));
|
||||||
cu = (struct cu_header *)(ud + 1);
|
cu = (struct cu_header *)(ud + 1);
|
||||||
oc = (struct oc_header *)(cu + 1);
|
oc = (struct oc_header *)(cu + 1);
|
||||||
ci = (struct client_info *)(oc + 1);
|
ci = (struct client_info *)(oc + 1);
|
||||||
end = (char *)ud + ntohs(ud->uh_ulen);
|
end = (char *)ud + ntohs(ud->uh_ulen);
|
||||||
|
|
||||||
if ((char *)oc <= end) {
|
if ((char *)oc <= end) {
|
||||||
if(cu->dest_addr)
|
if (cu->dest_addr)
|
||||||
cu->dest_addr = (u_int32_t)original_addr.s_addr;
|
cu->dest_addr = (u_int32_t) original_addr.s_addr;
|
||||||
if(ntohs(cu->data_type) == 101)
|
if (ntohs(cu->data_type) == 101)
|
||||||
/* Find and change our address */
|
/* Find and change our address */
|
||||||
for(i = 0; (char *)(ci + 1) <= end && i < oc->client_count; i++, ci++)
|
for (i = 0; (char *)(ci + 1) <= end && i < oc->client_count; i++, ci++)
|
||||||
if(ci->address == (u_int32_t)alias_addr.s_addr) {
|
if (ci->address == (u_int32_t) alias_addr.s_addr) {
|
||||||
ci->address = (u_int32_t)original_addr.s_addr;
|
ci->address = (u_int32_t) original_addr.s_addr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -87,495 +87,589 @@ __FBSDID("$FreeBSD$");
|
|||||||
#define WAIT_CRLF 0x01
|
#define WAIT_CRLF 0x01
|
||||||
|
|
||||||
enum ftp_message_type {
|
enum ftp_message_type {
|
||||||
FTP_PORT_COMMAND,
|
FTP_PORT_COMMAND,
|
||||||
FTP_EPRT_COMMAND,
|
FTP_EPRT_COMMAND,
|
||||||
FTP_227_REPLY,
|
FTP_227_REPLY,
|
||||||
FTP_229_REPLY,
|
FTP_229_REPLY,
|
||||||
FTP_UNKNOWN_MESSAGE
|
FTP_UNKNOWN_MESSAGE
|
||||||
};
|
};
|
||||||
|
|
||||||
static int ParseFtpPortCommand(struct libalias *la, char *, int);
|
static int ParseFtpPortCommand(struct libalias *la, char *, int);
|
||||||
static int ParseFtpEprtCommand(struct libalias *la, char *, int);
|
static int ParseFtpEprtCommand(struct libalias *la, char *, int);
|
||||||
static int ParseFtp227Reply(struct libalias *la, char *, int);
|
static int ParseFtp227Reply(struct libalias *la, char *, int);
|
||||||
static int ParseFtp229Reply(struct libalias *la, char *, int);
|
static int ParseFtp229Reply(struct libalias *la, char *, int);
|
||||||
static void NewFtpMessage(struct libalias *la, struct ip *, struct alias_link *, int, int);
|
static void NewFtpMessage(struct libalias *la, struct ip *, struct alias_link *, int, int);
|
||||||
|
|
||||||
void
|
void
|
||||||
AliasHandleFtpOut(
|
AliasHandleFtpOut(
|
||||||
struct libalias *la,
|
struct libalias *la,
|
||||||
struct ip *pip, /* IP packet to examine/patch */
|
struct ip *pip, /* IP packet to examine/patch */
|
||||||
struct alias_link *link, /* The link to go through (aliased port) */
|
struct alias_link *link, /* The link to go through (aliased port) */
|
||||||
int maxpacketsize /* The maximum size this packet can grow to (including headers) */)
|
int maxpacketsize /* The maximum size this packet can grow to
|
||||||
|
(including headers) */ )
|
||||||
{
|
{
|
||||||
int hlen, tlen, dlen, pflags;
|
int hlen, tlen, dlen, pflags;
|
||||||
char *sptr;
|
char *sptr;
|
||||||
struct tcphdr *tc;
|
struct tcphdr *tc;
|
||||||
int ftp_message_type;
|
int ftp_message_type;
|
||||||
|
|
||||||
/* Calculate data length of TCP packet */
|
/* Calculate data length of TCP packet */
|
||||||
tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
|
tc = (struct tcphdr *)((char *)pip + (pip->ip_hl << 2));
|
||||||
hlen = (pip->ip_hl + tc->th_off) << 2;
|
hlen = (pip->ip_hl + tc->th_off) << 2;
|
||||||
tlen = ntohs(pip->ip_len);
|
tlen = ntohs(pip->ip_len);
|
||||||
dlen = tlen - hlen;
|
dlen = tlen - hlen;
|
||||||
|
|
||||||
/* Place string pointer and beginning of data */
|
/* Place string pointer and beginning of data */
|
||||||
sptr = (char *) pip;
|
sptr = (char *)pip;
|
||||||
sptr += hlen;
|
sptr += hlen;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check that data length is not too long and previous message was
|
* Check that data length is not too long and previous message was
|
||||||
* properly terminated with CRLF.
|
* properly terminated with CRLF.
|
||||||
*/
|
*/
|
||||||
pflags = GetProtocolFlags(link);
|
pflags = GetProtocolFlags(link);
|
||||||
if (dlen <= MAX_MESSAGE_SIZE && !(pflags & WAIT_CRLF)) {
|
if (dlen <= MAX_MESSAGE_SIZE && !(pflags & WAIT_CRLF)) {
|
||||||
ftp_message_type = FTP_UNKNOWN_MESSAGE;
|
ftp_message_type = FTP_UNKNOWN_MESSAGE;
|
||||||
|
|
||||||
if (ntohs(tc->th_dport) == FTP_CONTROL_PORT_NUMBER) {
|
if (ntohs(tc->th_dport) == FTP_CONTROL_PORT_NUMBER) {
|
||||||
/*
|
/*
|
||||||
* When aliasing a client, check for the PORT/EPRT command.
|
* When aliasing a client, check for the PORT/EPRT command.
|
||||||
*/
|
*/
|
||||||
if (ParseFtpPortCommand(la, sptr, dlen))
|
if (ParseFtpPortCommand(la, sptr, dlen))
|
||||||
ftp_message_type = FTP_PORT_COMMAND;
|
ftp_message_type = FTP_PORT_COMMAND;
|
||||||
else if (ParseFtpEprtCommand(la, sptr, dlen))
|
else if (ParseFtpEprtCommand(la, sptr, dlen))
|
||||||
ftp_message_type = FTP_EPRT_COMMAND;
|
ftp_message_type = FTP_EPRT_COMMAND;
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* When aliasing a server, check for the 227/229 reply.
|
* When aliasing a server, check for the 227/229 reply.
|
||||||
*/
|
*/
|
||||||
if (ParseFtp227Reply(la, sptr, dlen))
|
if (ParseFtp227Reply(la, sptr, dlen))
|
||||||
ftp_message_type = FTP_227_REPLY;
|
ftp_message_type = FTP_227_REPLY;
|
||||||
else if (ParseFtp229Reply(la, sptr, dlen)) {
|
else if (ParseFtp229Reply(la, sptr, dlen)) {
|
||||||
ftp_message_type = FTP_229_REPLY;
|
ftp_message_type = FTP_229_REPLY;
|
||||||
la->true_addr.s_addr = pip->ip_src.s_addr;
|
la->true_addr.s_addr = pip->ip_src.s_addr;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ftp_message_type != FTP_UNKNOWN_MESSAGE)
|
||||||
|
NewFtpMessage(la, pip, link, maxpacketsize, ftp_message_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ftp_message_type != FTP_UNKNOWN_MESSAGE)
|
|
||||||
NewFtpMessage(la, pip, link, maxpacketsize, ftp_message_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Track the msgs which are CRLF term'd for PORT/PASV FW breach */
|
/* Track the msgs which are CRLF term'd for PORT/PASV FW breach */
|
||||||
|
|
||||||
if (dlen) { /* only if there's data */
|
if (dlen) { /* only if there's data */
|
||||||
sptr = (char *) pip; /* start over at beginning */
|
sptr = (char *)pip; /* start over at beginning */
|
||||||
tlen = ntohs(pip->ip_len); /* recalc tlen, pkt may have grown */
|
tlen = ntohs(pip->ip_len); /* recalc tlen, pkt may
|
||||||
if (sptr[tlen-2] == '\r' && sptr[tlen-1] == '\n')
|
* have grown */
|
||||||
pflags &= ~WAIT_CRLF;
|
if (sptr[tlen - 2] == '\r' && sptr[tlen - 1] == '\n')
|
||||||
else
|
pflags &= ~WAIT_CRLF;
|
||||||
pflags |= WAIT_CRLF;
|
else
|
||||||
SetProtocolFlags(link, pflags);
|
pflags |= WAIT_CRLF;
|
||||||
}
|
SetProtocolFlags(link, pflags);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ParseFtpPortCommand(struct libalias *la, char *sptr, int dlen)
|
ParseFtpPortCommand(struct libalias *la, char *sptr, int dlen)
|
||||||
{
|
{
|
||||||
char ch;
|
char ch;
|
||||||
int i, state;
|
int i, state;
|
||||||
u_int32_t addr;
|
u_int32_t addr;
|
||||||
u_short port;
|
u_short port;
|
||||||
u_int8_t octet;
|
u_int8_t octet;
|
||||||
|
|
||||||
/* Format: "PORT A,D,D,R,PO,RT". */
|
/* Format: "PORT A,D,D,R,PO,RT". */
|
||||||
|
|
||||||
/* Return if data length is too short. */
|
/* Return if data length is too short. */
|
||||||
if (dlen < 18)
|
if (dlen < 18)
|
||||||
return 0;
|
|
||||||
|
|
||||||
addr = port = octet = 0;
|
|
||||||
state = -4;
|
|
||||||
for (i = 0; i < dlen; i++) {
|
|
||||||
ch = sptr[i];
|
|
||||||
switch (state) {
|
|
||||||
case -4: if (ch == 'P') state++; else return 0; break;
|
|
||||||
case -3: if (ch == 'O') state++; else return 0; break;
|
|
||||||
case -2: if (ch == 'R') state++; else return 0; break;
|
|
||||||
case -1: if (ch == 'T') state++; else return 0; break;
|
|
||||||
|
|
||||||
case 0:
|
|
||||||
if (isspace(ch))
|
|
||||||
break;
|
|
||||||
else
|
|
||||||
state++;
|
|
||||||
case 1: case 3: case 5: case 7: case 9: case 11:
|
|
||||||
if (isdigit(ch)) {
|
|
||||||
octet = ch - '0';
|
|
||||||
state++;
|
|
||||||
} else
|
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
|
||||||
case 2: case 4: case 6: case 8:
|
addr = port = octet = 0;
|
||||||
if (isdigit(ch))
|
state = -4;
|
||||||
octet = 10 * octet + ch - '0';
|
for (i = 0; i < dlen; i++) {
|
||||||
else if (ch == ',') {
|
ch = sptr[i];
|
||||||
addr = (addr << 8) + octet;
|
switch (state) {
|
||||||
state++;
|
case -4:
|
||||||
} else
|
if (ch == 'P')
|
||||||
return 0;
|
state++;
|
||||||
break;
|
else
|
||||||
case 10: case 12:
|
return 0;
|
||||||
if (isdigit(ch))
|
break;
|
||||||
octet = 10 * octet + ch - '0';
|
case -3:
|
||||||
else if (ch == ',' || state == 12) {
|
if (ch == 'O')
|
||||||
port = (port << 8) + octet;
|
state++;
|
||||||
state++;
|
else
|
||||||
} else
|
return 0;
|
||||||
return 0;
|
break;
|
||||||
break;
|
case -2:
|
||||||
|
if (ch == 'R')
|
||||||
|
state++;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
case -1:
|
||||||
|
if (ch == 'T')
|
||||||
|
state++;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0:
|
||||||
|
if (isspace(ch))
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
state++;
|
||||||
|
case 1:
|
||||||
|
case 3:
|
||||||
|
case 5:
|
||||||
|
case 7:
|
||||||
|
case 9:
|
||||||
|
case 11:
|
||||||
|
if (isdigit(ch)) {
|
||||||
|
octet = ch - '0';
|
||||||
|
state++;
|
||||||
|
} else
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
case 4:
|
||||||
|
case 6:
|
||||||
|
case 8:
|
||||||
|
if (isdigit(ch))
|
||||||
|
octet = 10 * octet + ch - '0';
|
||||||
|
else if (ch == ',') {
|
||||||
|
addr = (addr << 8) + octet;
|
||||||
|
state++;
|
||||||
|
} else
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
case 12:
|
||||||
|
if (isdigit(ch))
|
||||||
|
octet = 10 * octet + ch - '0';
|
||||||
|
else if (ch == ',' || state == 12) {
|
||||||
|
port = (port << 8) + octet;
|
||||||
|
state++;
|
||||||
|
} else
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (state == 13) {
|
if (state == 13) {
|
||||||
la->true_addr.s_addr = htonl(addr);
|
la->true_addr.s_addr = htonl(addr);
|
||||||
la->true_port = port;
|
la->true_port = port;
|
||||||
return 1;
|
return 1;
|
||||||
} else
|
} else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ParseFtpEprtCommand(struct libalias *la, char *sptr, int dlen)
|
ParseFtpEprtCommand(struct libalias *la, char *sptr, int dlen)
|
||||||
{
|
{
|
||||||
char ch, delim;
|
char ch, delim;
|
||||||
int i, state;
|
int i, state;
|
||||||
u_int32_t addr;
|
u_int32_t addr;
|
||||||
u_short port;
|
u_short port;
|
||||||
u_int8_t octet;
|
u_int8_t octet;
|
||||||
|
|
||||||
/* Format: "EPRT |1|A.D.D.R|PORT|". */
|
/* Format: "EPRT |1|A.D.D.R|PORT|". */
|
||||||
|
|
||||||
/* Return if data length is too short. */
|
/* Return if data length is too short. */
|
||||||
if (dlen < 18)
|
if (dlen < 18)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
addr = port = octet = 0;
|
addr = port = octet = 0;
|
||||||
delim = '|'; /* XXX gcc -Wuninitialized */
|
delim = '|'; /* XXX gcc -Wuninitialized */
|
||||||
state = -4;
|
state = -4;
|
||||||
for (i = 0; i < dlen; i++) {
|
for (i = 0; i < dlen; i++) {
|
||||||
ch = sptr[i];
|
ch = sptr[i];
|
||||||
switch (state)
|
switch (state) {
|
||||||
{
|
case -4:
|
||||||
case -4: if (ch == 'E') state++; else return 0; break;
|
if (ch == 'E')
|
||||||
case -3: if (ch == 'P') state++; else return 0; break;
|
state++;
|
||||||
case -2: if (ch == 'R') state++; else return 0; break;
|
else
|
||||||
case -1: if (ch == 'T') state++; else return 0; break;
|
return 0;
|
||||||
|
break;
|
||||||
|
case -3:
|
||||||
|
if (ch == 'P')
|
||||||
|
state++;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
case -2:
|
||||||
|
if (ch == 'R')
|
||||||
|
state++;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
case -1:
|
||||||
|
if (ch == 'T')
|
||||||
|
state++;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
|
||||||
case 0:
|
case 0:
|
||||||
if (!isspace(ch)) {
|
if (!isspace(ch)) {
|
||||||
delim = ch;
|
delim = ch;
|
||||||
state++;
|
state++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
if (ch == '1') /* IPv4 address */
|
if (ch == '1') /* IPv4 address */
|
||||||
state++;
|
state++;
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
if (ch == delim)
|
if (ch == delim)
|
||||||
state++;
|
state++;
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
case 3: case 5: case 7: case 9:
|
case 3:
|
||||||
if (isdigit(ch)) {
|
case 5:
|
||||||
octet = ch - '0';
|
case 7:
|
||||||
state++;
|
case 9:
|
||||||
} else
|
if (isdigit(ch)) {
|
||||||
return 0;
|
octet = ch - '0';
|
||||||
break;
|
state++;
|
||||||
case 4: case 6: case 8: case 10:
|
} else
|
||||||
if (isdigit(ch))
|
return 0;
|
||||||
octet = 10 * octet + ch - '0';
|
break;
|
||||||
else if (ch == '.' || state == 10) {
|
case 4:
|
||||||
addr = (addr << 8) + octet;
|
case 6:
|
||||||
state++;
|
case 8:
|
||||||
} else
|
case 10:
|
||||||
return 0;
|
if (isdigit(ch))
|
||||||
break;
|
octet = 10 * octet + ch - '0';
|
||||||
case 11:
|
else if (ch == '.' || state == 10) {
|
||||||
if (isdigit(ch)) {
|
addr = (addr << 8) + octet;
|
||||||
port = ch - '0';
|
state++;
|
||||||
state++;
|
} else
|
||||||
} else
|
return 0;
|
||||||
return 0;
|
break;
|
||||||
break;
|
case 11:
|
||||||
case 12:
|
if (isdigit(ch)) {
|
||||||
if (isdigit(ch))
|
port = ch - '0';
|
||||||
port = 10 * port + ch - '0';
|
state++;
|
||||||
else if (ch == delim)
|
} else
|
||||||
state++;
|
return 0;
|
||||||
else
|
break;
|
||||||
return 0;
|
case 12:
|
||||||
break;
|
if (isdigit(ch))
|
||||||
|
port = 10 * port + ch - '0';
|
||||||
|
else if (ch == delim)
|
||||||
|
state++;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (state == 13) {
|
if (state == 13) {
|
||||||
la->true_addr.s_addr = htonl(addr);
|
la->true_addr.s_addr = htonl(addr);
|
||||||
la->true_port = port;
|
la->true_port = port;
|
||||||
return 1;
|
return 1;
|
||||||
} else
|
} else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ParseFtp227Reply(struct libalias *la, char *sptr, int dlen)
|
ParseFtp227Reply(struct libalias *la, char *sptr, int dlen)
|
||||||
{
|
{
|
||||||
char ch;
|
char ch;
|
||||||
int i, state;
|
int i, state;
|
||||||
u_int32_t addr;
|
u_int32_t addr;
|
||||||
u_short port;
|
u_short port;
|
||||||
u_int8_t octet;
|
u_int8_t octet;
|
||||||
|
|
||||||
/* Format: "227 Entering Passive Mode (A,D,D,R,PO,RT)" */
|
/* Format: "227 Entering Passive Mode (A,D,D,R,PO,RT)" */
|
||||||
|
|
||||||
/* Return if data length is too short. */
|
/* Return if data length is too short. */
|
||||||
if (dlen < 17)
|
if (dlen < 17)
|
||||||
return 0;
|
|
||||||
|
|
||||||
addr = port = octet = 0;
|
|
||||||
|
|
||||||
state = -3;
|
|
||||||
for (i = 0; i < dlen; i++) {
|
|
||||||
ch = sptr[i];
|
|
||||||
switch (state)
|
|
||||||
{
|
|
||||||
case -3: if (ch == '2') state++; else return 0; break;
|
|
||||||
case -2: if (ch == '2') state++; else return 0; break;
|
|
||||||
case -1: if (ch == '7') state++; else return 0; break;
|
|
||||||
|
|
||||||
case 0:
|
|
||||||
if (ch == '(')
|
|
||||||
state++;
|
|
||||||
break;
|
|
||||||
case 1: case 3: case 5: case 7: case 9: case 11:
|
|
||||||
if (isdigit(ch)) {
|
|
||||||
octet = ch - '0';
|
|
||||||
state++;
|
|
||||||
} else
|
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
|
||||||
case 2: case 4: case 6: case 8:
|
addr = port = octet = 0;
|
||||||
if (isdigit(ch))
|
|
||||||
octet = 10 * octet + ch - '0';
|
state = -3;
|
||||||
else if (ch == ',') {
|
for (i = 0; i < dlen; i++) {
|
||||||
addr = (addr << 8) + octet;
|
ch = sptr[i];
|
||||||
state++;
|
switch (state) {
|
||||||
} else
|
case -3:
|
||||||
return 0;
|
if (ch == '2')
|
||||||
break;
|
state++;
|
||||||
case 10: case 12:
|
else
|
||||||
if (isdigit(ch))
|
return 0;
|
||||||
octet = 10 * octet + ch - '0';
|
break;
|
||||||
else if (ch == ',' || (state == 12 && ch == ')')) {
|
case -2:
|
||||||
port = (port << 8) + octet;
|
if (ch == '2')
|
||||||
state++;
|
state++;
|
||||||
} else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
|
case -1:
|
||||||
|
if (ch == '7')
|
||||||
|
state++;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0:
|
||||||
|
if (ch == '(')
|
||||||
|
state++;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
case 3:
|
||||||
|
case 5:
|
||||||
|
case 7:
|
||||||
|
case 9:
|
||||||
|
case 11:
|
||||||
|
if (isdigit(ch)) {
|
||||||
|
octet = ch - '0';
|
||||||
|
state++;
|
||||||
|
} else
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
case 4:
|
||||||
|
case 6:
|
||||||
|
case 8:
|
||||||
|
if (isdigit(ch))
|
||||||
|
octet = 10 * octet + ch - '0';
|
||||||
|
else if (ch == ',') {
|
||||||
|
addr = (addr << 8) + octet;
|
||||||
|
state++;
|
||||||
|
} else
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
case 12:
|
||||||
|
if (isdigit(ch))
|
||||||
|
octet = 10 * octet + ch - '0';
|
||||||
|
else if (ch == ',' || (state == 12 && ch == ')')) {
|
||||||
|
port = (port << 8) + octet;
|
||||||
|
state++;
|
||||||
|
} else
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (state == 13) {
|
if (state == 13) {
|
||||||
la->true_port = port;
|
la->true_port = port;
|
||||||
la->true_addr.s_addr = htonl(addr);
|
la->true_addr.s_addr = htonl(addr);
|
||||||
return 1;
|
return 1;
|
||||||
} else
|
} else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ParseFtp229Reply(struct libalias *la, char *sptr, int dlen)
|
ParseFtp229Reply(struct libalias *la, char *sptr, int dlen)
|
||||||
{
|
{
|
||||||
char ch, delim;
|
char ch, delim;
|
||||||
int i, state;
|
int i, state;
|
||||||
u_short port;
|
u_short port;
|
||||||
|
|
||||||
/* Format: "229 Entering Extended Passive Mode (|||PORT|)" */
|
/* Format: "229 Entering Extended Passive Mode (|||PORT|)" */
|
||||||
|
|
||||||
/* Return if data length is too short. */
|
/* Return if data length is too short. */
|
||||||
if (dlen < 11)
|
if (dlen < 11)
|
||||||
return 0;
|
|
||||||
|
|
||||||
port = 0;
|
|
||||||
delim = '|'; /* XXX gcc -Wuninitialized */
|
|
||||||
|
|
||||||
state = -3;
|
|
||||||
for (i = 0; i < dlen; i++) {
|
|
||||||
ch = sptr[i];
|
|
||||||
switch (state)
|
|
||||||
{
|
|
||||||
case -3: if (ch == '2') state++; else return 0; break;
|
|
||||||
case -2: if (ch == '2') state++; else return 0; break;
|
|
||||||
case -1: if (ch == '9') state++; else return 0; break;
|
|
||||||
|
|
||||||
case 0:
|
|
||||||
if (ch == '(')
|
|
||||||
state++;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
delim = ch;
|
|
||||||
state++;
|
|
||||||
break;
|
|
||||||
case 2: case 3:
|
|
||||||
if (ch == delim)
|
|
||||||
state++;
|
|
||||||
else
|
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
|
||||||
case 4:
|
port = 0;
|
||||||
if (isdigit(ch)) {
|
delim = '|'; /* XXX gcc -Wuninitialized */
|
||||||
port = ch - '0';
|
|
||||||
state++;
|
state = -3;
|
||||||
} else
|
for (i = 0; i < dlen; i++) {
|
||||||
return 0;
|
ch = sptr[i];
|
||||||
break;
|
switch (state) {
|
||||||
case 5:
|
case -3:
|
||||||
if (isdigit(ch))
|
if (ch == '2')
|
||||||
port = 10 * port + ch - '0';
|
state++;
|
||||||
else if (ch == delim)
|
else
|
||||||
state++;
|
return 0;
|
||||||
else
|
break;
|
||||||
return 0;
|
case -2:
|
||||||
break;
|
if (ch == '2')
|
||||||
case 6:
|
state++;
|
||||||
if (ch == ')')
|
else
|
||||||
state++;
|
return 0;
|
||||||
else
|
break;
|
||||||
return 0;
|
case -1:
|
||||||
break;
|
if (ch == '9')
|
||||||
|
state++;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0:
|
||||||
|
if (ch == '(')
|
||||||
|
state++;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
delim = ch;
|
||||||
|
state++;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
if (ch == delim)
|
||||||
|
state++;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
if (isdigit(ch)) {
|
||||||
|
port = ch - '0';
|
||||||
|
state++;
|
||||||
|
} else
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
if (isdigit(ch))
|
||||||
|
port = 10 * port + ch - '0';
|
||||||
|
else if (ch == delim)
|
||||||
|
state++;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
if (ch == ')')
|
||||||
|
state++;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (state == 7) {
|
if (state == 7) {
|
||||||
la->true_port = port;
|
la->true_port = port;
|
||||||
return 1;
|
return 1;
|
||||||
} else
|
} else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
NewFtpMessage(struct libalias *la, struct ip *pip,
|
NewFtpMessage(struct libalias *la, struct ip *pip,
|
||||||
struct alias_link *link,
|
struct alias_link *link,
|
||||||
int maxpacketsize,
|
int maxpacketsize,
|
||||||
int ftp_message_type)
|
int ftp_message_type)
|
||||||
{
|
{
|
||||||
struct alias_link *ftp_link;
|
struct alias_link *ftp_link;
|
||||||
|
|
||||||
/* Security checks. */
|
/* Security checks. */
|
||||||
if (pip->ip_src.s_addr != la->true_addr.s_addr)
|
if (pip->ip_src.s_addr != la->true_addr.s_addr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (la->true_port < IPPORT_RESERVED)
|
if (la->true_port < IPPORT_RESERVED)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Establish link to address and port found in FTP control message. */
|
/* Establish link to address and port found in FTP control message. */
|
||||||
ftp_link = FindUdpTcpOut(la, la->true_addr, GetDestAddress(link),
|
ftp_link = FindUdpTcpOut(la, la->true_addr, GetDestAddress(link),
|
||||||
htons(la->true_port), 0, IPPROTO_TCP, 1);
|
htons(la->true_port), 0, IPPROTO_TCP, 1);
|
||||||
|
|
||||||
if (ftp_link != NULL)
|
if (ftp_link != NULL) {
|
||||||
{
|
int slen, hlen, tlen, dlen;
|
||||||
int slen, hlen, tlen, dlen;
|
struct tcphdr *tc;
|
||||||
struct tcphdr *tc;
|
|
||||||
|
|
||||||
#ifndef NO_FW_PUNCH
|
#ifndef NO_FW_PUNCH
|
||||||
/* Punch hole in firewall */
|
/* Punch hole in firewall */
|
||||||
PunchFWHole(ftp_link);
|
PunchFWHole(ftp_link);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Calculate data length of TCP packet */
|
/* Calculate data length of TCP packet */
|
||||||
tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
|
tc = (struct tcphdr *)((char *)pip + (pip->ip_hl << 2));
|
||||||
hlen = (pip->ip_hl + tc->th_off) << 2;
|
hlen = (pip->ip_hl + tc->th_off) << 2;
|
||||||
tlen = ntohs(pip->ip_len);
|
tlen = ntohs(pip->ip_len);
|
||||||
dlen = tlen - hlen;
|
dlen = tlen - hlen;
|
||||||
|
|
||||||
/* Create new FTP message. */
|
/* Create new FTP message. */
|
||||||
{
|
{
|
||||||
char stemp[MAX_MESSAGE_SIZE + 1];
|
char stemp[MAX_MESSAGE_SIZE + 1];
|
||||||
char *sptr;
|
char *sptr;
|
||||||
u_short alias_port;
|
u_short alias_port;
|
||||||
u_char *ptr;
|
u_char *ptr;
|
||||||
int a1, a2, a3, a4, p1, p2;
|
int a1, a2, a3, a4, p1, p2;
|
||||||
struct in_addr alias_address;
|
struct in_addr alias_address;
|
||||||
|
|
||||||
/* Decompose alias address into quad format */
|
/* Decompose alias address into quad format */
|
||||||
alias_address = GetAliasAddress(link);
|
alias_address = GetAliasAddress(link);
|
||||||
ptr = (u_char *) &alias_address.s_addr;
|
ptr = (u_char *) & alias_address.s_addr;
|
||||||
a1 = *ptr++; a2=*ptr++; a3=*ptr++; a4=*ptr;
|
a1 = *ptr++;
|
||||||
|
a2 = *ptr++;
|
||||||
|
a3 = *ptr++;
|
||||||
|
a4 = *ptr;
|
||||||
|
|
||||||
alias_port = GetAliasPort(ftp_link);
|
alias_port = GetAliasPort(ftp_link);
|
||||||
|
|
||||||
switch (ftp_message_type)
|
switch (ftp_message_type) {
|
||||||
{
|
case FTP_PORT_COMMAND:
|
||||||
case FTP_PORT_COMMAND:
|
case FTP_227_REPLY:
|
||||||
case FTP_227_REPLY:
|
/* Decompose alias port into pair format. */
|
||||||
/* Decompose alias port into pair format. */
|
ptr = (char *)&alias_port;
|
||||||
ptr = (char *) &alias_port;
|
p1 = *ptr++;
|
||||||
p1 = *ptr++; p2=*ptr;
|
p2 = *ptr;
|
||||||
|
|
||||||
if (ftp_message_type == FTP_PORT_COMMAND) {
|
if (ftp_message_type == FTP_PORT_COMMAND) {
|
||||||
/* Generate PORT command string. */
|
/* Generate PORT command string. */
|
||||||
sprintf(stemp, "PORT %d,%d,%d,%d,%d,%d\r\n",
|
sprintf(stemp, "PORT %d,%d,%d,%d,%d,%d\r\n",
|
||||||
a1,a2,a3,a4,p1,p2);
|
a1, a2, a3, a4, p1, p2);
|
||||||
} else {
|
} else {
|
||||||
/* Generate 227 reply string. */
|
/* Generate 227 reply string. */
|
||||||
sprintf(stemp,
|
sprintf(stemp,
|
||||||
"227 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n",
|
"227 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n",
|
||||||
a1,a2,a3,a4,p1,p2);
|
a1, a2, a3, a4, p1, p2);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FTP_EPRT_COMMAND:
|
case FTP_EPRT_COMMAND:
|
||||||
/* Generate EPRT command string. */
|
/* Generate EPRT command string. */
|
||||||
sprintf(stemp, "EPRT |1|%d.%d.%d.%d|%d|\r\n",
|
sprintf(stemp, "EPRT |1|%d.%d.%d.%d|%d|\r\n",
|
||||||
a1,a2,a3,a4,ntohs(alias_port));
|
a1, a2, a3, a4, ntohs(alias_port));
|
||||||
break;
|
break;
|
||||||
case FTP_229_REPLY:
|
case FTP_229_REPLY:
|
||||||
/* Generate 229 reply string. */
|
/* Generate 229 reply string. */
|
||||||
sprintf(stemp, "229 Entering Extended Passive Mode (|||%d|)\r\n",
|
sprintf(stemp, "229 Entering Extended Passive Mode (|||%d|)\r\n",
|
||||||
ntohs(alias_port));
|
ntohs(alias_port));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save string length for IP header modification */
|
/* Save string length for IP header modification */
|
||||||
slen = strlen(stemp);
|
slen = strlen(stemp);
|
||||||
|
|
||||||
/* Copy modified buffer into IP packet. */
|
/* Copy modified buffer into IP packet. */
|
||||||
sptr = (char *) pip; sptr += hlen;
|
sptr = (char *)pip;
|
||||||
strncpy(sptr, stemp, maxpacketsize-hlen);
|
sptr += hlen;
|
||||||
}
|
strncpy(sptr, stemp, maxpacketsize - hlen);
|
||||||
|
}
|
||||||
|
|
||||||
/* Save information regarding modified seq and ack numbers */
|
/* Save information regarding modified seq and ack numbers */
|
||||||
{
|
{
|
||||||
int delta;
|
int delta;
|
||||||
|
|
||||||
SetAckModified(link);
|
SetAckModified(link);
|
||||||
delta = GetDeltaSeqOut(pip, link);
|
delta = GetDeltaSeqOut(pip, link);
|
||||||
AddSeq(pip, link, delta+slen-dlen);
|
AddSeq(pip, link, delta + slen - dlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Revise IP header */
|
/* Revise IP header */
|
||||||
{
|
{
|
||||||
u_short new_len;
|
u_short new_len;
|
||||||
|
|
||||||
new_len = htons(hlen + slen);
|
new_len = htons(hlen + slen);
|
||||||
DifferentialChecksum(&pip->ip_sum,
|
DifferentialChecksum(&pip->ip_sum,
|
||||||
&new_len,
|
&new_len,
|
||||||
&pip->ip_len,
|
&pip->ip_len,
|
||||||
1);
|
1);
|
||||||
pip->ip_len = new_len;
|
pip->ip_len = new_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compute TCP checksum for revised packet */
|
/* Compute TCP checksum for revised packet */
|
||||||
tc->th_sum = 0;
|
tc->th_sum = 0;
|
||||||
tc->th_sum = TcpChecksum(pip);
|
tc->th_sum = TcpChecksum(pip);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"PacketAlias/HandleFtpOut: Cannot allocate FTP data port\n");
|
"PacketAlias/HandleFtpOut: Cannot allocate FTP data port\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,277 +65,305 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
AliasHandleIrcOut(struct libalias *la,
|
AliasHandleIrcOut(struct libalias *la,
|
||||||
struct ip *pip, /* IP packet to examine */
|
struct ip *pip, /* IP packet to examine */
|
||||||
struct alias_link *link, /* Which link are we on? */
|
struct alias_link *link, /* Which link are we on? */
|
||||||
int maxsize /* Maximum size of IP packet including headers */
|
int maxsize /* Maximum size of IP packet including
|
||||||
)
|
* headers */
|
||||||
|
)
|
||||||
{
|
{
|
||||||
int hlen, tlen, dlen;
|
int hlen, tlen, dlen;
|
||||||
struct in_addr true_addr;
|
struct in_addr true_addr;
|
||||||
u_short true_port;
|
u_short true_port;
|
||||||
char *sptr;
|
char *sptr;
|
||||||
struct tcphdr *tc;
|
struct tcphdr *tc;
|
||||||
int i; /* Iterator through the source */
|
int i; /* Iterator through the source */
|
||||||
|
|
||||||
/* Calculate data length of TCP packet */
|
/* Calculate data length of TCP packet */
|
||||||
tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
|
tc = (struct tcphdr *)((char *)pip + (pip->ip_hl << 2));
|
||||||
hlen = (pip->ip_hl + tc->th_off) << 2;
|
hlen = (pip->ip_hl + tc->th_off) << 2;
|
||||||
tlen = ntohs(pip->ip_len);
|
tlen = ntohs(pip->ip_len);
|
||||||
dlen = tlen - hlen;
|
dlen = tlen - hlen;
|
||||||
|
|
||||||
/* Return if data length is too short - assume an entire PRIVMSG in each packet. */
|
/*
|
||||||
if (dlen<sizeof(":A!a@n.n PRIVMSG A :aDCC 1 1a")-1)
|
* Return if data length is too short - assume an entire PRIVMSG in
|
||||||
return;
|
* each packet.
|
||||||
|
*/
|
||||||
|
if (dlen < sizeof(":A!a@n.n PRIVMSG A :aDCC 1 1a") - 1)
|
||||||
|
return;
|
||||||
|
|
||||||
/* Place string pointer at beginning of data */
|
/* Place string pointer at beginning of data */
|
||||||
sptr = (char *) pip;
|
sptr = (char *)pip;
|
||||||
sptr += hlen;
|
sptr += hlen;
|
||||||
maxsize -= hlen; /* We're interested in maximum size of data, not packet */
|
maxsize -= hlen; /* We're interested in maximum size of
|
||||||
|
* data, not packet */
|
||||||
|
|
||||||
/* Search for a CTCP command [Note 1] */
|
/* Search for a CTCP command [Note 1] */
|
||||||
for( i=0; i<dlen; i++ ) {
|
for (i = 0; i < dlen; i++) {
|
||||||
if(sptr[i]=='\001')
|
if (sptr[i] == '\001')
|
||||||
goto lFOUND_CTCP;
|
goto lFOUND_CTCP;
|
||||||
}
|
}
|
||||||
return; /* No CTCP commands in */
|
return; /* No CTCP commands in */
|
||||||
/* Handle CTCP commands - the buffer may have to be copied */
|
/* Handle CTCP commands - the buffer may have to be copied */
|
||||||
lFOUND_CTCP:
|
lFOUND_CTCP:
|
||||||
{
|
{
|
||||||
char newpacket[65536]; /* Estimate of maximum packet size :) */
|
char newpacket[65536]; /* Estimate of maximum packet size
|
||||||
int copyat = i; /* Same */
|
* :) */
|
||||||
int iCopy = 0; /* How much data have we written to copy-back string? */
|
int copyat = i; /* Same */
|
||||||
unsigned long org_addr; /* Original IP address */
|
int iCopy = 0; /* How much data have we written to
|
||||||
unsigned short org_port; /* Original source port address */
|
* copy-back string? */
|
||||||
lCTCP_START:
|
unsigned long org_addr; /* Original IP address */
|
||||||
if( i >= dlen || iCopy >= sizeof(newpacket) )
|
unsigned short org_port; /* Original source port
|
||||||
goto lPACKET_DONE;
|
* address */
|
||||||
newpacket[iCopy++] = sptr[i++]; /* Copy the CTCP start character */
|
|
||||||
/* Start of a CTCP */
|
|
||||||
if( i+4 >= dlen ) /* Too short for DCC */
|
|
||||||
goto lBAD_CTCP;
|
|
||||||
if( sptr[i+0] != 'D' )
|
|
||||||
goto lBAD_CTCP;
|
|
||||||
if( sptr[i+1] != 'C' )
|
|
||||||
goto lBAD_CTCP;
|
|
||||||
if( sptr[i+2] != 'C' )
|
|
||||||
goto lBAD_CTCP;
|
|
||||||
if( sptr[i+3] != ' ' )
|
|
||||||
goto lBAD_CTCP;
|
|
||||||
/* We have a DCC command - handle it! */
|
|
||||||
i+= 4; /* Skip "DCC " */
|
|
||||||
if( iCopy+4 > sizeof(newpacket) )
|
|
||||||
goto lPACKET_DONE;
|
|
||||||
newpacket[iCopy++] = 'D';
|
|
||||||
newpacket[iCopy++] = 'C';
|
|
||||||
newpacket[iCopy++] = 'C';
|
|
||||||
newpacket[iCopy++] = ' ';
|
|
||||||
|
|
||||||
DBprintf(("Found DCC\n"));
|
lCTCP_START:
|
||||||
/* Skip any extra spaces (should not occur according to
|
if (i >= dlen || iCopy >= sizeof(newpacket))
|
||||||
protocol, but DCC breaks CTCP protocol anyway */
|
goto lPACKET_DONE;
|
||||||
while(sptr[i] == ' ') {
|
newpacket[iCopy++] = sptr[i++]; /* Copy the CTCP start
|
||||||
if( ++i >= dlen) {
|
* character */
|
||||||
DBprintf(("DCC packet terminated in just spaces\n"));
|
/* Start of a CTCP */
|
||||||
goto lPACKET_DONE;
|
if (i + 4 >= dlen) /* Too short for DCC */
|
||||||
}
|
goto lBAD_CTCP;
|
||||||
}
|
if (sptr[i + 0] != 'D')
|
||||||
|
goto lBAD_CTCP;
|
||||||
|
if (sptr[i + 1] != 'C')
|
||||||
|
goto lBAD_CTCP;
|
||||||
|
if (sptr[i + 2] != 'C')
|
||||||
|
goto lBAD_CTCP;
|
||||||
|
if (sptr[i + 3] != ' ')
|
||||||
|
goto lBAD_CTCP;
|
||||||
|
/* We have a DCC command - handle it! */
|
||||||
|
i += 4; /* Skip "DCC " */
|
||||||
|
if (iCopy + 4 > sizeof(newpacket))
|
||||||
|
goto lPACKET_DONE;
|
||||||
|
newpacket[iCopy++] = 'D';
|
||||||
|
newpacket[iCopy++] = 'C';
|
||||||
|
newpacket[iCopy++] = 'C';
|
||||||
|
newpacket[iCopy++] = ' ';
|
||||||
|
|
||||||
DBprintf(("Transferring command...\n"));
|
DBprintf(("Found DCC\n"));
|
||||||
while(sptr[i] != ' ') {
|
/*
|
||||||
newpacket[iCopy++] = sptr[i];
|
* Skip any extra spaces (should not occur according to
|
||||||
if( ++i >= dlen || iCopy >= sizeof(newpacket) ) {
|
* protocol, but DCC breaks CTCP protocol anyway
|
||||||
DBprintf(("DCC packet terminated during command\n"));
|
*/
|
||||||
goto lPACKET_DONE;
|
while (sptr[i] == ' ') {
|
||||||
}
|
if (++i >= dlen) {
|
||||||
}
|
DBprintf(("DCC packet terminated in just spaces\n"));
|
||||||
/* Copy _one_ space */
|
goto lPACKET_DONE;
|
||||||
if( i+1 < dlen && iCopy < sizeof(newpacket) )
|
}
|
||||||
newpacket[iCopy++] = sptr[i++];
|
}
|
||||||
|
|
||||||
DBprintf(("Done command - removing spaces\n"));
|
DBprintf(("Transferring command...\n"));
|
||||||
/* Skip any extra spaces (should not occur according to
|
while (sptr[i] != ' ') {
|
||||||
protocol, but DCC breaks CTCP protocol anyway */
|
newpacket[iCopy++] = sptr[i];
|
||||||
while(sptr[i] == ' ') {
|
if (++i >= dlen || iCopy >= sizeof(newpacket)) {
|
||||||
if( ++i >= dlen ) {
|
DBprintf(("DCC packet terminated during command\n"));
|
||||||
DBprintf(("DCC packet terminated in just spaces (post-command)\n"));
|
goto lPACKET_DONE;
|
||||||
goto lPACKET_DONE;
|
}
|
||||||
}
|
}
|
||||||
}
|
/* Copy _one_ space */
|
||||||
|
if (i + 1 < dlen && iCopy < sizeof(newpacket))
|
||||||
|
newpacket[iCopy++] = sptr[i++];
|
||||||
|
|
||||||
DBprintf(("Transferring filename...\n"));
|
DBprintf(("Done command - removing spaces\n"));
|
||||||
while(sptr[i] != ' ') {
|
/*
|
||||||
newpacket[iCopy++] = sptr[i];
|
* Skip any extra spaces (should not occur according to
|
||||||
if( ++i >= dlen || iCopy >= sizeof(newpacket) ) {
|
* protocol, but DCC breaks CTCP protocol anyway
|
||||||
DBprintf(("DCC packet terminated during filename\n"));
|
*/
|
||||||
goto lPACKET_DONE;
|
while (sptr[i] == ' ') {
|
||||||
}
|
if (++i >= dlen) {
|
||||||
}
|
DBprintf(("DCC packet terminated in just spaces (post-command)\n"));
|
||||||
/* Copy _one_ space */
|
goto lPACKET_DONE;
|
||||||
if( i+1 < dlen && iCopy < sizeof(newpacket) )
|
}
|
||||||
newpacket[iCopy++] = sptr[i++];
|
}
|
||||||
|
|
||||||
DBprintf(("Done filename - removing spaces\n"));
|
DBprintf(("Transferring filename...\n"));
|
||||||
/* Skip any extra spaces (should not occur according to
|
while (sptr[i] != ' ') {
|
||||||
protocol, but DCC breaks CTCP protocol anyway */
|
newpacket[iCopy++] = sptr[i];
|
||||||
while(sptr[i] == ' ') {
|
if (++i >= dlen || iCopy >= sizeof(newpacket)) {
|
||||||
if( ++i >= dlen ) {
|
DBprintf(("DCC packet terminated during filename\n"));
|
||||||
DBprintf(("DCC packet terminated in just spaces (post-filename)\n"));
|
goto lPACKET_DONE;
|
||||||
goto lPACKET_DONE;
|
}
|
||||||
}
|
}
|
||||||
}
|
/* Copy _one_ space */
|
||||||
|
if (i + 1 < dlen && iCopy < sizeof(newpacket))
|
||||||
|
newpacket[iCopy++] = sptr[i++];
|
||||||
|
|
||||||
DBprintf(("Fetching IP address\n"));
|
DBprintf(("Done filename - removing spaces\n"));
|
||||||
/* Fetch IP address */
|
/*
|
||||||
org_addr = 0;
|
* Skip any extra spaces (should not occur according to
|
||||||
while(i<dlen && isdigit(sptr[i])) {
|
* protocol, but DCC breaks CTCP protocol anyway
|
||||||
if( org_addr > ULONG_MAX/10UL ) { /* Terminate on overflow */
|
*/
|
||||||
DBprintf(("DCC Address overflow (org_addr == 0x%08lx, next char %c\n", org_addr, sptr[i]));
|
while (sptr[i] == ' ') {
|
||||||
goto lBAD_CTCP;
|
if (++i >= dlen) {
|
||||||
}
|
DBprintf(("DCC packet terminated in just spaces (post-filename)\n"));
|
||||||
org_addr *= 10;
|
goto lPACKET_DONE;
|
||||||
org_addr += sptr[i++]-'0';
|
}
|
||||||
}
|
}
|
||||||
DBprintf(("Skipping space\n"));
|
|
||||||
if( i+1 >= dlen || sptr[i] != ' ' ) {
|
|
||||||
DBprintf(("Overflow (%d >= %d) or bad character (%02x) terminating IP address\n", i+1, dlen, sptr[i]));
|
|
||||||
goto lBAD_CTCP;
|
|
||||||
}
|
|
||||||
/* Skip any extra spaces (should not occur according to
|
|
||||||
protocol, but DCC breaks CTCP protocol anyway, so we might
|
|
||||||
as well play it safe */
|
|
||||||
while(sptr[i] == ' ') {
|
|
||||||
if( ++i >= dlen ) {
|
|
||||||
DBprintf(("Packet failure - space overflow.\n"));
|
|
||||||
goto lPACKET_DONE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DBprintf(("Fetching port number\n"));
|
|
||||||
/* Fetch source port */
|
|
||||||
org_port = 0;
|
|
||||||
while(i<dlen && isdigit(sptr[i])) {
|
|
||||||
if( org_port > 6554 ) { /* Terminate on overflow (65536/10 rounded up*/
|
|
||||||
DBprintf(("DCC: port number overflow\n"));
|
|
||||||
goto lBAD_CTCP;
|
|
||||||
}
|
|
||||||
org_port *= 10;
|
|
||||||
org_port += sptr[i++]-'0';
|
|
||||||
}
|
|
||||||
/* Skip illegal addresses (or early termination) */
|
|
||||||
if( i >= dlen || (sptr[i] != '\001' && sptr[i] != ' ') ) {
|
|
||||||
DBprintf(("Bad port termination\n"));
|
|
||||||
goto lBAD_CTCP;
|
|
||||||
}
|
|
||||||
DBprintf(("Got IP %lu and port %u\n", org_addr, (unsigned)org_port));
|
|
||||||
|
|
||||||
/* We've got the address and port - now alias it */
|
DBprintf(("Fetching IP address\n"));
|
||||||
{
|
/* Fetch IP address */
|
||||||
struct alias_link *dcc_link;
|
org_addr = 0;
|
||||||
struct in_addr destaddr;
|
while (i < dlen && isdigit(sptr[i])) {
|
||||||
|
if (org_addr > ULONG_MAX / 10UL) { /* Terminate on overflow */
|
||||||
|
DBprintf(("DCC Address overflow (org_addr == 0x%08lx, next char %c\n", org_addr, sptr[i]));
|
||||||
|
goto lBAD_CTCP;
|
||||||
|
}
|
||||||
|
org_addr *= 10;
|
||||||
|
org_addr += sptr[i++] - '0';
|
||||||
|
}
|
||||||
|
DBprintf(("Skipping space\n"));
|
||||||
|
if (i + 1 >= dlen || sptr[i] != ' ') {
|
||||||
|
DBprintf(("Overflow (%d >= %d) or bad character (%02x) terminating IP address\n", i + 1, dlen, sptr[i]));
|
||||||
|
goto lBAD_CTCP;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Skip any extra spaces (should not occur according to
|
||||||
|
* protocol, but DCC breaks CTCP protocol anyway, so we
|
||||||
|
* might as well play it safe
|
||||||
|
*/
|
||||||
|
while (sptr[i] == ' ') {
|
||||||
|
if (++i >= dlen) {
|
||||||
|
DBprintf(("Packet failure - space overflow.\n"));
|
||||||
|
goto lPACKET_DONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DBprintf(("Fetching port number\n"));
|
||||||
|
/* Fetch source port */
|
||||||
|
org_port = 0;
|
||||||
|
while (i < dlen && isdigit(sptr[i])) {
|
||||||
|
if (org_port > 6554) { /* Terminate on overflow
|
||||||
|
* (65536/10 rounded up */
|
||||||
|
DBprintf(("DCC: port number overflow\n"));
|
||||||
|
goto lBAD_CTCP;
|
||||||
|
}
|
||||||
|
org_port *= 10;
|
||||||
|
org_port += sptr[i++] - '0';
|
||||||
|
}
|
||||||
|
/* Skip illegal addresses (or early termination) */
|
||||||
|
if (i >= dlen || (sptr[i] != '\001' && sptr[i] != ' ')) {
|
||||||
|
DBprintf(("Bad port termination\n"));
|
||||||
|
goto lBAD_CTCP;
|
||||||
|
}
|
||||||
|
DBprintf(("Got IP %lu and port %u\n", org_addr, (unsigned)org_port));
|
||||||
|
|
||||||
|
/* We've got the address and port - now alias it */
|
||||||
|
{
|
||||||
|
struct alias_link *dcc_link;
|
||||||
|
struct in_addr destaddr;
|
||||||
|
|
||||||
|
|
||||||
true_port = htons(org_port);
|
true_port = htons(org_port);
|
||||||
true_addr.s_addr = htonl(org_addr);
|
true_addr.s_addr = htonl(org_addr);
|
||||||
destaddr.s_addr = 0;
|
destaddr.s_addr = 0;
|
||||||
|
|
||||||
/* Sanity/Security checking */
|
/* Sanity/Security checking */
|
||||||
if (!org_addr || !org_port ||
|
if (!org_addr || !org_port ||
|
||||||
pip->ip_src.s_addr != true_addr.s_addr ||
|
pip->ip_src.s_addr != true_addr.s_addr ||
|
||||||
org_port < IPPORT_RESERVED)
|
org_port < IPPORT_RESERVED)
|
||||||
goto lBAD_CTCP;
|
goto lBAD_CTCP;
|
||||||
|
|
||||||
/* Steal the FTP_DATA_PORT - it doesn't really matter, and this
|
/*
|
||||||
would probably allow it through at least _some_
|
* Steal the FTP_DATA_PORT - it doesn't really
|
||||||
firewalls. */
|
* matter, and this would probably allow it through
|
||||||
dcc_link = FindUdpTcpOut(la, true_addr, destaddr,
|
* at least _some_ firewalls.
|
||||||
true_port, 0,
|
*/
|
||||||
IPPROTO_TCP, 1);
|
dcc_link = FindUdpTcpOut(la, true_addr, destaddr,
|
||||||
DBprintf(("Got a DCC link\n"));
|
true_port, 0,
|
||||||
if ( dcc_link ) {
|
IPPROTO_TCP, 1);
|
||||||
struct in_addr alias_address; /* Address from aliasing */
|
DBprintf(("Got a DCC link\n"));
|
||||||
u_short alias_port; /* Port given by aliasing */
|
if (dcc_link) {
|
||||||
int n;
|
struct in_addr alias_address; /* Address from aliasing */
|
||||||
|
u_short alias_port; /* Port given by
|
||||||
|
* aliasing */
|
||||||
|
int n;
|
||||||
|
|
||||||
#ifndef NO_FW_PUNCH
|
#ifndef NO_FW_PUNCH
|
||||||
/* Generate firewall hole as appropriate */
|
/* Generate firewall hole as appropriate */
|
||||||
PunchFWHole(dcc_link);
|
PunchFWHole(dcc_link);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
alias_address = GetAliasAddress(link);
|
alias_address = GetAliasAddress(link);
|
||||||
n = snprintf(&newpacket[iCopy],
|
n = snprintf(&newpacket[iCopy],
|
||||||
sizeof(newpacket)-iCopy,
|
sizeof(newpacket) - iCopy,
|
||||||
"%lu ", (u_long)htonl(alias_address.s_addr));
|
"%lu ", (u_long) htonl(alias_address.s_addr));
|
||||||
if( n < 0 ) {
|
if (n < 0) {
|
||||||
DBprintf(("DCC packet construct failure.\n"));
|
DBprintf(("DCC packet construct failure.\n"));
|
||||||
goto lBAD_CTCP;
|
goto lBAD_CTCP;
|
||||||
}
|
}
|
||||||
if( (iCopy += n) >= sizeof(newpacket) ) { /* Truncated/fit exactly - bad news */
|
if ((iCopy += n) >= sizeof(newpacket)) { /* Truncated/fit exactly
|
||||||
DBprintf(("DCC constructed packet overflow.\n"));
|
* - bad news */
|
||||||
goto lBAD_CTCP;
|
DBprintf(("DCC constructed packet overflow.\n"));
|
||||||
}
|
goto lBAD_CTCP;
|
||||||
alias_port = GetAliasPort(dcc_link);
|
}
|
||||||
n = snprintf(&newpacket[iCopy],
|
alias_port = GetAliasPort(dcc_link);
|
||||||
sizeof(newpacket)-iCopy,
|
n = snprintf(&newpacket[iCopy],
|
||||||
"%u", htons(alias_port) );
|
sizeof(newpacket) - iCopy,
|
||||||
if( n < 0 ) {
|
"%u", htons(alias_port));
|
||||||
DBprintf(("DCC packet construct failure.\n"));
|
if (n < 0) {
|
||||||
goto lBAD_CTCP;
|
DBprintf(("DCC packet construct failure.\n"));
|
||||||
}
|
goto lBAD_CTCP;
|
||||||
iCopy += n;
|
}
|
||||||
/* Done - truncated cases will be taken care of by lBAD_CTCP */
|
iCopy += n;
|
||||||
DBprintf(("Aliased IP %lu and port %u\n", alias_address.s_addr, (unsigned)alias_port));
|
/*
|
||||||
}
|
* Done - truncated cases will be taken
|
||||||
}
|
* care of by lBAD_CTCP
|
||||||
/* An uninteresting CTCP - state entered right after '\001' has
|
*/
|
||||||
been pushed. Also used to copy the rest of a DCC, after IP
|
DBprintf(("Aliased IP %lu and port %u\n", alias_address.s_addr, (unsigned)alias_port));
|
||||||
address and port has been handled */
|
}
|
||||||
lBAD_CTCP:
|
}
|
||||||
for(; i<dlen && iCopy<sizeof(newpacket); i++,iCopy++) {
|
/*
|
||||||
newpacket[iCopy] = sptr[i]; /* Copy CTCP unchanged */
|
* An uninteresting CTCP - state entered right after '\001'
|
||||||
if(sptr[i] == '\001') {
|
* has been pushed. Also used to copy the rest of a DCC,
|
||||||
goto lNORMAL_TEXT;
|
* after IP address and port has been handled
|
||||||
}
|
*/
|
||||||
}
|
lBAD_CTCP:
|
||||||
goto lPACKET_DONE;
|
for (; i < dlen && iCopy < sizeof(newpacket); i++, iCopy++) {
|
||||||
/* Normal text */
|
newpacket[iCopy] = sptr[i]; /* Copy CTCP unchanged */
|
||||||
lNORMAL_TEXT:
|
if (sptr[i] == '\001') {
|
||||||
for(; i<dlen && iCopy<sizeof(newpacket); i++,iCopy++) {
|
goto lNORMAL_TEXT;
|
||||||
newpacket[iCopy] = sptr[i]; /* Copy CTCP unchanged */
|
}
|
||||||
if(sptr[i] == '\001') {
|
}
|
||||||
goto lCTCP_START;
|
goto lPACKET_DONE;
|
||||||
}
|
/* Normal text */
|
||||||
}
|
lNORMAL_TEXT:
|
||||||
/* Handle the end of a packet */
|
for (; i < dlen && iCopy < sizeof(newpacket); i++, iCopy++) {
|
||||||
lPACKET_DONE:
|
newpacket[iCopy] = sptr[i]; /* Copy CTCP unchanged */
|
||||||
iCopy = iCopy > maxsize-copyat ? maxsize-copyat : iCopy;
|
if (sptr[i] == '\001') {
|
||||||
memcpy(sptr+copyat, newpacket, iCopy);
|
goto lCTCP_START;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Handle the end of a packet */
|
||||||
|
lPACKET_DONE:
|
||||||
|
iCopy = iCopy > maxsize - copyat ? maxsize - copyat : iCopy;
|
||||||
|
memcpy(sptr + copyat, newpacket, iCopy);
|
||||||
|
|
||||||
/* Save information regarding modified seq and ack numbers */
|
/* Save information regarding modified seq and ack numbers */
|
||||||
{
|
{
|
||||||
int delta;
|
int delta;
|
||||||
|
|
||||||
SetAckModified(link);
|
SetAckModified(link);
|
||||||
delta = GetDeltaSeqOut(pip, link);
|
delta = GetDeltaSeqOut(pip, link);
|
||||||
AddSeq(pip, link, delta+copyat+iCopy-dlen);
|
AddSeq(pip, link, delta + copyat + iCopy - dlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Revise IP header */
|
/* Revise IP header */
|
||||||
{
|
{
|
||||||
u_short new_len;
|
u_short new_len;
|
||||||
|
|
||||||
new_len = htons(hlen + iCopy + copyat);
|
new_len = htons(hlen + iCopy + copyat);
|
||||||
DifferentialChecksum(&pip->ip_sum,
|
DifferentialChecksum(&pip->ip_sum,
|
||||||
&new_len,
|
&new_len,
|
||||||
&pip->ip_len,
|
&pip->ip_len,
|
||||||
1);
|
1);
|
||||||
pip->ip_len = new_len;
|
pip->ip_len = new_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compute TCP checksum for revised packet */
|
/* Compute TCP checksum for revised packet */
|
||||||
tc->th_sum = 0;
|
tc->th_sum = 0;
|
||||||
tc->th_sum = TcpChecksum(pip);
|
tc->th_sum = TcpChecksum(pip);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Notes:
|
/* Notes:
|
||||||
|
@ -55,80 +55,84 @@
|
|||||||
struct proxy_entry;
|
struct proxy_entry;
|
||||||
|
|
||||||
struct libalias {
|
struct libalias {
|
||||||
LIST_ENTRY(libalias) instancelist;
|
LIST_ENTRY(libalias) instancelist;
|
||||||
|
|
||||||
int packetAliasMode; /* Mode flags */
|
int packetAliasMode; /* Mode flags */
|
||||||
/* - documented in alias.h */
|
/* - documented in alias.h */
|
||||||
|
|
||||||
struct in_addr aliasAddress; /* Address written onto source */
|
struct in_addr aliasAddress; /* Address written onto source */
|
||||||
/* field of IP packet. */
|
/* field of IP packet. */
|
||||||
|
|
||||||
struct in_addr targetAddress; /* IP address incoming packets */
|
struct in_addr targetAddress; /* IP address incoming packets */
|
||||||
/* are sent to if no aliasing */
|
/* are sent to if no aliasing */
|
||||||
/* link already exists */
|
/* link already exists */
|
||||||
|
|
||||||
struct in_addr nullAddress; /* Used as a dummy parameter for */
|
struct in_addr nullAddress; /* Used as a dummy parameter for */
|
||||||
/* some function calls */
|
/* some function calls */
|
||||||
|
|
||||||
LIST_HEAD(, alias_link) linkTableOut[LINK_TABLE_OUT_SIZE];
|
LIST_HEAD (, alias_link) linkTableOut[LINK_TABLE_OUT_SIZE];
|
||||||
/* Lookup table of pointers to */
|
/* Lookup table of pointers to */
|
||||||
/* chains of link records. Each */
|
/* chains of link records. Each */
|
||||||
|
|
||||||
LIST_HEAD(, alias_link) linkTableIn[LINK_TABLE_IN_SIZE];
|
LIST_HEAD (, alias_link) linkTableIn[LINK_TABLE_IN_SIZE];
|
||||||
/* link record is doubly indexed */
|
/* link record is doubly indexed */
|
||||||
/* into input and output lookup */
|
/* into input and output lookup */
|
||||||
/* tables. */
|
/* tables. */
|
||||||
|
|
||||||
/* Link statistics */
|
/* Link statistics */
|
||||||
int icmpLinkCount;
|
int icmpLinkCount;
|
||||||
int udpLinkCount;
|
int udpLinkCount;
|
||||||
int tcpLinkCount;
|
int tcpLinkCount;
|
||||||
int pptpLinkCount;
|
int pptpLinkCount;
|
||||||
int protoLinkCount;
|
int protoLinkCount;
|
||||||
int fragmentIdLinkCount;
|
int fragmentIdLinkCount;
|
||||||
int fragmentPtrLinkCount;
|
int fragmentPtrLinkCount;
|
||||||
int sockCount;
|
int sockCount;
|
||||||
|
|
||||||
int cleanupIndex; /* Index to chain of link table */
|
int cleanupIndex; /* Index to chain of link table */
|
||||||
/* being inspected for old links */
|
/* being inspected for old links */
|
||||||
|
|
||||||
int timeStamp; /* System time in seconds for */
|
int timeStamp; /* System time in seconds for */
|
||||||
/* current packet */
|
/* current packet */
|
||||||
|
|
||||||
int lastCleanupTime; /* Last time IncrementalCleanup() */
|
int lastCleanupTime; /* Last time
|
||||||
/* was called */
|
* IncrementalCleanup() */
|
||||||
|
/* was called */
|
||||||
|
|
||||||
int houseKeepingResidual; /* used by HouseKeeping() */
|
int houseKeepingResidual; /* used by HouseKeeping() */
|
||||||
|
|
||||||
int deleteAllLinks; /* If equal to zero, DeleteLink() */
|
int deleteAllLinks; /* If equal to zero, DeleteLink() */
|
||||||
/* will not remove permanent links */
|
/* will not remove permanent links */
|
||||||
|
|
||||||
FILE *monitorFile; /* File descriptor for link */
|
FILE *monitorFile; /* File descriptor for link */
|
||||||
/* statistics monitoring file */
|
/* statistics monitoring file */
|
||||||
|
|
||||||
int newDefaultLink; /* Indicates if a new aliasing */
|
int newDefaultLink; /* Indicates if a new aliasing */
|
||||||
/* link has been created after a */
|
/* link has been created after a */
|
||||||
/* call to PacketAliasIn/Out(). */
|
/* call to PacketAliasIn/Out(). */
|
||||||
|
|
||||||
#ifndef NO_FW_PUNCH
|
#ifndef NO_FW_PUNCH
|
||||||
int fireWallFD; /* File descriptor to be able to */
|
int fireWallFD; /* File descriptor to be able to */
|
||||||
/* control firewall. Opened by */
|
/* control firewall. Opened by */
|
||||||
/* PacketAliasSetMode on first */
|
/* PacketAliasSetMode on first */
|
||||||
/* setting the PKT_ALIAS_PUNCH_FW */
|
/* setting the PKT_ALIAS_PUNCH_FW */
|
||||||
/* flag. */
|
/* flag. */
|
||||||
int fireWallBaseNum; /* The first firewall entry free for our use */
|
int fireWallBaseNum; /* The first firewall entry
|
||||||
int fireWallNumNums; /* How many entries can we use? */
|
* free for our use */
|
||||||
int fireWallActiveNum; /* Which entry did we last use? */
|
int fireWallNumNums; /* How many entries can we
|
||||||
char *fireWallField; /* bool array for entries */
|
* use? */
|
||||||
|
int fireWallActiveNum; /* Which entry did we last
|
||||||
|
* use? */
|
||||||
|
char *fireWallField; /* bool array for entries */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
unsigned int skinnyPort; /* TCP port used by the Skinny */
|
unsigned int skinnyPort; /* TCP port used by the Skinny */
|
||||||
/* protocol. */
|
/* protocol. */
|
||||||
|
|
||||||
struct proxy_entry *proxyList;
|
struct proxy_entry *proxyList;
|
||||||
|
|
||||||
struct in_addr true_addr; /* in network byte order. */
|
struct in_addr true_addr; /* in network byte order. */
|
||||||
u_short true_port; /* in host byte order. */
|
u_short true_port; /* in host byte order. */
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -161,148 +165,159 @@ struct libalias {
|
|||||||
/* Prototypes */
|
/* Prototypes */
|
||||||
|
|
||||||
/* General utilities */
|
/* General utilities */
|
||||||
u_short IpChecksum(struct ip *_pip);
|
u_short IpChecksum(struct ip *_pip);
|
||||||
u_short TcpChecksum(struct ip *_pip);
|
u_short TcpChecksum(struct ip *_pip);
|
||||||
void DifferentialChecksum(u_short *_cksum, u_short *_new, u_short *_old,
|
void
|
||||||
int _n);
|
DifferentialChecksum(u_short * _cksum, u_short * _new, u_short * _old,
|
||||||
|
int _n);
|
||||||
|
|
||||||
/* Internal data access */
|
/* Internal data access */
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
FindIcmpIn(struct libalias *la, struct in_addr _dst_addr, struct in_addr _alias_addr,
|
FindIcmpIn(struct libalias *la, struct in_addr _dst_addr, struct in_addr _alias_addr,
|
||||||
u_short _id_alias, int _create);
|
u_short _id_alias, int _create);
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
FindIcmpOut(struct libalias *la, struct in_addr _src_addr, struct in_addr _dst_addr,
|
FindIcmpOut(struct libalias *la, struct in_addr _src_addr, struct in_addr _dst_addr,
|
||||||
u_short _id, int _create);
|
u_short _id, int _create);
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
FindFragmentIn1(struct libalias *la, struct in_addr _dst_addr, struct in_addr _alias_addr,
|
FindFragmentIn1(struct libalias *la, struct in_addr _dst_addr, struct in_addr _alias_addr,
|
||||||
u_short _ip_id);
|
u_short _ip_id);
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
FindFragmentIn2(struct libalias *la, struct in_addr _dst_addr, struct in_addr _alias_addr,
|
FindFragmentIn2(struct libalias *la, struct in_addr _dst_addr, struct in_addr _alias_addr,
|
||||||
u_short _ip_id);
|
u_short _ip_id);
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
AddFragmentPtrLink(struct libalias *la, struct in_addr _dst_addr, u_short _ip_id);
|
AddFragmentPtrLink(struct libalias *la, struct in_addr _dst_addr, u_short _ip_id);
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
FindFragmentPtr(struct libalias *la, struct in_addr _dst_addr, u_short _ip_id);
|
FindFragmentPtr(struct libalias *la, struct in_addr _dst_addr, u_short _ip_id);
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
FindProtoIn(struct libalias *la, struct in_addr _dst_addr, struct in_addr _alias_addr,
|
FindProtoIn(struct libalias *la, struct in_addr _dst_addr, struct in_addr _alias_addr,
|
||||||
u_char _proto);
|
u_char _proto);
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
FindProtoOut(struct libalias *la, struct in_addr _src_addr, struct in_addr _dst_addr,
|
FindProtoOut(struct libalias *la, struct in_addr _src_addr, struct in_addr _dst_addr,
|
||||||
u_char _proto);
|
u_char _proto);
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
FindUdpTcpIn(struct libalias *la, struct in_addr _dst_addr, struct in_addr _alias_addr,
|
FindUdpTcpIn(struct libalias *la, struct in_addr _dst_addr, struct in_addr _alias_addr,
|
||||||
u_short _dst_port, u_short _alias_port, u_char _proto, int _create);
|
u_short _dst_port, u_short _alias_port, u_char _proto, int _create);
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
FindUdpTcpOut(struct libalias *la, struct in_addr _src_addr, struct in_addr _dst_addr,
|
FindUdpTcpOut(struct libalias *la, struct in_addr _src_addr, struct in_addr _dst_addr,
|
||||||
u_short _src_port, u_short _dst_port, u_char _proto, int _create);
|
u_short _src_port, u_short _dst_port, u_char _proto, int _create);
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
AddPptp(struct libalias *la, struct in_addr _src_addr, struct in_addr _dst_addr,
|
AddPptp(struct libalias *la, struct in_addr _src_addr, struct in_addr _dst_addr,
|
||||||
struct in_addr _alias_addr, u_int16_t _src_call_id);
|
struct in_addr _alias_addr, u_int16_t _src_call_id);
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
FindPptpOutByCallId(struct libalias *la, struct in_addr _src_addr,
|
FindPptpOutByCallId(struct libalias *la, struct in_addr _src_addr,
|
||||||
struct in_addr _dst_addr, u_int16_t _src_call_id);
|
struct in_addr _dst_addr, u_int16_t _src_call_id);
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
FindPptpInByCallId(struct libalias *la, struct in_addr _dst_addr,
|
FindPptpInByCallId(struct libalias *la, struct in_addr _dst_addr,
|
||||||
struct in_addr _alias_addr, u_int16_t _dst_call_id);
|
struct in_addr _alias_addr, u_int16_t _dst_call_id);
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
FindPptpOutByPeerCallId(struct libalias *la, struct in_addr _src_addr,
|
FindPptpOutByPeerCallId(struct libalias *la, struct in_addr _src_addr,
|
||||||
struct in_addr _dst_addr, u_int16_t _dst_call_id);
|
struct in_addr _dst_addr, u_int16_t _dst_call_id);
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
FindPptpInByPeerCallId(struct libalias *la, struct in_addr _dst_addr,
|
FindPptpInByPeerCallId(struct libalias *la, struct in_addr _dst_addr,
|
||||||
struct in_addr _alias_addr, u_int16_t _alias_call_id);
|
struct in_addr _alias_addr, u_int16_t _alias_call_id);
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
FindRtspOut(struct libalias *la, struct in_addr _src_addr, struct in_addr _dst_addr,
|
FindRtspOut(struct libalias *la, struct in_addr _src_addr, struct in_addr _dst_addr,
|
||||||
u_short _src_port, u_short _alias_port, u_char _proto);
|
u_short _src_port, u_short _alias_port, u_char _proto);
|
||||||
struct in_addr
|
struct in_addr
|
||||||
FindOriginalAddress(struct libalias *la, struct in_addr _alias_addr);
|
FindOriginalAddress(struct libalias *la, struct in_addr _alias_addr);
|
||||||
struct in_addr
|
struct in_addr
|
||||||
FindAliasAddress(struct libalias *la, struct in_addr _original_addr);
|
FindAliasAddress(struct libalias *la, struct in_addr _original_addr);
|
||||||
|
|
||||||
/* External data access/modification */
|
/* External data access/modification */
|
||||||
int FindNewPortGroup(struct libalias *la, struct in_addr _dst_addr, struct in_addr _alias_addr,
|
int
|
||||||
u_short _src_port, u_short _dst_port, u_short _port_count,
|
FindNewPortGroup(struct libalias *la, struct in_addr _dst_addr, struct in_addr _alias_addr,
|
||||||
u_char _proto, u_char _align);
|
u_short _src_port, u_short _dst_port, u_short _port_count,
|
||||||
void GetFragmentAddr(struct alias_link *_link, struct in_addr *_src_addr);
|
u_char _proto, u_char _align);
|
||||||
void SetFragmentAddr(struct alias_link *_link, struct in_addr _src_addr);
|
void GetFragmentAddr(struct alias_link *_link, struct in_addr *_src_addr);
|
||||||
void GetFragmentPtr(struct alias_link *_link, char **_fptr);
|
void SetFragmentAddr(struct alias_link *_link, struct in_addr _src_addr);
|
||||||
void SetFragmentPtr(struct alias_link *_link, char *fptr);
|
void GetFragmentPtr(struct alias_link *_link, char **_fptr);
|
||||||
void SetStateIn(struct alias_link *_link, int _state);
|
void SetFragmentPtr(struct alias_link *_link, char *fptr);
|
||||||
void SetStateOut(struct alias_link *_link, int _state);
|
void SetStateIn(struct alias_link *_link, int _state);
|
||||||
int GetStateIn(struct alias_link *_link);
|
void SetStateOut(struct alias_link *_link, int _state);
|
||||||
int GetStateOut(struct alias_link *_link);
|
int GetStateIn (struct alias_link *_link);
|
||||||
|
int GetStateOut(struct alias_link *_link);
|
||||||
struct in_addr
|
struct in_addr
|
||||||
GetOriginalAddress(struct alias_link *_link);
|
GetOriginalAddress(struct alias_link *_link);
|
||||||
struct in_addr
|
struct in_addr
|
||||||
GetDestAddress(struct alias_link *_link);
|
GetDestAddress(struct alias_link *_link);
|
||||||
struct in_addr
|
struct in_addr
|
||||||
GetAliasAddress(struct alias_link *_link);
|
GetAliasAddress(struct alias_link *_link);
|
||||||
struct in_addr
|
struct in_addr
|
||||||
GetDefaultAliasAddress(struct libalias *la);
|
GetDefaultAliasAddress(struct libalias *la);
|
||||||
void SetDefaultAliasAddress(struct libalias *la, struct in_addr _alias_addr);
|
void SetDefaultAliasAddress(struct libalias *la, struct in_addr _alias_addr);
|
||||||
u_short GetOriginalPort(struct alias_link *_link);
|
u_short GetOriginalPort(struct alias_link *_link);
|
||||||
u_short GetAliasPort(struct alias_link *_link);
|
u_short GetAliasPort(struct alias_link *_link);
|
||||||
struct in_addr
|
struct in_addr
|
||||||
GetProxyAddress(struct alias_link *_link);
|
GetProxyAddress(struct alias_link *_link);
|
||||||
void SetProxyAddress(struct alias_link *_link, struct in_addr _addr);
|
void SetProxyAddress(struct alias_link *_link, struct in_addr _addr);
|
||||||
u_short GetProxyPort(struct alias_link *_link);
|
u_short GetProxyPort(struct alias_link *_link);
|
||||||
void SetProxyPort(struct alias_link *_link, u_short _port);
|
void SetProxyPort(struct alias_link *_link, u_short _port);
|
||||||
void SetAckModified(struct alias_link *_link);
|
void SetAckModified(struct alias_link *_link);
|
||||||
int GetAckModified(struct alias_link *_link);
|
int GetAckModified(struct alias_link *_link);
|
||||||
int GetDeltaAckIn(struct ip *_pip, struct alias_link *_link);
|
int GetDeltaAckIn(struct ip *_pip, struct alias_link *_link);
|
||||||
int GetDeltaSeqOut(struct ip *_pip, struct alias_link *_link);
|
int GetDeltaSeqOut(struct ip *_pip, struct alias_link *_link);
|
||||||
void AddSeq(struct ip *_pip, struct alias_link *_link, int _delta);
|
void AddSeq (struct ip *_pip, struct alias_link *_link, int _delta);
|
||||||
void SetExpire(struct alias_link *_link, int _expire);
|
void SetExpire (struct alias_link *_link, int _expire);
|
||||||
void ClearCheckNewLink(struct libalias *la);
|
void ClearCheckNewLink(struct libalias *la);
|
||||||
void SetProtocolFlags(struct alias_link *_link, int _pflags);
|
void SetProtocolFlags(struct alias_link *_link, int _pflags);
|
||||||
int GetProtocolFlags(struct alias_link *_link);
|
int GetProtocolFlags(struct alias_link *_link);
|
||||||
void SetDestCallId(struct alias_link *_link, u_int16_t _cid);
|
void SetDestCallId(struct alias_link *_link, u_int16_t _cid);
|
||||||
|
|
||||||
#ifndef NO_FW_PUNCH
|
#ifndef NO_FW_PUNCH
|
||||||
void PunchFWHole(struct alias_link *_link);
|
void PunchFWHole(struct alias_link *_link);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Housekeeping function */
|
/* Housekeeping function */
|
||||||
void HouseKeeping(struct libalias *);
|
void HouseKeeping(struct libalias *);
|
||||||
|
|
||||||
/* Tcp specfic routines */
|
/* Tcp specfic routines */
|
||||||
/* lint -save -library Suppress flexelint warnings */
|
/* lint -save -library Suppress flexelint warnings */
|
||||||
|
|
||||||
/* FTP routines */
|
/* FTP routines */
|
||||||
void AliasHandleFtpOut(struct libalias *la, struct ip *_pip, struct alias_link *_link,
|
void
|
||||||
int _maxpacketsize);
|
AliasHandleFtpOut(struct libalias *la, struct ip *_pip, struct alias_link *_link,
|
||||||
|
int _maxpacketsize);
|
||||||
|
|
||||||
/* IRC routines */
|
/* IRC routines */
|
||||||
void AliasHandleIrcOut(struct libalias *la, struct ip *_pip, struct alias_link *_link,
|
void
|
||||||
int _maxsize);
|
AliasHandleIrcOut(struct libalias *la, struct ip *_pip, struct alias_link *_link,
|
||||||
|
int _maxsize);
|
||||||
|
|
||||||
/* RTSP routines */
|
/* RTSP routines */
|
||||||
void AliasHandleRtspOut(struct libalias *la, struct ip *_pip, struct alias_link *_link,
|
void
|
||||||
int _maxpacketsize);
|
AliasHandleRtspOut(struct libalias *la, struct ip *_pip, struct alias_link *_link,
|
||||||
|
int _maxpacketsize);
|
||||||
|
|
||||||
/* PPTP routines */
|
/* PPTP routines */
|
||||||
void AliasHandlePptpOut(struct libalias *la, struct ip *_pip, struct alias_link *_link);
|
void AliasHandlePptpOut(struct libalias *la, struct ip *_pip, struct alias_link *_link);
|
||||||
void AliasHandlePptpIn(struct libalias *la, struct ip *_pip, struct alias_link *_link);
|
void AliasHandlePptpIn(struct libalias *la, struct ip *_pip, struct alias_link *_link);
|
||||||
int AliasHandlePptpGreOut(struct libalias *la, struct ip *_pip);
|
int AliasHandlePptpGreOut(struct libalias *la, struct ip *_pip);
|
||||||
int AliasHandlePptpGreIn(struct libalias *la, struct ip *_pip);
|
int AliasHandlePptpGreIn(struct libalias *la, struct ip *_pip);
|
||||||
|
|
||||||
/* NetBIOS routines */
|
/* NetBIOS routines */
|
||||||
int AliasHandleUdpNbt(struct libalias *la, struct ip *_pip, struct alias_link *_link,
|
int
|
||||||
struct in_addr *_alias_address, u_short _alias_port);
|
AliasHandleUdpNbt(struct libalias *la, struct ip *_pip, struct alias_link *_link,
|
||||||
int AliasHandleUdpNbtNS(struct libalias *la, struct ip *_pip, struct alias_link *_link,
|
struct in_addr *_alias_address, u_short _alias_port);
|
||||||
struct in_addr *_alias_address, u_short *_alias_port,
|
int
|
||||||
struct in_addr *_original_address, u_short *_original_port);
|
AliasHandleUdpNbtNS(struct libalias *la, struct ip *_pip, struct alias_link *_link,
|
||||||
|
struct in_addr *_alias_address, u_short * _alias_port,
|
||||||
|
struct in_addr *_original_address, u_short * _original_port);
|
||||||
|
|
||||||
/* CUSeeMe routines */
|
/* CUSeeMe routines */
|
||||||
void AliasHandleCUSeeMeOut(struct libalias *la, struct ip *_pip, struct alias_link *_link);
|
void AliasHandleCUSeeMeOut(struct libalias *la, struct ip *_pip, struct alias_link *_link);
|
||||||
void AliasHandleCUSeeMeIn(struct libalias *la, struct ip *_pip, struct in_addr _original_addr);
|
void AliasHandleCUSeeMeIn(struct libalias *la, struct ip *_pip, struct in_addr _original_addr);
|
||||||
|
|
||||||
/* Skinny routines */
|
/* Skinny routines */
|
||||||
void AliasHandleSkinny(struct libalias *la, struct ip *_pip, struct alias_link *_link);
|
void AliasHandleSkinny(struct libalias *la, struct ip *_pip, struct alias_link *_link);
|
||||||
|
|
||||||
/* Transparent proxy routines */
|
/* Transparent proxy routines */
|
||||||
int ProxyCheck(struct libalias *la, struct ip *_pip, struct in_addr *_proxy_server_addr,
|
int
|
||||||
u_short *_proxy_server_port);
|
ProxyCheck(struct libalias *la, struct ip *_pip, struct in_addr *_proxy_server_addr,
|
||||||
void ProxyModify(struct libalias *la, struct alias_link *_link, struct ip *_pip,
|
u_short * _proxy_server_port);
|
||||||
int _maxpacketsize, int _proxy_type);
|
void
|
||||||
|
ProxyModify(struct libalias *la, struct alias_link *_link, struct ip *_pip,
|
||||||
|
int _maxpacketsize, int _proxy_type);
|
||||||
|
|
||||||
enum alias_tcp_state {
|
enum alias_tcp_state {
|
||||||
ALIAS_TCP_STATE_NOT_CONNECTED,
|
ALIAS_TCP_STATE_NOT_CONNECTED,
|
||||||
@ -312,4 +327,4 @@ enum alias_tcp_state {
|
|||||||
|
|
||||||
/*lint -restore */
|
/*lint -restore */
|
||||||
|
|
||||||
#endif /* !_ALIAS_LOCAL_H_ */
|
#endif /* !_ALIAS_LOCAL_H_ */
|
||||||
|
@ -55,22 +55,22 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include "alias_local.h"
|
#include "alias_local.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
struct in_addr oldaddr;
|
struct in_addr oldaddr;
|
||||||
u_short oldport;
|
u_short oldport;
|
||||||
struct in_addr newaddr;
|
struct in_addr newaddr;
|
||||||
u_short newport;
|
u_short newport;
|
||||||
u_short *uh_sum;
|
u_short *uh_sum;
|
||||||
} NBTArguments;
|
} NBTArguments;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned char type;
|
unsigned char type;
|
||||||
unsigned char flags;
|
unsigned char flags;
|
||||||
u_short id;
|
u_short id;
|
||||||
struct in_addr source_ip;
|
struct in_addr source_ip;
|
||||||
u_short source_port;
|
u_short source_port;
|
||||||
u_short len;
|
u_short len;
|
||||||
u_short offset;
|
u_short offset;
|
||||||
} NbtDataHeader;
|
} NbtDataHeader;
|
||||||
|
|
||||||
#define OpQuery 0
|
#define OpQuery 0
|
||||||
#define OpUnknown 4
|
#define OpUnknown 4
|
||||||
@ -79,13 +79,13 @@ typedef struct {
|
|||||||
#define OpWACK 7
|
#define OpWACK 7
|
||||||
#define OpRefresh 8
|
#define OpRefresh 8
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u_short nametrid;
|
u_short nametrid;
|
||||||
u_short dir:1, opcode:4, nmflags:7, rcode:4;
|
u_short dir: 1, opcode:4, nmflags:7, rcode:4;
|
||||||
u_short qdcount;
|
u_short qdcount;
|
||||||
u_short ancount;
|
u_short ancount;
|
||||||
u_short nscount;
|
u_short nscount;
|
||||||
u_short arcount;
|
u_short arcount;
|
||||||
} NbtNSHeader;
|
} NbtNSHeader;
|
||||||
|
|
||||||
#define FMT_ERR 0x1
|
#define FMT_ERR 0x1
|
||||||
#define SRV_ERR 0x2
|
#define SRV_ERR 0x2
|
||||||
@ -96,56 +96,61 @@ typedef struct {
|
|||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
static void PrintRcode( u_char rcode ) {
|
static void
|
||||||
|
PrintRcode(u_char rcode)
|
||||||
|
{
|
||||||
|
|
||||||
switch (rcode) {
|
switch (rcode) {
|
||||||
case FMT_ERR:
|
case FMT_ERR:
|
||||||
printf("\nFormat Error.");
|
printf("\nFormat Error.");
|
||||||
case SRV_ERR:
|
case SRV_ERR:
|
||||||
printf("\nSever failure.");
|
printf("\nSever failure.");
|
||||||
case IMP_ERR:
|
case IMP_ERR:
|
||||||
printf("\nUnsupported request error.\n");
|
printf("\nUnsupported request error.\n");
|
||||||
case RFS_ERR:
|
case RFS_ERR:
|
||||||
printf("\nRefused error.\n");
|
printf("\nRefused error.\n");
|
||||||
case ACT_ERR:
|
case ACT_ERR:
|
||||||
printf("\nActive error.\n");
|
printf("\nActive error.\n");
|
||||||
case CFT_ERR:
|
case CFT_ERR:
|
||||||
printf("\nName in conflict error.\n");
|
printf("\nName in conflict error.\n");
|
||||||
default:
|
default:
|
||||||
printf("\n?%c?=%0x\n", '?', rcode );
|
printf("\n?%c?=%0x\n", '?', rcode);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Handling Name field */
|
/* Handling Name field */
|
||||||
static u_char *AliasHandleName ( u_char *p, char *pmax ) {
|
static u_char *
|
||||||
|
AliasHandleName(u_char * p, char *pmax)
|
||||||
|
{
|
||||||
|
|
||||||
u_char *s;
|
u_char *s;
|
||||||
u_char c;
|
u_char c;
|
||||||
int compress;
|
int compress;
|
||||||
|
|
||||||
/* Following length field */
|
/* Following length field */
|
||||||
|
|
||||||
if (p == NULL || (char *)p >= pmax)
|
if (p == NULL || (char *)p >= pmax)
|
||||||
return(NULL);
|
return (NULL);
|
||||||
|
|
||||||
if (*p & 0xc0 ) {
|
if (*p & 0xc0) {
|
||||||
p = p + 2;
|
p = p + 2;
|
||||||
if ((char *)p > pmax)
|
if ((char *)p > pmax)
|
||||||
return(NULL);
|
return (NULL);
|
||||||
return ((u_char *)p);
|
return ((u_char *) p);
|
||||||
}
|
}
|
||||||
while ( ( *p & 0x3f) != 0x00 ) {
|
while ((*p & 0x3f) != 0x00) {
|
||||||
s = p + 1;
|
s = p + 1;
|
||||||
if ( *p == 0x20 )
|
if (*p == 0x20)
|
||||||
compress = 1;
|
compress = 1;
|
||||||
else
|
else
|
||||||
compress = 0;
|
compress = 0;
|
||||||
|
|
||||||
/* Get next length field */
|
/* Get next length field */
|
||||||
p = (u_char *)(p + (*p & 0x3f) + 1);
|
p = (u_char *) (p + (*p & 0x3f) + 1);
|
||||||
if ((char *)p > pmax) {
|
if ((char *)p > pmax) {
|
||||||
p = NULL;
|
p = NULL;
|
||||||
break;
|
break;
|
||||||
@ -154,15 +159,15 @@ static u_char *AliasHandleName ( u_char *p, char *pmax ) {
|
|||||||
printf(":");
|
printf(":");
|
||||||
#endif
|
#endif
|
||||||
while (s < p) {
|
while (s < p) {
|
||||||
if ( compress == 1 ) {
|
if (compress == 1) {
|
||||||
c = (u_char )(((((*s & 0x0f) << 4) | (*(s+1) & 0x0f)) - 0x11));
|
c = (u_char) (((((*s & 0x0f) << 4) | (*(s + 1) & 0x0f)) - 0x11));
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (isprint( c ) )
|
if (isprint(c))
|
||||||
printf("%c", c );
|
printf("%c", c);
|
||||||
else
|
else
|
||||||
printf("<0x%02x>", c );
|
printf("<0x%02x>", c);
|
||||||
#endif
|
#endif
|
||||||
s +=2;
|
s += 2;
|
||||||
} else {
|
} else {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("%c", *s);
|
printf("%c", *s);
|
||||||
@ -174,14 +179,14 @@ static u_char *AliasHandleName ( u_char *p, char *pmax ) {
|
|||||||
printf(":");
|
printf(":");
|
||||||
#endif
|
#endif
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set up to out of Name field */
|
/* Set up to out of Name field */
|
||||||
if (p == NULL || (char *)p >= pmax)
|
if (p == NULL || (char *)p >= pmax)
|
||||||
p = NULL;
|
p = NULL;
|
||||||
else
|
else
|
||||||
p++;
|
p++;
|
||||||
return ((u_char *)p);
|
return ((u_char *) p);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -195,58 +200,61 @@ static u_char *AliasHandleName ( u_char *p, char *pmax ) {
|
|||||||
#define DGM_POSITIVE_RES 0x15
|
#define DGM_POSITIVE_RES 0x15
|
||||||
#define DGM_NEGATIVE_RES 0x16
|
#define DGM_NEGATIVE_RES 0x16
|
||||||
|
|
||||||
int AliasHandleUdpNbt(
|
int
|
||||||
struct libalias *la,
|
AliasHandleUdpNbt(
|
||||||
struct ip *pip, /* IP packet to examine/patch */
|
struct libalias *la,
|
||||||
struct alias_link *link,
|
struct ip *pip, /* IP packet to examine/patch */
|
||||||
struct in_addr *alias_address,
|
struct alias_link *link,
|
||||||
u_short alias_port
|
struct in_addr *alias_address,
|
||||||
) {
|
u_short alias_port
|
||||||
struct udphdr * uh;
|
)
|
||||||
NbtDataHeader *ndh;
|
{
|
||||||
u_char *p = NULL;
|
struct udphdr *uh;
|
||||||
char *pmax;
|
NbtDataHeader *ndh;
|
||||||
|
u_char *p = NULL;
|
||||||
|
char *pmax;
|
||||||
|
|
||||||
/* Calculate data length of UDP packet */
|
/* Calculate data length of UDP packet */
|
||||||
uh = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2));
|
uh = (struct udphdr *)((char *)pip + (pip->ip_hl << 2));
|
||||||
pmax = (char *)uh + ntohs( uh->uh_ulen );
|
pmax = (char *)uh + ntohs(uh->uh_ulen);
|
||||||
|
|
||||||
ndh = (NbtDataHeader *)((char *)uh + (sizeof (struct udphdr)));
|
ndh = (NbtDataHeader *) ((char *)uh + (sizeof(struct udphdr)));
|
||||||
if ((char *)(ndh + 1) > pmax)
|
if ((char *)(ndh + 1) > pmax)
|
||||||
return(-1);
|
return (-1);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("\nType=%02x,", ndh->type );
|
printf("\nType=%02x,", ndh->type);
|
||||||
#endif
|
#endif
|
||||||
switch ( ndh->type ) {
|
switch (ndh->type) {
|
||||||
case DGM_DIRECT_UNIQ:
|
case DGM_DIRECT_UNIQ:
|
||||||
case DGM_DIRECT_GROUP:
|
case DGM_DIRECT_GROUP:
|
||||||
case DGM_BROADCAST:
|
case DGM_BROADCAST:
|
||||||
p = (u_char *)ndh + 14;
|
p = (u_char *) ndh + 14;
|
||||||
p = AliasHandleName ( p, pmax ); /* Source Name */
|
p = AliasHandleName(p, pmax); /* Source Name */
|
||||||
p = AliasHandleName ( p, pmax ); /* Destination Name */
|
p = AliasHandleName(p, pmax); /* Destination Name */
|
||||||
break;
|
break;
|
||||||
case DGM_ERROR:
|
case DGM_ERROR:
|
||||||
p = (u_char *)ndh + 11;
|
p = (u_char *) ndh + 11;
|
||||||
break;
|
break;
|
||||||
case DGM_QUERY:
|
case DGM_QUERY:
|
||||||
case DGM_POSITIVE_RES:
|
case DGM_POSITIVE_RES:
|
||||||
case DGM_NEGATIVE_RES:
|
case DGM_NEGATIVE_RES:
|
||||||
p = (u_char *)ndh + 10;
|
p = (u_char *) ndh + 10;
|
||||||
p = AliasHandleName ( p, pmax ); /* Destination Name */
|
p = AliasHandleName(p, pmax); /* Destination Name */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (p == NULL || (char *)p > pmax)
|
if (p == NULL || (char *)p > pmax)
|
||||||
p = NULL;
|
p = NULL;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("%s:%d-->", inet_ntoa(ndh->source_ip), ntohs(ndh->source_port) );
|
printf("%s:%d-->", inet_ntoa(ndh->source_ip), ntohs(ndh->source_port));
|
||||||
#endif
|
#endif
|
||||||
/* Doing an IP address and Port number Translation */
|
/* Doing an IP address and Port number Translation */
|
||||||
if ( uh->uh_sum != 0 ) {
|
if (uh->uh_sum != 0) {
|
||||||
int acc;
|
int acc;
|
||||||
u_short *sptr;
|
u_short *sptr;
|
||||||
acc = ndh->source_port;
|
|
||||||
|
acc = ndh->source_port;
|
||||||
acc -= alias_port;
|
acc -= alias_port;
|
||||||
sptr = (u_short *) &(ndh->source_ip);
|
sptr = (u_short *) & (ndh->source_ip);
|
||||||
acc += *sptr++;
|
acc += *sptr++;
|
||||||
acc += *sptr;
|
acc += *sptr;
|
||||||
sptr = (u_short *) alias_address;
|
sptr = (u_short *) alias_address;
|
||||||
@ -254,49 +262,49 @@ int AliasHandleUdpNbt(
|
|||||||
acc -= *sptr;
|
acc -= *sptr;
|
||||||
ADJUST_CHECKSUM(acc, uh->uh_sum);
|
ADJUST_CHECKSUM(acc, uh->uh_sum);
|
||||||
}
|
}
|
||||||
ndh->source_ip = *alias_address;
|
ndh->source_ip = *alias_address;
|
||||||
ndh->source_port = alias_port;
|
ndh->source_port = alias_port;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("%s:%d\n", inet_ntoa(ndh->source_ip), ntohs(ndh->source_port) );
|
printf("%s:%d\n", inet_ntoa(ndh->source_ip), ntohs(ndh->source_port));
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
#endif
|
#endif
|
||||||
return((p == NULL) ? -1 : 0);
|
return ((p == NULL) ? -1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Question Section */
|
/* Question Section */
|
||||||
#define QS_TYPE_NB 0x0020
|
#define QS_TYPE_NB 0x0020
|
||||||
#define QS_TYPE_NBSTAT 0x0021
|
#define QS_TYPE_NBSTAT 0x0021
|
||||||
#define QS_CLAS_IN 0x0001
|
#define QS_CLAS_IN 0x0001
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u_short type; /* The type of Request */
|
u_short type; /* The type of Request */
|
||||||
u_short class; /* The class of Request */
|
u_short class; /* The class of Request */
|
||||||
} NBTNsQuestion;
|
} NBTNsQuestion;
|
||||||
|
|
||||||
static u_char *
|
static u_char *
|
||||||
AliasHandleQuestion(
|
AliasHandleQuestion(
|
||||||
u_short count,
|
u_short count,
|
||||||
NBTNsQuestion *q,
|
NBTNsQuestion * q,
|
||||||
char *pmax,
|
char *pmax,
|
||||||
NBTArguments *nbtarg)
|
NBTArguments * nbtarg)
|
||||||
{
|
{
|
||||||
|
|
||||||
while ( count != 0 ) {
|
while (count != 0) {
|
||||||
/* Name Filed */
|
/* Name Filed */
|
||||||
q = (NBTNsQuestion *)AliasHandleName((u_char *)q, pmax);
|
q = (NBTNsQuestion *) AliasHandleName((u_char *) q, pmax);
|
||||||
|
|
||||||
if (q == NULL || (char *)(q + 1) > pmax) {
|
if (q == NULL || (char *)(q + 1) > pmax) {
|
||||||
q = NULL;
|
q = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Type and Class filed */
|
/* Type and Class filed */
|
||||||
switch ( ntohs(q->type) ) {
|
switch (ntohs(q->type)) {
|
||||||
case QS_TYPE_NB:
|
case QS_TYPE_NB:
|
||||||
case QS_TYPE_NBSTAT:
|
case QS_TYPE_NBSTAT:
|
||||||
q= q+1;
|
q = q + 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("\nUnknown Type on Question %0x\n", ntohs(q->type) );
|
printf("\nUnknown Type on Question %0x\n", ntohs(q->type));
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -304,7 +312,7 @@ AliasHandleQuestion(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Set up to out of Question Section */
|
/* Set up to out of Question Section */
|
||||||
return ((u_char *)q);
|
return ((u_char *) q);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Resource Record */
|
/* Resource Record */
|
||||||
@ -316,101 +324,99 @@ AliasHandleQuestion(
|
|||||||
#define RR_CLAS_IN 0x0001
|
#define RR_CLAS_IN 0x0001
|
||||||
#define SizeOfNsResource 8
|
#define SizeOfNsResource 8
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u_short type;
|
u_short type;
|
||||||
u_short class;
|
u_short class;
|
||||||
unsigned int ttl;
|
unsigned int ttl;
|
||||||
u_short rdlen;
|
u_short rdlen;
|
||||||
} NBTNsResource;
|
} NBTNsResource;
|
||||||
|
|
||||||
#define SizeOfNsRNB 6
|
#define SizeOfNsRNB 6
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u_short g:1, ont:2, resv:13;
|
u_short g: 1 , ont:2, resv:13;
|
||||||
struct in_addr addr;
|
struct in_addr addr;
|
||||||
} NBTNsRNB;
|
} NBTNsRNB;
|
||||||
|
|
||||||
static u_char *
|
static u_char *
|
||||||
AliasHandleResourceNB(
|
AliasHandleResourceNB(
|
||||||
NBTNsResource *q,
|
NBTNsResource * q,
|
||||||
char *pmax,
|
char *pmax,
|
||||||
NBTArguments *nbtarg)
|
NBTArguments * nbtarg)
|
||||||
{
|
{
|
||||||
NBTNsRNB *nb;
|
NBTNsRNB *nb;
|
||||||
u_short bcount;
|
u_short bcount;
|
||||||
|
|
||||||
if (q == NULL || (char *)(q + 1) > pmax)
|
if (q == NULL || (char *)(q + 1) > pmax)
|
||||||
return(NULL);
|
return (NULL);
|
||||||
/* Check out a length */
|
/* Check out a length */
|
||||||
bcount = ntohs(q->rdlen);
|
bcount = ntohs(q->rdlen);
|
||||||
|
|
||||||
/* Forward to Resource NB position */
|
/* Forward to Resource NB position */
|
||||||
nb = (NBTNsRNB *)((u_char *)q + SizeOfNsResource);
|
nb = (NBTNsRNB *) ((u_char *) q + SizeOfNsResource);
|
||||||
|
|
||||||
/* Processing all in_addr array */
|
/* Processing all in_addr array */
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("NB rec[%s", inet_ntoa(nbtarg->oldaddr));
|
printf("NB rec[%s", inet_ntoa(nbtarg->oldaddr));
|
||||||
printf("->%s, %dbytes] ",inet_ntoa(nbtarg->newaddr ), bcount);
|
printf("->%s, %dbytes] ", inet_ntoa(nbtarg->newaddr), bcount);
|
||||||
#endif
|
#endif
|
||||||
while ( nb != NULL && bcount != 0 ) {
|
while (nb != NULL && bcount != 0) {
|
||||||
if ((char *)(nb + 1) > pmax) {
|
if ((char *)(nb + 1) > pmax) {
|
||||||
nb = NULL;
|
nb = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("<%s>", inet_ntoa(nb->addr) );
|
printf("<%s>", inet_ntoa(nb->addr));
|
||||||
#endif
|
#endif
|
||||||
if (!bcmp(&nbtarg->oldaddr,&nb->addr, sizeof(struct in_addr) ) ) {
|
if (!bcmp(&nbtarg->oldaddr, &nb->addr, sizeof(struct in_addr))) {
|
||||||
if ( *nbtarg->uh_sum != 0 ) {
|
if (*nbtarg->uh_sum != 0) {
|
||||||
int acc;
|
int acc;
|
||||||
u_short *sptr;
|
u_short *sptr;
|
||||||
|
|
||||||
sptr = (u_short *) &(nb->addr);
|
sptr = (u_short *) & (nb->addr);
|
||||||
acc = *sptr++;
|
acc = *sptr++;
|
||||||
acc += *sptr;
|
acc += *sptr;
|
||||||
sptr = (u_short *) &(nbtarg->newaddr);
|
sptr = (u_short *) & (nbtarg->newaddr);
|
||||||
acc -= *sptr++;
|
acc -= *sptr++;
|
||||||
acc -= *sptr;
|
acc -= *sptr;
|
||||||
ADJUST_CHECKSUM(acc, *nbtarg->uh_sum);
|
ADJUST_CHECKSUM(acc, *nbtarg->uh_sum);
|
||||||
}
|
}
|
||||||
|
|
||||||
nb->addr = nbtarg->newaddr;
|
nb->addr = nbtarg->newaddr;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("O");
|
printf("O");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
else {
|
else {
|
||||||
printf(".");
|
printf(".");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
nb=(NBTNsRNB *)((u_char *)nb + SizeOfNsRNB);
|
nb = (NBTNsRNB *) ((u_char *) nb + SizeOfNsRNB);
|
||||||
bcount -= SizeOfNsRNB;
|
bcount -= SizeOfNsRNB;
|
||||||
}
|
}
|
||||||
if (nb == NULL || (char *)(nb + 1) > pmax) {
|
if (nb == NULL || (char *)(nb + 1) > pmax) {
|
||||||
nb = NULL;
|
nb = NULL;
|
||||||
}
|
}
|
||||||
|
return ((u_char *) nb);
|
||||||
return ((u_char *)nb);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SizeOfResourceA 6
|
#define SizeOfResourceA 6
|
||||||
typedef struct {
|
typedef struct {
|
||||||
struct in_addr addr;
|
struct in_addr addr;
|
||||||
} NBTNsResourceA;
|
} NBTNsResourceA;
|
||||||
|
|
||||||
static u_char *
|
static u_char *
|
||||||
AliasHandleResourceA(
|
AliasHandleResourceA(
|
||||||
NBTNsResource *q,
|
NBTNsResource * q,
|
||||||
char *pmax,
|
char *pmax,
|
||||||
NBTArguments *nbtarg)
|
NBTArguments * nbtarg)
|
||||||
{
|
{
|
||||||
NBTNsResourceA *a;
|
NBTNsResourceA *a;
|
||||||
u_short bcount;
|
u_short bcount;
|
||||||
|
|
||||||
if (q == NULL || (char *)(q + 1) > pmax)
|
if (q == NULL || (char *)(q + 1) > pmax)
|
||||||
return(NULL);
|
return (NULL);
|
||||||
|
|
||||||
/* Forward to Resource A position */
|
/* Forward to Resource A position */
|
||||||
a = (NBTNsResourceA *)( (u_char *)q + sizeof(NBTNsResource) );
|
a = (NBTNsResourceA *) ((u_char *) q + sizeof(NBTNsResource));
|
||||||
|
|
||||||
/* Check out of length */
|
/* Check out of length */
|
||||||
bcount = ntohs(q->rdlen);
|
bcount = ntohs(q->rdlen);
|
||||||
@ -418,62 +424,61 @@ AliasHandleResourceA(
|
|||||||
/* Processing all in_addr array */
|
/* Processing all in_addr array */
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("Arec [%s", inet_ntoa(nbtarg->oldaddr));
|
printf("Arec [%s", inet_ntoa(nbtarg->oldaddr));
|
||||||
printf("->%s]",inet_ntoa(nbtarg->newaddr ));
|
printf("->%s]", inet_ntoa(nbtarg->newaddr));
|
||||||
#endif
|
#endif
|
||||||
while ( bcount != 0 ) {
|
while (bcount != 0) {
|
||||||
if (a == NULL || (char *)(a + 1) > pmax)
|
if (a == NULL || (char *)(a + 1) > pmax)
|
||||||
return(NULL);
|
return (NULL);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("..%s", inet_ntoa(a->addr) );
|
printf("..%s", inet_ntoa(a->addr));
|
||||||
#endif
|
#endif
|
||||||
if ( !bcmp(&nbtarg->oldaddr, &a->addr, sizeof(struct in_addr) ) ) {
|
if (!bcmp(&nbtarg->oldaddr, &a->addr, sizeof(struct in_addr))) {
|
||||||
if ( *nbtarg->uh_sum != 0 ) {
|
if (*nbtarg->uh_sum != 0) {
|
||||||
int acc;
|
int acc;
|
||||||
u_short *sptr;
|
u_short *sptr;
|
||||||
|
|
||||||
sptr = (u_short *) &(a->addr); /* Old */
|
sptr = (u_short *) & (a->addr); /* Old */
|
||||||
acc = *sptr++;
|
acc = *sptr++;
|
||||||
acc += *sptr;
|
acc += *sptr;
|
||||||
sptr = (u_short *) &nbtarg->newaddr; /* New */
|
sptr = (u_short *) & nbtarg->newaddr; /* New */
|
||||||
acc -= *sptr++;
|
acc -= *sptr++;
|
||||||
acc -= *sptr;
|
acc -= *sptr;
|
||||||
ADJUST_CHECKSUM(acc, *nbtarg->uh_sum);
|
ADJUST_CHECKSUM(acc, *nbtarg->uh_sum);
|
||||||
}
|
}
|
||||||
|
|
||||||
a->addr = nbtarg->newaddr;
|
a->addr = nbtarg->newaddr;
|
||||||
}
|
}
|
||||||
a++; /*XXXX*/
|
a++; /* XXXX */
|
||||||
bcount -= SizeOfResourceA;
|
bcount -= SizeOfResourceA;
|
||||||
}
|
}
|
||||||
if (a == NULL || (char *)(a + 1) > pmax)
|
if (a == NULL || (char *)(a + 1) > pmax)
|
||||||
a = NULL;
|
a = NULL;
|
||||||
return ((u_char *)a);
|
return ((u_char *) a);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u_short opcode:4, flags:8, resv:4;
|
u_short opcode:4, flags:8, resv:4;
|
||||||
} NBTNsResourceNULL;
|
} NBTNsResourceNULL;
|
||||||
|
|
||||||
static u_char *
|
static u_char *
|
||||||
AliasHandleResourceNULL(
|
AliasHandleResourceNULL(
|
||||||
NBTNsResource *q,
|
NBTNsResource * q,
|
||||||
char *pmax,
|
char *pmax,
|
||||||
NBTArguments *nbtarg)
|
NBTArguments * nbtarg)
|
||||||
{
|
{
|
||||||
NBTNsResourceNULL *n;
|
NBTNsResourceNULL *n;
|
||||||
u_short bcount;
|
u_short bcount;
|
||||||
|
|
||||||
if (q == NULL || (char *)(q + 1) > pmax)
|
if (q == NULL || (char *)(q + 1) > pmax)
|
||||||
return(NULL);
|
return (NULL);
|
||||||
|
|
||||||
/* Forward to Resource NULL position */
|
/* Forward to Resource NULL position */
|
||||||
n = (NBTNsResourceNULL *)( (u_char *)q + sizeof(NBTNsResource) );
|
n = (NBTNsResourceNULL *) ((u_char *) q + sizeof(NBTNsResource));
|
||||||
|
|
||||||
/* Check out of length */
|
/* Check out of length */
|
||||||
bcount = ntohs(q->rdlen);
|
bcount = ntohs(q->rdlen);
|
||||||
|
|
||||||
/* Processing all in_addr array */
|
/* Processing all in_addr array */
|
||||||
while ( bcount != 0 ) {
|
while (bcount != 0) {
|
||||||
if ((char *)(n + 1) > pmax) {
|
if ((char *)(n + 1) > pmax) {
|
||||||
n = NULL;
|
n = NULL;
|
||||||
break;
|
break;
|
||||||
@ -484,223 +489,220 @@ AliasHandleResourceNULL(
|
|||||||
if ((char *)(n + 1) > pmax)
|
if ((char *)(n + 1) > pmax)
|
||||||
n = NULL;
|
n = NULL;
|
||||||
|
|
||||||
return ((u_char *)n);
|
return ((u_char *) n);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u_char *
|
static u_char *
|
||||||
AliasHandleResourceNS(
|
AliasHandleResourceNS(
|
||||||
NBTNsResource *q,
|
NBTNsResource * q,
|
||||||
char *pmax,
|
char *pmax,
|
||||||
NBTArguments *nbtarg)
|
NBTArguments * nbtarg)
|
||||||
{
|
{
|
||||||
NBTNsResourceNULL *n;
|
NBTNsResourceNULL *n;
|
||||||
u_short bcount;
|
u_short bcount;
|
||||||
|
|
||||||
if (q == NULL || (char *)(q + 1) > pmax)
|
if (q == NULL || (char *)(q + 1) > pmax)
|
||||||
return(NULL);
|
return (NULL);
|
||||||
|
|
||||||
/* Forward to Resource NULL position */
|
/* Forward to Resource NULL position */
|
||||||
n = (NBTNsResourceNULL *)( (u_char *)q + sizeof(NBTNsResource) );
|
n = (NBTNsResourceNULL *) ((u_char *) q + sizeof(NBTNsResource));
|
||||||
|
|
||||||
/* Check out of length */
|
/* Check out of length */
|
||||||
bcount = ntohs(q->rdlen);
|
bcount = ntohs(q->rdlen);
|
||||||
|
|
||||||
/* Resource Record Name Filed */
|
/* Resource Record Name Filed */
|
||||||
q = (NBTNsResource *)AliasHandleName( (u_char *)n, pmax ); /* XXX */
|
q = (NBTNsResource *) AliasHandleName((u_char *) n, pmax); /* XXX */
|
||||||
|
|
||||||
if (q == NULL || (char *)((u_char *)n + bcount) > pmax)
|
if (q == NULL || (char *)((u_char *) n + bcount) > pmax)
|
||||||
return(NULL);
|
return (NULL);
|
||||||
else
|
else
|
||||||
return ((u_char *)n + bcount);
|
return ((u_char *) n + bcount);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u_short numnames;
|
u_short numnames;
|
||||||
} NBTNsResourceNBSTAT;
|
} NBTNsResourceNBSTAT;
|
||||||
|
|
||||||
static u_char *
|
static u_char *
|
||||||
AliasHandleResourceNBSTAT(
|
AliasHandleResourceNBSTAT(
|
||||||
NBTNsResource *q,
|
NBTNsResource * q,
|
||||||
char *pmax,
|
char *pmax,
|
||||||
NBTArguments *nbtarg)
|
NBTArguments * nbtarg)
|
||||||
{
|
{
|
||||||
NBTNsResourceNBSTAT *n;
|
NBTNsResourceNBSTAT *n;
|
||||||
u_short bcount;
|
u_short bcount;
|
||||||
|
|
||||||
if (q == NULL || (char *)(q + 1) > pmax)
|
if (q == NULL || (char *)(q + 1) > pmax)
|
||||||
return(NULL);
|
return (NULL);
|
||||||
|
|
||||||
/* Forward to Resource NBSTAT position */
|
/* Forward to Resource NBSTAT position */
|
||||||
n = (NBTNsResourceNBSTAT *)( (u_char *)q + sizeof(NBTNsResource) );
|
n = (NBTNsResourceNBSTAT *) ((u_char *) q + sizeof(NBTNsResource));
|
||||||
|
|
||||||
/* Check out of length */
|
/* Check out of length */
|
||||||
bcount = ntohs(q->rdlen);
|
bcount = ntohs(q->rdlen);
|
||||||
|
|
||||||
if (q == NULL || (char *)((u_char *)n + bcount) > pmax)
|
if (q == NULL || (char *)((u_char *) n + bcount) > pmax)
|
||||||
return(NULL);
|
return (NULL);
|
||||||
else
|
else
|
||||||
return ((u_char *)n + bcount);
|
return ((u_char *) n + bcount);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u_char *
|
static u_char *
|
||||||
AliasHandleResource(
|
AliasHandleResource(
|
||||||
u_short count,
|
u_short count,
|
||||||
NBTNsResource *q,
|
NBTNsResource * q,
|
||||||
char *pmax,
|
char *pmax,
|
||||||
NBTArguments
|
NBTArguments
|
||||||
*nbtarg)
|
* nbtarg)
|
||||||
{
|
{
|
||||||
while ( count != 0 ) {
|
while (count != 0) {
|
||||||
/* Resource Record Name Filed */
|
/* Resource Record Name Filed */
|
||||||
q = (NBTNsResource *)AliasHandleName( (u_char *)q, pmax );
|
q = (NBTNsResource *) AliasHandleName((u_char *) q, pmax);
|
||||||
|
|
||||||
if (q == NULL || (char *)(q + 1) > pmax)
|
if (q == NULL || (char *)(q + 1) > pmax)
|
||||||
break;
|
break;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("type=%02x, count=%d\n", ntohs(q->type), count );
|
printf("type=%02x, count=%d\n", ntohs(q->type), count);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Type and Class filed */
|
/* Type and Class filed */
|
||||||
switch ( ntohs(q->type) ) {
|
switch (ntohs(q->type)) {
|
||||||
case RR_TYPE_NB:
|
case RR_TYPE_NB:
|
||||||
q = (NBTNsResource *)AliasHandleResourceNB(
|
q = (NBTNsResource *) AliasHandleResourceNB(
|
||||||
q,
|
q,
|
||||||
pmax,
|
pmax,
|
||||||
nbtarg
|
nbtarg
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case RR_TYPE_A:
|
case RR_TYPE_A:
|
||||||
q = (NBTNsResource *)AliasHandleResourceA(
|
q = (NBTNsResource *) AliasHandleResourceA(
|
||||||
q,
|
q,
|
||||||
pmax,
|
pmax,
|
||||||
nbtarg
|
nbtarg
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case RR_TYPE_NS:
|
case RR_TYPE_NS:
|
||||||
q = (NBTNsResource *)AliasHandleResourceNS(
|
q = (NBTNsResource *) AliasHandleResourceNS(
|
||||||
q,
|
q,
|
||||||
pmax,
|
pmax,
|
||||||
nbtarg
|
nbtarg
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case RR_TYPE_NULL:
|
case RR_TYPE_NULL:
|
||||||
q = (NBTNsResource *)AliasHandleResourceNULL(
|
q = (NBTNsResource *) AliasHandleResourceNULL(
|
||||||
q,
|
q,
|
||||||
pmax,
|
pmax,
|
||||||
nbtarg
|
nbtarg
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case RR_TYPE_NBSTAT:
|
case RR_TYPE_NBSTAT:
|
||||||
q = (NBTNsResource *)AliasHandleResourceNBSTAT(
|
q = (NBTNsResource *) AliasHandleResourceNBSTAT(
|
||||||
q,
|
q,
|
||||||
pmax,
|
pmax,
|
||||||
nbtarg
|
nbtarg
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf(
|
printf(
|
||||||
"\nUnknown Type of Resource %0x\n",
|
"\nUnknown Type of Resource %0x\n",
|
||||||
ntohs(q->type)
|
ntohs(q->type)
|
||||||
);
|
);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
count--;
|
count--;
|
||||||
}
|
}
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
return ((u_char *)q);
|
return ((u_char *) q);
|
||||||
}
|
}
|
||||||
|
|
||||||
int AliasHandleUdpNbtNS(
|
int
|
||||||
struct libalias *la,
|
AliasHandleUdpNbtNS(
|
||||||
struct ip *pip, /* IP packet to examine/patch */
|
struct libalias *la,
|
||||||
struct alias_link *link,
|
struct ip *pip, /* IP packet to examine/patch */
|
||||||
struct in_addr *alias_address,
|
struct alias_link *link,
|
||||||
u_short *alias_port,
|
struct in_addr *alias_address,
|
||||||
struct in_addr *original_address,
|
u_short * alias_port,
|
||||||
u_short *original_port )
|
struct in_addr *original_address,
|
||||||
|
u_short * original_port)
|
||||||
{
|
{
|
||||||
struct udphdr * uh;
|
struct udphdr *uh;
|
||||||
NbtNSHeader * nsh;
|
NbtNSHeader *nsh;
|
||||||
u_char * p;
|
u_char *p;
|
||||||
char *pmax;
|
char *pmax;
|
||||||
NBTArguments nbtarg;
|
NBTArguments nbtarg;
|
||||||
|
|
||||||
/* Set up Common Parameter */
|
/* Set up Common Parameter */
|
||||||
nbtarg.oldaddr = *alias_address;
|
nbtarg.oldaddr = *alias_address;
|
||||||
nbtarg.oldport = *alias_port;
|
nbtarg.oldport = *alias_port;
|
||||||
nbtarg.newaddr = *original_address;
|
nbtarg.newaddr = *original_address;
|
||||||
nbtarg.newport = *original_port;
|
nbtarg.newport = *original_port;
|
||||||
|
|
||||||
/* Calculate data length of UDP packet */
|
/* Calculate data length of UDP packet */
|
||||||
uh = (struct udphdr *) ((char *) pip + (pip->ip_hl << 2));
|
uh = (struct udphdr *)((char *)pip + (pip->ip_hl << 2));
|
||||||
nbtarg.uh_sum = &(uh->uh_sum);
|
nbtarg.uh_sum = &(uh->uh_sum);
|
||||||
nsh = (NbtNSHeader *)((char *)uh + (sizeof(struct udphdr)));
|
nsh = (NbtNSHeader *) ((char *)uh + (sizeof(struct udphdr)));
|
||||||
p = (u_char *)(nsh + 1);
|
p = (u_char *) (nsh + 1);
|
||||||
pmax = (char *)uh + ntohs( uh->uh_ulen );
|
pmax = (char *)uh + ntohs(uh->uh_ulen);
|
||||||
|
|
||||||
if ((char *)(nsh + 1) > pmax)
|
if ((char *)(nsh + 1) > pmax)
|
||||||
return(-1);
|
return (-1);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf(" [%s] ID=%02x, op=%01x, flag=%02x, rcode=%01x, qd=%04x"
|
printf(" [%s] ID=%02x, op=%01x, flag=%02x, rcode=%01x, qd=%04x"
|
||||||
", an=%04x, ns=%04x, ar=%04x, [%d]-->",
|
", an=%04x, ns=%04x, ar=%04x, [%d]-->",
|
||||||
nsh->dir ? "Response": "Request",
|
nsh->dir ? "Response" : "Request",
|
||||||
nsh->nametrid,
|
nsh->nametrid,
|
||||||
nsh->opcode,
|
nsh->opcode,
|
||||||
nsh->nmflags,
|
nsh->nmflags,
|
||||||
nsh->rcode,
|
nsh->rcode,
|
||||||
ntohs(nsh->qdcount),
|
ntohs(nsh->qdcount),
|
||||||
ntohs(nsh->ancount),
|
ntohs(nsh->ancount),
|
||||||
ntohs(nsh->nscount),
|
ntohs(nsh->nscount),
|
||||||
ntohs(nsh->arcount),
|
ntohs(nsh->arcount),
|
||||||
(u_char *)p -(u_char *)nsh
|
(u_char *) p - (u_char *) nsh
|
||||||
);
|
);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Question Entries */
|
/* Question Entries */
|
||||||
if (ntohs(nsh->qdcount) !=0 ) {
|
if (ntohs(nsh->qdcount) != 0) {
|
||||||
p = AliasHandleQuestion(
|
p = AliasHandleQuestion(
|
||||||
ntohs(nsh->qdcount),
|
ntohs(nsh->qdcount),
|
||||||
(NBTNsQuestion *)p,
|
(NBTNsQuestion *) p,
|
||||||
pmax,
|
pmax,
|
||||||
&nbtarg
|
&nbtarg
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Answer Resource Records */
|
/* Answer Resource Records */
|
||||||
if (ntohs(nsh->ancount) !=0 ) {
|
if (ntohs(nsh->ancount) != 0) {
|
||||||
p = AliasHandleResource(
|
p = AliasHandleResource(
|
||||||
ntohs(nsh->ancount),
|
ntohs(nsh->ancount),
|
||||||
(NBTNsResource *)p,
|
(NBTNsResource *) p,
|
||||||
pmax,
|
pmax,
|
||||||
&nbtarg
|
&nbtarg
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Authority Resource Recodrs */
|
/* Authority Resource Recodrs */
|
||||||
if (ntohs(nsh->nscount) !=0 ) {
|
if (ntohs(nsh->nscount) != 0) {
|
||||||
p = AliasHandleResource(
|
p = AliasHandleResource(
|
||||||
ntohs(nsh->nscount),
|
ntohs(nsh->nscount),
|
||||||
(NBTNsResource *)p,
|
(NBTNsResource *) p,
|
||||||
pmax,
|
pmax,
|
||||||
&nbtarg
|
&nbtarg
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Additional Resource Recodrs */
|
/* Additional Resource Recodrs */
|
||||||
if (ntohs(nsh->arcount) !=0 ) {
|
if (ntohs(nsh->arcount) != 0) {
|
||||||
p = AliasHandleResource(
|
p = AliasHandleResource(
|
||||||
ntohs(nsh->arcount),
|
ntohs(nsh->arcount),
|
||||||
(NBTNsResource *)p,
|
(NBTNsResource *) p,
|
||||||
pmax,
|
pmax,
|
||||||
&nbtarg
|
&nbtarg
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
PrintRcode(nsh->rcode);
|
PrintRcode(nsh->rcode);
|
||||||
#endif
|
#endif
|
||||||
return ((p == NULL) ? -1 : 0);
|
return ((p == NULL) ? -1 : 0);
|
||||||
}
|
}
|
||||||
|
@ -113,7 +113,7 @@ PacketAliasAddServer(struct alias_link *_link,
|
|||||||
|
|
||||||
struct alias_link *
|
struct alias_link *
|
||||||
PacketAliasRedirectAddr(struct in_addr _src_addr,
|
PacketAliasRedirectAddr(struct in_addr _src_addr,
|
||||||
struct in_addr _alias_addr)
|
struct in_addr _alias_addr)
|
||||||
{
|
{
|
||||||
|
|
||||||
return LibAliasRedirectAddr(la, _src_addr, _alias_addr);
|
return LibAliasRedirectAddr(la, _src_addr, _alias_addr);
|
||||||
@ -152,7 +152,7 @@ PacketAliasRedirectProto(struct in_addr _src_addr,
|
|||||||
{
|
{
|
||||||
|
|
||||||
return LibAliasRedirectProto(la, _src_addr, _dst_addr, _alias_addr,
|
return LibAliasRedirectProto(la, _src_addr, _dst_addr, _alias_addr,
|
||||||
_proto);
|
_proto);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -162,7 +162,7 @@ PacketAliasFragmentIn(char *_ptr, char *_ptr_fragment)
|
|||||||
LibAliasFragmentIn(la, _ptr, _ptr_fragment);
|
LibAliasFragmentIn(la, _ptr, _ptr_fragment);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
PacketAliasGetFragment(char *_ptr)
|
PacketAliasGetFragment(char *_ptr)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -80,16 +80,16 @@ __FBSDID("$FreeBSD$");
|
|||||||
* PPTP definitions
|
* PPTP definitions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct grehdr /* Enhanced GRE header. */
|
struct grehdr { /* Enhanced GRE header. */
|
||||||
{
|
u_int16_t gh_flags; /* Flags. */
|
||||||
u_int16_t gh_flags; /* Flags. */
|
u_int16_t gh_protocol; /* Protocol type. */
|
||||||
u_int16_t gh_protocol; /* Protocol type. */
|
u_int16_t gh_length; /* Payload length. */
|
||||||
u_int16_t gh_length; /* Payload length. */
|
u_int16_t gh_call_id; /* Call ID. */
|
||||||
u_int16_t gh_call_id; /* Call ID. */
|
u_int32_t gh_seq_no; /* Sequence number (optional). */
|
||||||
u_int32_t gh_seq_no; /* Sequence number (optional). */
|
u_int32_t gh_ack_no; /* Acknowledgment number
|
||||||
u_int32_t gh_ack_no; /* Acknowledgment number (optional). */
|
* (optional). */
|
||||||
};
|
};
|
||||||
typedef struct grehdr GreHdr;
|
typedef struct grehdr GreHdr;
|
||||||
|
|
||||||
/* The PPTP protocol ID used in the GRE 'proto' field. */
|
/* The PPTP protocol ID used in the GRE 'proto' field. */
|
||||||
#define PPTP_GRE_PROTO 0x880b
|
#define PPTP_GRE_PROTO 0x880b
|
||||||
@ -102,270 +102,276 @@ typedef struct grehdr GreHdr;
|
|||||||
#define PPTP_CTRL_MSG_TYPE 1
|
#define PPTP_CTRL_MSG_TYPE 1
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PPTP_StartCtrlConnRequest = 1,
|
PPTP_StartCtrlConnRequest = 1,
|
||||||
PPTP_StartCtrlConnReply = 2,
|
PPTP_StartCtrlConnReply = 2,
|
||||||
PPTP_StopCtrlConnRequest = 3,
|
PPTP_StopCtrlConnRequest = 3,
|
||||||
PPTP_StopCtrlConnReply = 4,
|
PPTP_StopCtrlConnReply = 4,
|
||||||
PPTP_EchoRequest = 5,
|
PPTP_EchoRequest = 5,
|
||||||
PPTP_EchoReply = 6,
|
PPTP_EchoReply = 6,
|
||||||
PPTP_OutCallRequest = 7,
|
PPTP_OutCallRequest = 7,
|
||||||
PPTP_OutCallReply = 8,
|
PPTP_OutCallReply = 8,
|
||||||
PPTP_InCallRequest = 9,
|
PPTP_InCallRequest = 9,
|
||||||
PPTP_InCallReply = 10,
|
PPTP_InCallReply = 10,
|
||||||
PPTP_InCallConn = 11,
|
PPTP_InCallConn = 11,
|
||||||
PPTP_CallClearRequest = 12,
|
PPTP_CallClearRequest = 12,
|
||||||
PPTP_CallDiscNotify = 13,
|
PPTP_CallDiscNotify = 13,
|
||||||
PPTP_WanErrorNotify = 14,
|
PPTP_WanErrorNotify = 14,
|
||||||
PPTP_SetLinkInfo = 15
|
PPTP_SetLinkInfo = 15
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Message structures */
|
/* Message structures */
|
||||||
struct pptpMsgHead {
|
struct pptpMsgHead {
|
||||||
u_int16_t length; /* total length */
|
u_int16_t length; /* total length */
|
||||||
u_int16_t msgType; /* PPTP message type */
|
u_int16_t msgType;/* PPTP message type */
|
||||||
u_int32_t magic; /* magic cookie */
|
u_int32_t magic; /* magic cookie */
|
||||||
u_int16_t type; /* control message type */
|
u_int16_t type; /* control message type */
|
||||||
u_int16_t resv0; /* reserved */
|
u_int16_t resv0; /* reserved */
|
||||||
};
|
};
|
||||||
typedef struct pptpMsgHead *PptpMsgHead;
|
typedef struct pptpMsgHead *PptpMsgHead;
|
||||||
|
|
||||||
struct pptpCodes {
|
struct pptpCodes {
|
||||||
u_int8_t resCode; /* Result Code */
|
u_int8_t resCode;/* Result Code */
|
||||||
u_int8_t errCode; /* Error Code */
|
u_int8_t errCode;/* Error Code */
|
||||||
};
|
};
|
||||||
typedef struct pptpCodes *PptpCode;
|
typedef struct pptpCodes *PptpCode;
|
||||||
|
|
||||||
struct pptpCallIds {
|
struct pptpCallIds {
|
||||||
u_int16_t cid1; /* Call ID field #1 */
|
u_int16_t cid1; /* Call ID field #1 */
|
||||||
u_int16_t cid2; /* Call ID field #2 */
|
u_int16_t cid2; /* Call ID field #2 */
|
||||||
};
|
};
|
||||||
typedef struct pptpCallIds *PptpCallId;
|
typedef struct pptpCallIds *PptpCallId;
|
||||||
|
|
||||||
static PptpCallId AliasVerifyPptp(struct ip *, u_int16_t *);
|
static PptpCallId AliasVerifyPptp(struct ip *, u_int16_t *);
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
AliasHandlePptpOut(struct libalias *la,
|
AliasHandlePptpOut(struct libalias *la,
|
||||||
struct ip *pip, /* IP packet to examine/patch */
|
struct ip *pip, /* IP packet to examine/patch */
|
||||||
struct alias_link *link) /* The PPTP control link */
|
struct alias_link *link)
|
||||||
{
|
{ /* The PPTP control link */
|
||||||
struct alias_link *pptp_link;
|
struct alias_link *pptp_link;
|
||||||
PptpCallId cptr;
|
PptpCallId cptr;
|
||||||
PptpCode codes;
|
PptpCode codes;
|
||||||
u_int16_t ctl_type; /* control message type */
|
u_int16_t ctl_type; /* control message type */
|
||||||
struct tcphdr *tc;
|
struct tcphdr *tc;
|
||||||
|
|
||||||
/* Verify valid PPTP control message */
|
/* Verify valid PPTP control message */
|
||||||
if ((cptr = AliasVerifyPptp(pip, &ctl_type)) == NULL)
|
if ((cptr = AliasVerifyPptp(pip, &ctl_type)) == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Modify certain PPTP messages */
|
|
||||||
switch (ctl_type) {
|
|
||||||
case PPTP_OutCallRequest:
|
|
||||||
case PPTP_OutCallReply:
|
|
||||||
case PPTP_InCallRequest:
|
|
||||||
case PPTP_InCallReply:
|
|
||||||
/* Establish PPTP link for address and Call ID found in control message. */
|
|
||||||
pptp_link = AddPptp(la, GetOriginalAddress(link), GetDestAddress(link),
|
|
||||||
GetAliasAddress(link), cptr->cid1);
|
|
||||||
break;
|
|
||||||
case PPTP_CallClearRequest:
|
|
||||||
case PPTP_CallDiscNotify:
|
|
||||||
/* Find PPTP link for address and Call ID found in control message. */
|
|
||||||
pptp_link = FindPptpOutByCallId(la, GetOriginalAddress(link),
|
|
||||||
GetDestAddress(link),
|
|
||||||
cptr->cid1);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pptp_link != NULL) {
|
|
||||||
int accumulate = cptr->cid1;
|
|
||||||
|
|
||||||
/* alias the Call Id */
|
|
||||||
cptr->cid1 = GetAliasPort(pptp_link);
|
|
||||||
|
|
||||||
/* Compute TCP checksum for revised packet */
|
|
||||||
tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
|
|
||||||
accumulate -= cptr->cid1;
|
|
||||||
ADJUST_CHECKSUM(accumulate, tc->th_sum);
|
|
||||||
|
|
||||||
|
/* Modify certain PPTP messages */
|
||||||
switch (ctl_type) {
|
switch (ctl_type) {
|
||||||
|
case PPTP_OutCallRequest:
|
||||||
case PPTP_OutCallReply:
|
case PPTP_OutCallReply:
|
||||||
|
case PPTP_InCallRequest:
|
||||||
case PPTP_InCallReply:
|
case PPTP_InCallReply:
|
||||||
codes = (PptpCode)(cptr + 1);
|
/*
|
||||||
if (codes->resCode == 1) /* Connection established, */
|
* Establish PPTP link for address and Call ID found in
|
||||||
SetDestCallId(pptp_link, /* note the Peer's Call ID. */
|
* control message.
|
||||||
cptr->cid2);
|
*/
|
||||||
else
|
pptp_link = AddPptp(la, GetOriginalAddress(link), GetDestAddress(link),
|
||||||
SetExpire(pptp_link, 0); /* Connection refused. */
|
GetAliasAddress(link), cptr->cid1);
|
||||||
break;
|
break;
|
||||||
case PPTP_CallDiscNotify: /* Connection closed. */
|
case PPTP_CallClearRequest:
|
||||||
SetExpire(pptp_link, 0);
|
case PPTP_CallDiscNotify:
|
||||||
break;
|
/*
|
||||||
|
* Find PPTP link for address and Call ID found in control
|
||||||
|
* message.
|
||||||
|
*/
|
||||||
|
pptp_link = FindPptpOutByCallId(la, GetOriginalAddress(link),
|
||||||
|
GetDestAddress(link),
|
||||||
|
cptr->cid1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pptp_link != NULL) {
|
||||||
|
int accumulate = cptr->cid1;
|
||||||
|
|
||||||
|
/* alias the Call Id */
|
||||||
|
cptr->cid1 = GetAliasPort(pptp_link);
|
||||||
|
|
||||||
|
/* Compute TCP checksum for revised packet */
|
||||||
|
tc = (struct tcphdr *)((char *)pip + (pip->ip_hl << 2));
|
||||||
|
accumulate -= cptr->cid1;
|
||||||
|
ADJUST_CHECKSUM(accumulate, tc->th_sum);
|
||||||
|
|
||||||
|
switch (ctl_type) {
|
||||||
|
case PPTP_OutCallReply:
|
||||||
|
case PPTP_InCallReply:
|
||||||
|
codes = (PptpCode) (cptr + 1);
|
||||||
|
if (codes->resCode == 1) /* Connection
|
||||||
|
* established, */
|
||||||
|
SetDestCallId(pptp_link, /* note the Peer's Call
|
||||||
|
* ID. */
|
||||||
|
cptr->cid2);
|
||||||
|
else
|
||||||
|
SetExpire(pptp_link, 0); /* Connection refused. */
|
||||||
|
break;
|
||||||
|
case PPTP_CallDiscNotify: /* Connection closed. */
|
||||||
|
SetExpire(pptp_link, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
AliasHandlePptpIn(struct libalias *la,
|
AliasHandlePptpIn(struct libalias *la,
|
||||||
struct ip *pip, /* IP packet to examine/patch */
|
struct ip *pip, /* IP packet to examine/patch */
|
||||||
struct alias_link *link) /* The PPTP control link */
|
struct alias_link *link)
|
||||||
{
|
{ /* The PPTP control link */
|
||||||
struct alias_link *pptp_link;
|
struct alias_link *pptp_link;
|
||||||
PptpCallId cptr;
|
PptpCallId cptr;
|
||||||
u_int16_t *pcall_id;
|
u_int16_t *pcall_id;
|
||||||
u_int16_t ctl_type; /* control message type */
|
u_int16_t ctl_type; /* control message type */
|
||||||
struct tcphdr *tc;
|
struct tcphdr *tc;
|
||||||
|
|
||||||
/* Verify valid PPTP control message */
|
/* Verify valid PPTP control message */
|
||||||
if ((cptr = AliasVerifyPptp(pip, &ctl_type)) == NULL)
|
if ((cptr = AliasVerifyPptp(pip, &ctl_type)) == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Modify certain PPTP messages */
|
/* Modify certain PPTP messages */
|
||||||
switch (ctl_type)
|
switch (ctl_type) {
|
||||||
{
|
case PPTP_InCallConn:
|
||||||
case PPTP_InCallConn:
|
case PPTP_WanErrorNotify:
|
||||||
case PPTP_WanErrorNotify:
|
case PPTP_SetLinkInfo:
|
||||||
case PPTP_SetLinkInfo:
|
pcall_id = &cptr->cid1;
|
||||||
pcall_id = &cptr->cid1;
|
break;
|
||||||
break;
|
case PPTP_OutCallReply:
|
||||||
case PPTP_OutCallReply:
|
case PPTP_InCallReply:
|
||||||
case PPTP_InCallReply:
|
pcall_id = &cptr->cid2;
|
||||||
pcall_id = &cptr->cid2;
|
break;
|
||||||
break;
|
case PPTP_CallDiscNotify: /* Connection closed. */
|
||||||
case PPTP_CallDiscNotify: /* Connection closed. */
|
pptp_link = FindPptpInByCallId(la, GetDestAddress(link),
|
||||||
pptp_link = FindPptpInByCallId(la, GetDestAddress(link),
|
GetAliasAddress(link),
|
||||||
GetAliasAddress(link),
|
cptr->cid1);
|
||||||
cptr->cid1);
|
if (pptp_link != NULL)
|
||||||
if (pptp_link != NULL)
|
SetExpire(pptp_link, 0);
|
||||||
SetExpire(pptp_link, 0);
|
return;
|
||||||
return;
|
default:
|
||||||
default:
|
return;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Find PPTP link for address and Call ID found in PPTP Control Msg */
|
/* Find PPTP link for address and Call ID found in PPTP Control Msg */
|
||||||
pptp_link = FindPptpInByPeerCallId(la, GetDestAddress(link),
|
pptp_link = FindPptpInByPeerCallId(la, GetDestAddress(link),
|
||||||
GetAliasAddress(link),
|
GetAliasAddress(link),
|
||||||
*pcall_id);
|
*pcall_id);
|
||||||
|
|
||||||
if (pptp_link != NULL) {
|
if (pptp_link != NULL) {
|
||||||
int accumulate = *pcall_id;
|
int accumulate = *pcall_id;
|
||||||
|
|
||||||
/* De-alias the Peer's Call Id. */
|
/* De-alias the Peer's Call Id. */
|
||||||
*pcall_id = GetOriginalPort(pptp_link);
|
*pcall_id = GetOriginalPort(pptp_link);
|
||||||
|
|
||||||
/* Compute TCP checksum for modified packet */
|
/* Compute TCP checksum for modified packet */
|
||||||
tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
|
tc = (struct tcphdr *)((char *)pip + (pip->ip_hl << 2));
|
||||||
accumulate -= *pcall_id;
|
accumulate -= *pcall_id;
|
||||||
ADJUST_CHECKSUM(accumulate, tc->th_sum);
|
ADJUST_CHECKSUM(accumulate, tc->th_sum);
|
||||||
|
|
||||||
if (ctl_type == PPTP_OutCallReply || ctl_type == PPTP_InCallReply) {
|
if (ctl_type == PPTP_OutCallReply || ctl_type == PPTP_InCallReply) {
|
||||||
PptpCode codes = (PptpCode)(cptr + 1);
|
PptpCode codes = (PptpCode) (cptr + 1);
|
||||||
|
|
||||||
if (codes->resCode == 1) /* Connection established, */
|
if (codes->resCode == 1) /* Connection
|
||||||
SetDestCallId(pptp_link, /* note the Call ID. */
|
* established, */
|
||||||
cptr->cid1);
|
SetDestCallId(pptp_link, /* note the Call ID. */
|
||||||
else
|
cptr->cid1);
|
||||||
SetExpire(pptp_link, 0); /* Connection refused. */
|
else
|
||||||
}
|
SetExpire(pptp_link, 0); /* Connection refused. */
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static PptpCallId
|
static PptpCallId
|
||||||
AliasVerifyPptp(struct ip *pip, u_int16_t *ptype) /* IP packet to examine/patch */
|
AliasVerifyPptp(struct ip *pip, u_int16_t * ptype)
|
||||||
{
|
{ /* IP packet to examine/patch */
|
||||||
int hlen, tlen, dlen;
|
int hlen, tlen, dlen;
|
||||||
PptpMsgHead hptr;
|
PptpMsgHead hptr;
|
||||||
struct tcphdr *tc;
|
struct tcphdr *tc;
|
||||||
|
|
||||||
/* Calculate some lengths */
|
/* Calculate some lengths */
|
||||||
tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
|
tc = (struct tcphdr *)((char *)pip + (pip->ip_hl << 2));
|
||||||
hlen = (pip->ip_hl + tc->th_off) << 2;
|
hlen = (pip->ip_hl + tc->th_off) << 2;
|
||||||
tlen = ntohs(pip->ip_len);
|
tlen = ntohs(pip->ip_len);
|
||||||
dlen = tlen - hlen;
|
dlen = tlen - hlen;
|
||||||
|
|
||||||
/* Verify data length */
|
/* Verify data length */
|
||||||
if (dlen < (sizeof(struct pptpMsgHead) + sizeof(struct pptpCallIds)))
|
if (dlen < (sizeof(struct pptpMsgHead) + sizeof(struct pptpCallIds)))
|
||||||
return(NULL);
|
return (NULL);
|
||||||
|
|
||||||
/* Move up to PPTP message header */
|
/* Move up to PPTP message header */
|
||||||
hptr = (PptpMsgHead)(((char *) pip) + hlen);
|
hptr = (PptpMsgHead) (((char *)pip) + hlen);
|
||||||
|
|
||||||
/* Return the control message type */
|
/* Return the control message type */
|
||||||
*ptype = ntohs(hptr->type);
|
*ptype = ntohs(hptr->type);
|
||||||
|
|
||||||
/* Verify PPTP Control Message */
|
/* Verify PPTP Control Message */
|
||||||
if ((ntohs(hptr->msgType) != PPTP_CTRL_MSG_TYPE) ||
|
if ((ntohs(hptr->msgType) != PPTP_CTRL_MSG_TYPE) ||
|
||||||
(ntohl(hptr->magic) != PPTP_MAGIC))
|
(ntohl(hptr->magic) != PPTP_MAGIC))
|
||||||
return(NULL);
|
return (NULL);
|
||||||
|
|
||||||
/* Verify data length. */
|
/* Verify data length. */
|
||||||
if ((*ptype == PPTP_OutCallReply || *ptype == PPTP_InCallReply) &&
|
if ((*ptype == PPTP_OutCallReply || *ptype == PPTP_InCallReply) &&
|
||||||
(dlen < sizeof(struct pptpMsgHead) + sizeof(struct pptpCallIds) +
|
(dlen < sizeof(struct pptpMsgHead) + sizeof(struct pptpCallIds) +
|
||||||
sizeof(struct pptpCodes)))
|
sizeof(struct pptpCodes)))
|
||||||
return (NULL);
|
return (NULL);
|
||||||
else
|
else
|
||||||
return (PptpCallId)(hptr + 1);
|
return (PptpCallId) (hptr + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
AliasHandlePptpGreOut(struct libalias *la, struct ip *pip)
|
AliasHandlePptpGreOut(struct libalias *la, struct ip *pip)
|
||||||
{
|
{
|
||||||
GreHdr *gr;
|
GreHdr *gr;
|
||||||
struct alias_link *link;
|
struct alias_link *link;
|
||||||
|
|
||||||
gr = (GreHdr *)((char *)pip + (pip->ip_hl << 2));
|
gr = (GreHdr *) ((char *)pip + (pip->ip_hl << 2));
|
||||||
|
|
||||||
/* Check GRE header bits. */
|
/* Check GRE header bits. */
|
||||||
if ((ntohl(*((u_int32_t *)gr)) & PPTP_INIT_MASK) != PPTP_INIT_VALUE)
|
if ((ntohl(*((u_int32_t *) gr)) & PPTP_INIT_MASK) != PPTP_INIT_VALUE)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
|
||||||
link = FindPptpOutByPeerCallId(la, pip->ip_src, pip->ip_dst, gr->gh_call_id);
|
link = FindPptpOutByPeerCallId(la, pip->ip_src, pip->ip_dst, gr->gh_call_id);
|
||||||
if (link != NULL) {
|
if (link != NULL) {
|
||||||
struct in_addr alias_addr = GetAliasAddress(link);
|
struct in_addr alias_addr = GetAliasAddress(link);
|
||||||
|
|
||||||
/* Change source IP address. */
|
/* Change source IP address. */
|
||||||
DifferentialChecksum(&pip->ip_sum,
|
DifferentialChecksum(&pip->ip_sum,
|
||||||
(u_short *)&alias_addr,
|
(u_short *) & alias_addr,
|
||||||
(u_short *)&pip->ip_src,
|
(u_short *) & pip->ip_src,
|
||||||
2);
|
2);
|
||||||
pip->ip_src = alias_addr;
|
pip->ip_src = alias_addr;
|
||||||
}
|
}
|
||||||
|
return (0);
|
||||||
return (0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
AliasHandlePptpGreIn(struct libalias *la, struct ip *pip)
|
AliasHandlePptpGreIn(struct libalias *la, struct ip *pip)
|
||||||
{
|
{
|
||||||
GreHdr *gr;
|
GreHdr *gr;
|
||||||
struct alias_link *link;
|
struct alias_link *link;
|
||||||
|
|
||||||
gr = (GreHdr *)((char *)pip + (pip->ip_hl << 2));
|
gr = (GreHdr *) ((char *)pip + (pip->ip_hl << 2));
|
||||||
|
|
||||||
/* Check GRE header bits. */
|
/* Check GRE header bits. */
|
||||||
if ((ntohl(*((u_int32_t *)gr)) & PPTP_INIT_MASK) != PPTP_INIT_VALUE)
|
if ((ntohl(*((u_int32_t *) gr)) & PPTP_INIT_MASK) != PPTP_INIT_VALUE)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
|
||||||
link = FindPptpInByPeerCallId(la, pip->ip_src, pip->ip_dst, gr->gh_call_id);
|
link = FindPptpInByPeerCallId(la, pip->ip_src, pip->ip_dst, gr->gh_call_id);
|
||||||
if (link != NULL) {
|
if (link != NULL) {
|
||||||
struct in_addr src_addr = GetOriginalAddress(link);
|
struct in_addr src_addr = GetOriginalAddress(link);
|
||||||
|
|
||||||
/* De-alias the Peer's Call Id. */
|
/* De-alias the Peer's Call Id. */
|
||||||
gr->gh_call_id = GetOriginalPort(link);
|
gr->gh_call_id = GetOriginalPort(link);
|
||||||
|
|
||||||
/* Restore original IP address. */
|
/* Restore original IP address. */
|
||||||
DifferentialChecksum(&pip->ip_sum,
|
DifferentialChecksum(&pip->ip_sum,
|
||||||
(u_short *)&src_addr,
|
(u_short *) & src_addr,
|
||||||
(u_short *)&pip->ip_dst,
|
(u_short *) & pip->ip_dst,
|
||||||
2);
|
2);
|
||||||
pip->ip_dst = src_addr;
|
pip->ip_dst = src_addr;
|
||||||
}
|
}
|
||||||
|
return (0);
|
||||||
return (0);
|
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -60,10 +60,10 @@
|
|||||||
* has answered. The phone then sends back an Open Receive Channel
|
* has answered. The phone then sends back an Open Receive Channel
|
||||||
* Acknowledgement. In this packet, the phone sends its IP address again,
|
* Acknowledgement. In this packet, the phone sends its IP address again,
|
||||||
* and the UDP port over which the voice traffic should flow. These values
|
* and the UDP port over which the voice traffic should flow. These values
|
||||||
* need translation. Right after the Open Receive Channel Acknowledgement,
|
* need translation. Right after the Open Receive Channel Acknowledgement,
|
||||||
* the Call Manager sends a Start Media Transmission message indicating the
|
* the Call Manager sends a Start Media Transmission message indicating the
|
||||||
* call is connected. This message contains the IP address and UDP port
|
* call is connected. This message contains the IP address and UDP port
|
||||||
* number of the remote (called) party. Once this message is translated, the
|
* number of the remote (called) party. Once this message is translated, the
|
||||||
* call can commence. The called part sends the first UDP packet to the
|
* call can commence. The called part sends the first UDP packet to the
|
||||||
* calling phone at the pre-arranged UDP port in the Open Receive Channel
|
* calling phone at the pre-arranged UDP port in the Open Receive Channel
|
||||||
* Acknowledgement.
|
* Acknowledgement.
|
||||||
@ -81,258 +81,258 @@
|
|||||||
#define START_MEDIATX 0x0000008a
|
#define START_MEDIATX 0x0000008a
|
||||||
|
|
||||||
struct skinny_header {
|
struct skinny_header {
|
||||||
u_int32_t len;
|
u_int32_t len;
|
||||||
u_int32_t reserved;
|
u_int32_t reserved;
|
||||||
u_int32_t msgId;
|
u_int32_t msgId;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RegisterMessage {
|
struct RegisterMessage {
|
||||||
u_int32_t msgId;
|
u_int32_t msgId;
|
||||||
char devName[16];
|
char devName [16];
|
||||||
u_int32_t uid;
|
u_int32_t uid;
|
||||||
u_int32_t instance;
|
u_int32_t instance;
|
||||||
u_int32_t ipAddr;
|
u_int32_t ipAddr;
|
||||||
u_char devType;
|
u_char devType;
|
||||||
u_int32_t maxStreams;
|
u_int32_t maxStreams;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IpPortMessage {
|
struct IpPortMessage {
|
||||||
u_int32_t msgId;
|
u_int32_t msgId;
|
||||||
u_int32_t stationIpPort; /* Note: Skinny uses 32-bit port
|
u_int32_t stationIpPort; /* Note: Skinny uses 32-bit port
|
||||||
* numbers */
|
* numbers */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct OpenReceiveChannelAck {
|
struct OpenReceiveChannelAck {
|
||||||
u_int32_t msgId;
|
u_int32_t msgId;
|
||||||
u_int32_t status;
|
u_int32_t status;
|
||||||
u_int32_t ipAddr;
|
u_int32_t ipAddr;
|
||||||
u_int32_t port;
|
u_int32_t port;
|
||||||
u_int32_t passThruPartyID;
|
u_int32_t passThruPartyID;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct StartMediaTransmission {
|
struct StartMediaTransmission {
|
||||||
u_int32_t msgId;
|
u_int32_t msgId;
|
||||||
u_int32_t conferenceID;
|
u_int32_t conferenceID;
|
||||||
u_int32_t passThruPartyID;
|
u_int32_t passThruPartyID;
|
||||||
u_int32_t remoteIpAddr;
|
u_int32_t remoteIpAddr;
|
||||||
u_int32_t remotePort;
|
u_int32_t remotePort;
|
||||||
u_int32_t MSPacket;
|
u_int32_t MSPacket;
|
||||||
u_int32_t payloadCap;
|
u_int32_t payloadCap;
|
||||||
u_int32_t precedence;
|
u_int32_t precedence;
|
||||||
u_int32_t silenceSuppression;
|
u_int32_t silenceSuppression;
|
||||||
u_short maxFramesPerPacket;
|
u_short maxFramesPerPacket;
|
||||||
u_int32_t G723BitRate;
|
u_int32_t G723BitRate;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ClientToServer = 0,
|
ClientToServer = 0,
|
||||||
ServerToClient = 1
|
ServerToClient = 1
|
||||||
} ConvDirection;
|
} ConvDirection;
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
alias_skinny_reg_msg(struct RegisterMessage *reg_msg, struct ip *pip,
|
alias_skinny_reg_msg(struct RegisterMessage *reg_msg, struct ip *pip,
|
||||||
struct tcphdr *tc, struct alias_link *link,
|
struct tcphdr *tc, struct alias_link *link,
|
||||||
ConvDirection direction)
|
ConvDirection direction)
|
||||||
{
|
{
|
||||||
reg_msg->ipAddr = (u_int32_t) GetAliasAddress(link).s_addr;
|
reg_msg->ipAddr = (u_int32_t) GetAliasAddress(link).s_addr;
|
||||||
|
|
||||||
tc->th_sum = 0;
|
tc->th_sum = 0;
|
||||||
tc->th_sum = TcpChecksum(pip);
|
tc->th_sum = TcpChecksum(pip);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
alias_skinny_startmedia(struct StartMediaTransmission *start_media,
|
alias_skinny_startmedia(struct StartMediaTransmission *start_media,
|
||||||
struct ip *pip, struct tcphdr *tc,
|
struct ip *pip, struct tcphdr *tc,
|
||||||
struct alias_link *link, u_int32_t localIpAddr,
|
struct alias_link *link, u_int32_t localIpAddr,
|
||||||
ConvDirection direction)
|
ConvDirection direction)
|
||||||
{
|
{
|
||||||
struct in_addr dst, src;
|
struct in_addr dst, src;
|
||||||
|
|
||||||
dst.s_addr = start_media->remoteIpAddr;
|
dst.s_addr = start_media->remoteIpAddr;
|
||||||
src.s_addr = localIpAddr;
|
src.s_addr = localIpAddr;
|
||||||
|
|
||||||
/* XXX I should probably handle in bound global translations as well. */
|
/*
|
||||||
|
* XXX I should probably handle in bound global translations as
|
||||||
|
* well.
|
||||||
|
*/
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
alias_skinny_port_msg(struct IpPortMessage *port_msg, struct ip *pip,
|
alias_skinny_port_msg(struct IpPortMessage *port_msg, struct ip *pip,
|
||||||
struct tcphdr *tc, struct alias_link *link,
|
struct tcphdr *tc, struct alias_link *link,
|
||||||
ConvDirection direction)
|
ConvDirection direction)
|
||||||
{
|
{
|
||||||
port_msg->stationIpPort = (u_int32_t) ntohs(GetAliasPort(link));
|
port_msg->stationIpPort = (u_int32_t) ntohs(GetAliasPort(link));
|
||||||
|
|
||||||
tc->th_sum = 0;
|
tc->th_sum = 0;
|
||||||
tc->th_sum = TcpChecksum(pip);
|
tc->th_sum = TcpChecksum(pip);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
alias_skinny_opnrcvch_ack(struct libalias *la, struct OpenReceiveChannelAck *opnrcvch_ack,
|
alias_skinny_opnrcvch_ack(struct libalias *la, struct OpenReceiveChannelAck *opnrcvch_ack,
|
||||||
struct ip * pip, struct tcphdr *tc,
|
struct ip *pip, struct tcphdr *tc,
|
||||||
struct alias_link *link, u_int32_t *localIpAddr,
|
struct alias_link *link, u_int32_t * localIpAddr,
|
||||||
ConvDirection direction)
|
ConvDirection direction)
|
||||||
{
|
{
|
||||||
struct in_addr null_addr;
|
struct in_addr null_addr;
|
||||||
struct alias_link *opnrcv_link;
|
struct alias_link *opnrcv_link;
|
||||||
u_int32_t localPort;
|
u_int32_t localPort;
|
||||||
|
|
||||||
*localIpAddr = (u_int32_t) opnrcvch_ack->ipAddr;
|
*localIpAddr = (u_int32_t) opnrcvch_ack->ipAddr;
|
||||||
localPort = opnrcvch_ack->port;
|
localPort = opnrcvch_ack->port;
|
||||||
|
|
||||||
null_addr.s_addr = INADDR_ANY;
|
null_addr.s_addr = INADDR_ANY;
|
||||||
opnrcv_link = FindUdpTcpOut(la, pip->ip_src, null_addr,
|
opnrcv_link = FindUdpTcpOut(la, pip->ip_src, null_addr,
|
||||||
htons((u_short) opnrcvch_ack->port), 0,
|
htons((u_short) opnrcvch_ack->port), 0,
|
||||||
IPPROTO_UDP, 1);
|
IPPROTO_UDP, 1);
|
||||||
opnrcvch_ack->ipAddr = (u_int32_t) GetAliasAddress(opnrcv_link).s_addr;
|
opnrcvch_ack->ipAddr = (u_int32_t) GetAliasAddress(opnrcv_link).s_addr;
|
||||||
opnrcvch_ack->port = (u_int32_t) ntohs(GetAliasPort(opnrcv_link));
|
opnrcvch_ack->port = (u_int32_t) ntohs(GetAliasPort(opnrcv_link));
|
||||||
|
|
||||||
tc->th_sum = 0;
|
tc->th_sum = 0;
|
||||||
tc->th_sum = TcpChecksum(pip);
|
tc->th_sum = TcpChecksum(pip);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
AliasHandleSkinny(struct libalias *la, struct ip *pip, struct alias_link *link)
|
AliasHandleSkinny(struct libalias *la, struct ip *pip, struct alias_link *link)
|
||||||
{
|
{
|
||||||
int hlen, tlen, dlen;
|
int hlen, tlen, dlen;
|
||||||
struct tcphdr *tc;
|
struct tcphdr *tc;
|
||||||
u_int32_t msgId, len, t, lip;
|
u_int32_t msgId, len, t, lip;
|
||||||
struct skinny_header *sd;
|
struct skinny_header *sd;
|
||||||
int orig_len, skinny_hdr_len = sizeof(struct skinny_header);
|
int orig_len, skinny_hdr_len = sizeof(struct skinny_header);
|
||||||
ConvDirection direction;
|
ConvDirection direction;
|
||||||
|
|
||||||
tc = (struct tcphdr *) ((char *)pip + (pip->ip_hl << 2));
|
tc = (struct tcphdr *)((char *)pip + (pip->ip_hl << 2));
|
||||||
hlen = (pip->ip_hl + tc->th_off) << 2;
|
hlen = (pip->ip_hl + tc->th_off) << 2;
|
||||||
tlen = ntohs(pip->ip_len);
|
tlen = ntohs(pip->ip_len);
|
||||||
dlen = tlen - hlen;
|
dlen = tlen - hlen;
|
||||||
|
|
||||||
sd = (struct skinny_header *) ((char *)pip + hlen);
|
sd = (struct skinny_header *)((char *)pip + hlen);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX This direction is reserved for future use. I still need to
|
* XXX This direction is reserved for future use. I still need to
|
||||||
* handle the scenario where the call manager is on the inside, and
|
* handle the scenario where the call manager is on the inside, and
|
||||||
* the calling phone is on the global outside.
|
* the calling phone is on the global outside.
|
||||||
*/
|
*/
|
||||||
if (ntohs(tc->th_dport) == la->skinnyPort) {
|
if (ntohs(tc->th_dport) == la->skinnyPort) {
|
||||||
direction = ClientToServer;
|
direction = ClientToServer;
|
||||||
} else if (ntohs(tc->th_sport) == la->skinnyPort) {
|
} else if (ntohs(tc->th_sport) == la->skinnyPort) {
|
||||||
direction = ServerToClient;
|
direction = ServerToClient;
|
||||||
} else {
|
} else {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"PacketAlias/Skinny: Invalid port number, not a Skinny packet\n");
|
"PacketAlias/Skinny: Invalid port number, not a Skinny packet\n");
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
orig_len = dlen;
|
orig_len = dlen;
|
||||||
/*
|
/*
|
||||||
* Skinny packets can contain many messages. We need to loop through
|
* Skinny packets can contain many messages. We need to loop
|
||||||
* the packet using len to determine message boundaries. This comes
|
* through the packet using len to determine message boundaries.
|
||||||
* into play big time with port messages being in the same packet as
|
* This comes into play big time with port messages being in the
|
||||||
* register messages. Also, open receive channel acks are
|
* same packet as register messages. Also, open receive channel
|
||||||
* usually buried in a pakcet some 400 bytes long.
|
* acks are usually buried in a pakcet some 400 bytes long.
|
||||||
*/
|
*/
|
||||||
while (dlen >= skinny_hdr_len) {
|
while (dlen >= skinny_hdr_len) {
|
||||||
len = (sd->len);
|
len = (sd->len);
|
||||||
msgId = (sd->msgId);
|
msgId = (sd->msgId);
|
||||||
t = len;
|
t = len;
|
||||||
|
|
||||||
if (t < 0 || t > orig_len || t > dlen) {
|
if (t < 0 || t > orig_len || t > dlen) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"PacketAlias/Skinny: Not a skinny packet, invalid length \n");
|
"PacketAlias/Skinny: Not a skinny packet, invalid length \n");
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switch (msgId) {
|
switch (msgId) {
|
||||||
case REG_MSG:
|
case REG_MSG: {
|
||||||
{
|
struct RegisterMessage *reg_mesg;
|
||||||
struct RegisterMessage *reg_mesg;
|
|
||||||
|
|
||||||
if (len < sizeof(struct RegisterMessage)) {
|
if (len < sizeof(struct RegisterMessage)) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"PacketAlias/Skinny: Not a skinny packet, bad registration message\n");
|
"PacketAlias/Skinny: Not a skinny packet, bad registration message\n");
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
reg_mesg = (struct RegisterMessage *) & sd->msgId;
|
reg_mesg = (struct RegisterMessage *)&sd->msgId;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"PacketAlias/Skinny: Received a register message");
|
"PacketAlias/Skinny: Received a register message");
|
||||||
#endif
|
#endif
|
||||||
alias_skinny_reg_msg(reg_mesg, pip, tc, link, direction);
|
alias_skinny_reg_msg(reg_mesg, pip, tc, link, direction);
|
||||||
}
|
break;
|
||||||
break;
|
}
|
||||||
case IP_PORT_MSG:
|
case IP_PORT_MSG: {
|
||||||
{
|
struct IpPortMessage *port_mesg;
|
||||||
struct IpPortMessage *port_mesg;
|
|
||||||
if (len < sizeof(struct IpPortMessage)) {
|
|
||||||
#ifdef DEBUG
|
|
||||||
fprintf(stderr,
|
|
||||||
"PacketAlias/Skinny: Not a skinny packet, port message\n");
|
|
||||||
#endif
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#ifdef DEBUG
|
|
||||||
fprintf(stderr
|
|
||||||
"PacketAlias/Skinny: Received ipport message\n");
|
|
||||||
#endif
|
|
||||||
port_mesg = (struct IpPortMessage *) & sd->msgId;
|
|
||||||
alias_skinny_port_msg(port_mesg, pip, tc, link, direction);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case OPNRCVCH_ACK:
|
|
||||||
{
|
|
||||||
struct OpenReceiveChannelAck *opnrcvchn_ack;
|
|
||||||
|
|
||||||
if (len < sizeof(struct OpenReceiveChannelAck)) {
|
if (len < sizeof(struct IpPortMessage)) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"PacketAlias/Skinny: Not a skinny packet, packet,OpnRcvChnAckMsg\n");
|
"PacketAlias/Skinny: Not a skinny packet, port message\n");
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr,
|
fprintf(stderr
|
||||||
"PacketAlias/Skinny: Received open rcv channel msg\n");
|
"PacketAlias/Skinny: Received ipport message\n");
|
||||||
#endif
|
#endif
|
||||||
opnrcvchn_ack = (struct OpenReceiveChannelAck *) & sd->msgId;
|
port_mesg = (struct IpPortMessage *)&sd->msgId;
|
||||||
alias_skinny_opnrcvch_ack(la, opnrcvchn_ack, pip, tc, link, &lip, direction);
|
alias_skinny_port_msg(port_mesg, pip, tc, link, direction);
|
||||||
}
|
break;
|
||||||
break;
|
}
|
||||||
case START_MEDIATX:
|
case OPNRCVCH_ACK: {
|
||||||
{
|
struct OpenReceiveChannelAck *opnrcvchn_ack;
|
||||||
struct StartMediaTransmission *startmedia_tx;
|
|
||||||
|
|
||||||
if (len < sizeof(struct StartMediaTransmission)) {
|
if (len < sizeof(struct OpenReceiveChannelAck)) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"PacketAlias/Skinny: Not a skinny packet,StartMediaTx Message\n");
|
"PacketAlias/Skinny: Not a skinny packet, packet,OpnRcvChnAckMsg\n");
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"PacketAlias/Skinny: Received start media trans msg\n");
|
"PacketAlias/Skinny: Received open rcv channel msg\n");
|
||||||
#endif
|
#endif
|
||||||
startmedia_tx = (struct StartMediaTransmission *) & sd->msgId;
|
opnrcvchn_ack = (struct OpenReceiveChannelAck *)&sd->msgId;
|
||||||
alias_skinny_startmedia(startmedia_tx, pip, tc, link, lip, direction);
|
alias_skinny_opnrcvch_ack(la, opnrcvchn_ack, pip, tc, link, &lip, direction);
|
||||||
}
|
break;
|
||||||
break;
|
}
|
||||||
default:
|
case START_MEDIATX: {
|
||||||
break;
|
struct StartMediaTransmission *startmedia_tx;
|
||||||
}
|
|
||||||
/* Place the pointer at the next message in the packet. */
|
if (len < sizeof(struct StartMediaTransmission)) {
|
||||||
dlen -= len + (skinny_hdr_len - sizeof(msgId));
|
#ifdef DEBUG
|
||||||
sd = (struct skinny_header *) (((char *)&sd->msgId) + len);
|
fprintf(stderr,
|
||||||
}
|
"PacketAlias/Skinny: Not a skinny packet,StartMediaTx Message\n");
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf(stderr,
|
||||||
|
"PacketAlias/Skinny: Received start media trans msg\n");
|
||||||
|
#endif
|
||||||
|
startmedia_tx = (struct StartMediaTransmission *)&sd->msgId;
|
||||||
|
alias_skinny_startmedia(startmedia_tx, pip, tc, link, lip, direction);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* Place the pointer at the next message in the packet. */
|
||||||
|
dlen -= len + (skinny_hdr_len - sizeof(msgId));
|
||||||
|
sd = (struct skinny_header *)(((char *)&sd->msgId) + len);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -118,316 +118,326 @@ __FBSDID("$FreeBSD$");
|
|||||||
static int
|
static int
|
||||||
search_string(char *data, int dlen, const char *search_str)
|
search_string(char *data, int dlen, const char *search_str)
|
||||||
{
|
{
|
||||||
int i, j, k;
|
int i, j, k;
|
||||||
int search_str_len;
|
int search_str_len;
|
||||||
|
|
||||||
search_str_len = strlen(search_str);
|
search_str_len = strlen(search_str);
|
||||||
for (i = 0; i < dlen - search_str_len; i++) {
|
for (i = 0; i < dlen - search_str_len; i++) {
|
||||||
for (j = i, k = 0; j < dlen - search_str_len; j++, k++) {
|
for (j = i, k = 0; j < dlen - search_str_len; j++, k++) {
|
||||||
if (data[j] != search_str[k] &&
|
if (data[j] != search_str[k] &&
|
||||||
data[j] != search_str[k] - ('a' - 'A')) {
|
data[j] != search_str[k] - ('a' - 'A')) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (k == search_str_len - 1) {
|
if (k == search_str_len - 1) {
|
||||||
return j + 1;
|
return j + 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
return -1;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
alias_rtsp_out(struct libalias *la, struct ip *pip,
|
alias_rtsp_out(struct libalias *la, struct ip *pip,
|
||||||
struct alias_link *link,
|
struct alias_link *link,
|
||||||
char *data,
|
char *data,
|
||||||
const char *port_str)
|
const char *port_str)
|
||||||
{
|
{
|
||||||
int hlen, tlen, dlen;
|
int hlen, tlen, dlen;
|
||||||
struct tcphdr *tc;
|
struct tcphdr *tc;
|
||||||
int i, j, pos, state, port_dlen, new_dlen, delta;
|
int i, j, pos, state, port_dlen, new_dlen, delta;
|
||||||
u_short p[2], new_len;
|
u_short p[2], new_len;
|
||||||
u_short sport, eport, base_port;
|
u_short sport, eport, base_port;
|
||||||
u_short salias = 0, ealias = 0, base_alias = 0;
|
u_short salias = 0, ealias = 0, base_alias = 0;
|
||||||
const char *transport_str = "transport:";
|
const char *transport_str = "transport:";
|
||||||
char newdata[2048], *port_data, *port_newdata, stemp[80];
|
char newdata[2048], *port_data, *port_newdata, stemp[80];
|
||||||
int links_created = 0, pkt_updated = 0;
|
int links_created = 0, pkt_updated = 0;
|
||||||
struct alias_link *rtsp_link = NULL;
|
struct alias_link *rtsp_link = NULL;
|
||||||
struct in_addr null_addr;
|
struct in_addr null_addr;
|
||||||
|
|
||||||
/* Calculate data length of TCP packet */
|
/* Calculate data length of TCP packet */
|
||||||
tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
|
tc = (struct tcphdr *)((char *)pip + (pip->ip_hl << 2));
|
||||||
hlen = (pip->ip_hl + tc->th_off) << 2;
|
hlen = (pip->ip_hl + tc->th_off) << 2;
|
||||||
tlen = ntohs(pip->ip_len);
|
tlen = ntohs(pip->ip_len);
|
||||||
dlen = tlen - hlen;
|
dlen = tlen - hlen;
|
||||||
|
|
||||||
/* Find keyword, "Transport: " */
|
/* Find keyword, "Transport: " */
|
||||||
pos = search_string(data, dlen, transport_str);
|
pos = search_string(data, dlen, transport_str);
|
||||||
if (pos < 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
port_data = data + pos;
|
|
||||||
port_dlen = dlen - pos;
|
|
||||||
|
|
||||||
memcpy(newdata, data, pos);
|
|
||||||
port_newdata = newdata + pos;
|
|
||||||
|
|
||||||
while (port_dlen > strlen(port_str)) {
|
|
||||||
/* Find keyword, appropriate port string */
|
|
||||||
pos = search_string(port_data, port_dlen, port_str);
|
|
||||||
if (pos < 0) {
|
if (pos < 0) {
|
||||||
break;
|
return -1;
|
||||||
}
|
}
|
||||||
|
port_data = data + pos;
|
||||||
|
port_dlen = dlen - pos;
|
||||||
|
|
||||||
memcpy (port_newdata, port_data, pos + 1);
|
memcpy(newdata, data, pos);
|
||||||
port_newdata += (pos + 1);
|
port_newdata = newdata + pos;
|
||||||
|
|
||||||
p[0] = p[1] = 0;
|
while (port_dlen > strlen(port_str)) {
|
||||||
sport = eport = 0;
|
/* Find keyword, appropriate port string */
|
||||||
state = 0;
|
pos = search_string(port_data, port_dlen, port_str);
|
||||||
for (i = pos; i < port_dlen; i++) {
|
if (pos < 0) {
|
||||||
switch(state) {
|
break;
|
||||||
case 0:
|
|
||||||
if (port_data[i] == '=') {
|
|
||||||
state++;
|
|
||||||
}
|
}
|
||||||
break;
|
memcpy(port_newdata, port_data, pos + 1);
|
||||||
case 1:
|
port_newdata += (pos + 1);
|
||||||
if (ISDIGIT(port_data[i])) {
|
|
||||||
p[0] = p[0] * 10 + port_data[i] - '0';
|
|
||||||
} else {
|
|
||||||
if (port_data[i] == ';') {
|
|
||||||
state = 3;
|
|
||||||
}
|
|
||||||
if (port_data[i] == '-') {
|
|
||||||
state++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
if (ISDIGIT(port_data[i])) {
|
|
||||||
p[1] = p[1] * 10 + port_data[i] - '0';
|
|
||||||
} else {
|
|
||||||
state++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
base_port = p[0];
|
|
||||||
sport = htons(p[0]);
|
|
||||||
eport = htons(p[1]);
|
|
||||||
|
|
||||||
if (!links_created) {
|
p[0] = p[1] = 0;
|
||||||
|
sport = eport = 0;
|
||||||
|
state = 0;
|
||||||
|
for (i = pos; i < port_dlen; i++) {
|
||||||
|
switch (state) {
|
||||||
|
case 0:
|
||||||
|
if (port_data[i] == '=') {
|
||||||
|
state++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (ISDIGIT(port_data[i])) {
|
||||||
|
p[0] = p[0] * 10 + port_data[i] - '0';
|
||||||
|
} else {
|
||||||
|
if (port_data[i] == ';') {
|
||||||
|
state = 3;
|
||||||
|
}
|
||||||
|
if (port_data[i] == '-') {
|
||||||
|
state++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (ISDIGIT(port_data[i])) {
|
||||||
|
p[1] = p[1] * 10 + port_data[i] - '0';
|
||||||
|
} else {
|
||||||
|
state++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
base_port = p[0];
|
||||||
|
sport = htons(p[0]);
|
||||||
|
eport = htons(p[1]);
|
||||||
|
|
||||||
links_created = 1;
|
if (!links_created) {
|
||||||
/* Find an even numbered port number base that
|
|
||||||
satisfies the contiguous number of ports we need */
|
links_created = 1;
|
||||||
null_addr.s_addr = 0;
|
/*
|
||||||
if (0 == (salias = FindNewPortGroup(la, null_addr,
|
* Find an even numbered port
|
||||||
FindAliasAddress(la, pip->ip_src),
|
* number base that satisfies the
|
||||||
sport, 0,
|
* contiguous number of ports we
|
||||||
RTSP_PORT_GROUP,
|
* need
|
||||||
IPPROTO_UDP, 1))) {
|
*/
|
||||||
|
null_addr.s_addr = 0;
|
||||||
|
if (0 == (salias = FindNewPortGroup(la, null_addr,
|
||||||
|
FindAliasAddress(la, pip->ip_src),
|
||||||
|
sport, 0,
|
||||||
|
RTSP_PORT_GROUP,
|
||||||
|
IPPROTO_UDP, 1))) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"PacketAlias/RTSP: Cannot find contiguous RTSP data ports\n");
|
"PacketAlias/RTSP: Cannot find contiguous RTSP data ports\n");
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
base_alias = ntohs(salias);
|
base_alias = ntohs(salias);
|
||||||
for (j = 0; j < RTSP_PORT_GROUP; j++) {
|
for (j = 0; j < RTSP_PORT_GROUP; j++) {
|
||||||
/* Establish link to port found in RTSP packet */
|
/*
|
||||||
rtsp_link = FindRtspOut(la, GetOriginalAddress(link), null_addr,
|
* Establish link
|
||||||
htons(base_port + j), htons(base_alias + j),
|
* to port found in
|
||||||
IPPROTO_UDP);
|
* RTSP packet
|
||||||
if (rtsp_link != NULL) {
|
*/
|
||||||
|
rtsp_link = FindRtspOut(la, GetOriginalAddress(link), null_addr,
|
||||||
|
htons(base_port + j), htons(base_alias + j),
|
||||||
|
IPPROTO_UDP);
|
||||||
|
if (rtsp_link != NULL) {
|
||||||
#ifndef NO_FW_PUNCH
|
#ifndef NO_FW_PUNCH
|
||||||
/* Punch hole in firewall */
|
/*
|
||||||
PunchFWHole(rtsp_link);
|
* Punch
|
||||||
|
* hole in
|
||||||
|
* firewall
|
||||||
|
*/
|
||||||
|
PunchFWHole(rtsp_link);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"PacketAlias/RTSP: Cannot allocate RTSP data ports\n");
|
"PacketAlias/RTSP: Cannot allocate RTSP data ports\n");
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ealias = htons(base_alias + (RTSP_PORT_GROUP - 1));
|
ealias = htons(base_alias + (RTSP_PORT_GROUP - 1));
|
||||||
|
}
|
||||||
|
if (salias && rtsp_link) {
|
||||||
|
|
||||||
|
pkt_updated = 1;
|
||||||
|
|
||||||
|
/* Copy into IP packet */
|
||||||
|
sprintf(stemp, "%d", ntohs(salias));
|
||||||
|
memcpy(port_newdata, stemp, strlen(stemp));
|
||||||
|
port_newdata += strlen(stemp);
|
||||||
|
|
||||||
|
if (eport != 0) {
|
||||||
|
*port_newdata = '-';
|
||||||
|
port_newdata++;
|
||||||
|
|
||||||
|
/* Copy into IP packet */
|
||||||
|
sprintf(stemp, "%d", ntohs(ealias));
|
||||||
|
memcpy(port_newdata, stemp, strlen(stemp));
|
||||||
|
port_newdata += strlen(stemp);
|
||||||
|
}
|
||||||
|
*port_newdata = ';';
|
||||||
|
port_newdata++;
|
||||||
|
}
|
||||||
|
state++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (state > 3) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
port_data += i;
|
||||||
if (salias && rtsp_link) {
|
port_dlen -= i;
|
||||||
|
|
||||||
pkt_updated = 1;
|
|
||||||
|
|
||||||
/* Copy into IP packet */
|
|
||||||
sprintf(stemp, "%d", ntohs(salias));
|
|
||||||
memcpy(port_newdata, stemp, strlen(stemp));
|
|
||||||
port_newdata += strlen(stemp);
|
|
||||||
|
|
||||||
if (eport != 0) {
|
|
||||||
*port_newdata = '-';
|
|
||||||
port_newdata++;
|
|
||||||
|
|
||||||
/* Copy into IP packet */
|
|
||||||
sprintf(stemp, "%d", ntohs(ealias));
|
|
||||||
memcpy(port_newdata, stemp, strlen(stemp));
|
|
||||||
port_newdata += strlen(stemp);
|
|
||||||
}
|
|
||||||
|
|
||||||
*port_newdata = ';';
|
|
||||||
port_newdata++;
|
|
||||||
}
|
|
||||||
state++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (state > 3) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
port_data += i;
|
|
||||||
port_dlen -= i;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!pkt_updated)
|
if (!pkt_updated)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
memcpy (port_newdata, port_data, port_dlen);
|
memcpy(port_newdata, port_data, port_dlen);
|
||||||
port_newdata += port_dlen;
|
port_newdata += port_dlen;
|
||||||
*port_newdata = '\0';
|
*port_newdata = '\0';
|
||||||
|
|
||||||
/* Create new packet */
|
/* Create new packet */
|
||||||
new_dlen = port_newdata - newdata;
|
new_dlen = port_newdata - newdata;
|
||||||
memcpy (data, newdata, new_dlen);
|
memcpy(data, newdata, new_dlen);
|
||||||
|
|
||||||
SetAckModified(link);
|
SetAckModified(link);
|
||||||
delta = GetDeltaSeqOut(pip, link);
|
delta = GetDeltaSeqOut(pip, link);
|
||||||
AddSeq(pip, link, delta + new_dlen - dlen);
|
AddSeq(pip, link, delta + new_dlen - dlen);
|
||||||
|
|
||||||
new_len = htons(hlen + new_dlen);
|
new_len = htons(hlen + new_dlen);
|
||||||
DifferentialChecksum(&pip->ip_sum,
|
DifferentialChecksum(&pip->ip_sum,
|
||||||
&new_len,
|
&new_len,
|
||||||
&pip->ip_len,
|
&pip->ip_len,
|
||||||
1);
|
1);
|
||||||
pip->ip_len = new_len;
|
pip->ip_len = new_len;
|
||||||
|
|
||||||
tc->th_sum = 0;
|
tc->th_sum = 0;
|
||||||
tc->th_sum = TcpChecksum(pip);
|
tc->th_sum = TcpChecksum(pip);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Support the protocol used by early versions of RealPlayer */
|
/* Support the protocol used by early versions of RealPlayer */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
alias_pna_out(struct libalias *la, struct ip *pip,
|
alias_pna_out(struct libalias *la, struct ip *pip,
|
||||||
struct alias_link *link,
|
struct alias_link *link,
|
||||||
char *data,
|
char *data,
|
||||||
int dlen)
|
int dlen)
|
||||||
{
|
{
|
||||||
struct alias_link *pna_links;
|
struct alias_link *pna_links;
|
||||||
u_short msg_id, msg_len;
|
u_short msg_id, msg_len;
|
||||||
char *work;
|
char *work;
|
||||||
u_short alias_port, port;
|
u_short alias_port, port;
|
||||||
struct tcphdr *tc;
|
struct tcphdr *tc;
|
||||||
|
|
||||||
work = data;
|
work = data;
|
||||||
work += 5;
|
work += 5;
|
||||||
while (work + 4 < data + dlen) {
|
while (work + 4 < data + dlen) {
|
||||||
memcpy(&msg_id, work, 2);
|
memcpy(&msg_id, work, 2);
|
||||||
work += 2;
|
work += 2;
|
||||||
memcpy(&msg_len, work, 2);
|
memcpy(&msg_len, work, 2);
|
||||||
work += 2;
|
work += 2;
|
||||||
if (ntohs(msg_id) == 0) {
|
if (ntohs(msg_id) == 0) {
|
||||||
/* end of options */
|
/* end of options */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if ((ntohs(msg_id) == 1) || (ntohs(msg_id) == 7)) {
|
if ((ntohs(msg_id) == 1) || (ntohs(msg_id) == 7)) {
|
||||||
memcpy(&port, work, 2);
|
memcpy(&port, work, 2);
|
||||||
pna_links = FindUdpTcpOut(la, pip->ip_src, GetDestAddress(link),
|
pna_links = FindUdpTcpOut(la, pip->ip_src, GetDestAddress(link),
|
||||||
port, 0, IPPROTO_UDP, 1);
|
port, 0, IPPROTO_UDP, 1);
|
||||||
if (pna_links != NULL) {
|
if (pna_links != NULL) {
|
||||||
#ifndef NO_FW_PUNCH
|
#ifndef NO_FW_PUNCH
|
||||||
/* Punch hole in firewall */
|
/* Punch hole in firewall */
|
||||||
PunchFWHole(pna_links);
|
PunchFWHole(pna_links);
|
||||||
#endif
|
#endif
|
||||||
tc = (struct tcphdr *) ((char *) pip + (pip->ip_hl << 2));
|
tc = (struct tcphdr *)((char *)pip + (pip->ip_hl << 2));
|
||||||
alias_port = GetAliasPort(pna_links);
|
alias_port = GetAliasPort(pna_links);
|
||||||
memcpy(work, &alias_port, 2);
|
memcpy(work, &alias_port, 2);
|
||||||
|
|
||||||
/* Compute TCP checksum for revised packet */
|
/* Compute TCP checksum for revised packet */
|
||||||
tc->th_sum = 0;
|
tc->th_sum = 0;
|
||||||
tc->th_sum = TcpChecksum(pip);
|
tc->th_sum = TcpChecksum(pip);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
work += ntohs(msg_len);
|
||||||
}
|
}
|
||||||
work += ntohs(msg_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
AliasHandleRtspOut(struct libalias *la, struct ip *pip, struct alias_link *link, int maxpacketsize)
|
AliasHandleRtspOut(struct libalias *la, struct ip *pip, struct alias_link *link, int maxpacketsize)
|
||||||
{
|
{
|
||||||
int hlen, tlen, dlen;
|
int hlen, tlen, dlen;
|
||||||
struct tcphdr *tc;
|
struct tcphdr *tc;
|
||||||
char *data;
|
char *data;
|
||||||
const char *setup = "SETUP", *pna = "PNA", *str200 = "200";
|
const char *setup = "SETUP", *pna = "PNA", *str200 = "200";
|
||||||
const char *okstr = "OK", *client_port_str = "client_port";
|
const char *okstr = "OK", *client_port_str = "client_port";
|
||||||
const char *server_port_str = "server_port";
|
const char *server_port_str = "server_port";
|
||||||
int i, parseOk;
|
int i, parseOk;
|
||||||
|
|
||||||
tc = (struct tcphdr *)((char *)pip + (pip->ip_hl << 2));
|
tc = (struct tcphdr *)((char *)pip + (pip->ip_hl << 2));
|
||||||
hlen = (pip->ip_hl + tc->th_off) << 2;
|
hlen = (pip->ip_hl + tc->th_off) << 2;
|
||||||
tlen = ntohs(pip->ip_len);
|
tlen = ntohs(pip->ip_len);
|
||||||
dlen = tlen - hlen;
|
dlen = tlen - hlen;
|
||||||
|
|
||||||
data = (char*)pip;
|
data = (char *)pip;
|
||||||
data += hlen;
|
data += hlen;
|
||||||
|
|
||||||
/* When aliasing a client, check for the SETUP request */
|
/* When aliasing a client, check for the SETUP request */
|
||||||
if ((ntohs(tc->th_dport) == RTSP_CONTROL_PORT_NUMBER_1) ||
|
if ((ntohs(tc->th_dport) == RTSP_CONTROL_PORT_NUMBER_1) ||
|
||||||
(ntohs(tc->th_dport) == RTSP_CONTROL_PORT_NUMBER_2)) {
|
(ntohs(tc->th_dport) == RTSP_CONTROL_PORT_NUMBER_2)) {
|
||||||
|
|
||||||
if (dlen >= strlen(setup)) {
|
if (dlen >= strlen(setup)) {
|
||||||
if (memcmp(data, setup, strlen(setup)) == 0) {
|
if (memcmp(data, setup, strlen(setup)) == 0) {
|
||||||
alias_rtsp_out(la, pip, link, data, client_port_str);
|
alias_rtsp_out(la, pip, link, data, client_port_str);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dlen >= strlen(pna)) {
|
||||||
|
if (memcmp(data, pna, strlen(pna)) == 0) {
|
||||||
|
alias_pna_out(la, pip, link, data, dlen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When aliasing a server, check for the 200 reply
|
||||||
|
* Accomodate varying number of blanks between 200 & OK
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (dlen >= strlen(str200)) {
|
||||||
|
|
||||||
|
for (parseOk = 0, i = 0;
|
||||||
|
i <= dlen - strlen(str200);
|
||||||
|
i++) {
|
||||||
|
if (memcmp(&data[i], str200, strlen(str200)) == 0) {
|
||||||
|
parseOk = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (parseOk) {
|
||||||
|
|
||||||
|
i += strlen(str200); /* skip string found */
|
||||||
|
while (data[i] == ' ') /* skip blank(s) */
|
||||||
|
i++;
|
||||||
|
|
||||||
|
if ((dlen - i) >= strlen(okstr)) {
|
||||||
|
|
||||||
|
if (memcmp(&data[i], okstr, strlen(okstr)) == 0)
|
||||||
|
alias_rtsp_out(la, pip, link, data, server_port_str);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (dlen >= strlen(pna)) {
|
|
||||||
if (memcmp(data, pna, strlen(pna)) == 0) {
|
|
||||||
alias_pna_out(la, pip, link, data, dlen);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
/* When aliasing a server, check for the 200 reply
|
|
||||||
Accomodate varying number of blanks between 200 & OK */
|
|
||||||
|
|
||||||
if (dlen >= strlen(str200)) {
|
|
||||||
|
|
||||||
for (parseOk = 0, i = 0;
|
|
||||||
i <= dlen - strlen(str200);
|
|
||||||
i++) {
|
|
||||||
if (memcmp(&data[i], str200, strlen(str200)) == 0) {
|
|
||||||
parseOk = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (parseOk) {
|
|
||||||
|
|
||||||
i += strlen(str200); /* skip string found */
|
|
||||||
while(data[i] == ' ') /* skip blank(s) */
|
|
||||||
i++;
|
|
||||||
|
|
||||||
if ((dlen - i) >= strlen(okstr)) {
|
|
||||||
|
|
||||||
if (memcmp(&data[i], okstr, strlen(okstr)) == 0)
|
|
||||||
alias_rtsp_out(la, pip, link, data, server_port_str);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -61,110 +61,100 @@ purposes);
|
|||||||
#include "alias_local.h"
|
#include "alias_local.h"
|
||||||
|
|
||||||
u_short
|
u_short
|
||||||
LibAliasInternetChecksum(struct libalias *la, u_short *ptr, int nbytes)
|
LibAliasInternetChecksum(struct libalias *la, u_short * ptr, int nbytes)
|
||||||
{
|
{
|
||||||
int sum, oddbyte;
|
int sum, oddbyte;
|
||||||
|
|
||||||
sum = 0;
|
sum = 0;
|
||||||
while (nbytes > 1)
|
while (nbytes > 1) {
|
||||||
{
|
sum += *ptr++;
|
||||||
sum += *ptr++;
|
nbytes -= 2;
|
||||||
nbytes -= 2;
|
}
|
||||||
}
|
if (nbytes == 1) {
|
||||||
if (nbytes == 1)
|
oddbyte = 0;
|
||||||
{
|
((u_char *) & oddbyte)[0] = *(u_char *) ptr;
|
||||||
oddbyte = 0;
|
((u_char *) & oddbyte)[1] = 0;
|
||||||
((u_char *) &oddbyte)[0] = *(u_char *) ptr;
|
sum += oddbyte;
|
||||||
((u_char *) &oddbyte)[1] = 0;
|
}
|
||||||
sum += oddbyte;
|
sum = (sum >> 16) + (sum & 0xffff);
|
||||||
}
|
sum += (sum >> 16);
|
||||||
sum = (sum >> 16) + (sum & 0xffff);
|
return (~sum);
|
||||||
sum += (sum >> 16);
|
|
||||||
return(~sum);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u_short
|
u_short
|
||||||
IpChecksum(struct ip *pip)
|
IpChecksum(struct ip *pip)
|
||||||
{
|
{
|
||||||
return( PacketAliasInternetChecksum((u_short *) pip,
|
return (PacketAliasInternetChecksum((u_short *) pip,
|
||||||
(pip->ip_hl << 2)) );
|
(pip->ip_hl << 2)));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u_short
|
u_short
|
||||||
TcpChecksum(struct ip *pip)
|
TcpChecksum(struct ip *pip)
|
||||||
{
|
{
|
||||||
u_short *ptr;
|
u_short *ptr;
|
||||||
struct tcphdr *tc;
|
struct tcphdr *tc;
|
||||||
int nhdr, ntcp, nbytes;
|
int nhdr, ntcp, nbytes;
|
||||||
int sum, oddbyte;
|
int sum, oddbyte;
|
||||||
|
|
||||||
nhdr = pip->ip_hl << 2;
|
nhdr = pip->ip_hl << 2;
|
||||||
ntcp = ntohs(pip->ip_len) - nhdr;
|
ntcp = ntohs(pip->ip_len) - nhdr;
|
||||||
|
|
||||||
tc = (struct tcphdr *) ((char *) pip + nhdr);
|
tc = (struct tcphdr *)((char *)pip + nhdr);
|
||||||
ptr = (u_short *) tc;
|
ptr = (u_short *) tc;
|
||||||
|
|
||||||
/* Add up TCP header and data */
|
/* Add up TCP header and data */
|
||||||
nbytes = ntcp;
|
nbytes = ntcp;
|
||||||
sum = 0;
|
sum = 0;
|
||||||
while (nbytes > 1)
|
while (nbytes > 1) {
|
||||||
{
|
sum += *ptr++;
|
||||||
sum += *ptr++;
|
nbytes -= 2;
|
||||||
nbytes -= 2;
|
}
|
||||||
}
|
if (nbytes == 1) {
|
||||||
if (nbytes == 1)
|
oddbyte = 0;
|
||||||
{
|
((u_char *) & oddbyte)[0] = *(u_char *) ptr;
|
||||||
oddbyte = 0;
|
((u_char *) & oddbyte)[1] = 0;
|
||||||
((u_char *) &oddbyte)[0] = *(u_char *) ptr;
|
sum += oddbyte;
|
||||||
((u_char *) &oddbyte)[1] = 0;
|
}
|
||||||
sum += oddbyte;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* "Pseudo-header" data */
|
/* "Pseudo-header" data */
|
||||||
ptr = (u_short *) &(pip->ip_dst);
|
ptr = (u_short *) & (pip->ip_dst);
|
||||||
sum += *ptr++;
|
sum += *ptr++;
|
||||||
sum += *ptr;
|
sum += *ptr;
|
||||||
ptr = (u_short *) &(pip->ip_src);
|
ptr = (u_short *) & (pip->ip_src);
|
||||||
sum += *ptr++;
|
sum += *ptr++;
|
||||||
sum += *ptr;
|
sum += *ptr;
|
||||||
sum += htons((u_short) ntcp);
|
sum += htons((u_short) ntcp);
|
||||||
sum += htons((u_short) pip->ip_p);
|
sum += htons((u_short) pip->ip_p);
|
||||||
|
|
||||||
/* Roll over carry bits */
|
/* Roll over carry bits */
|
||||||
sum = (sum >> 16) + (sum & 0xffff);
|
sum = (sum >> 16) + (sum & 0xffff);
|
||||||
sum += (sum >> 16);
|
sum += (sum >> 16);
|
||||||
|
|
||||||
/* Return checksum */
|
/* Return checksum */
|
||||||
return((u_short) ~sum);
|
return ((u_short) ~ sum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
DifferentialChecksum(u_short *cksum, u_short *new, u_short *old, int n)
|
DifferentialChecksum(u_short * cksum, u_short * new, u_short * old, int n)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int accumulate;
|
int accumulate;
|
||||||
|
|
||||||
accumulate = *cksum;
|
accumulate = *cksum;
|
||||||
for (i=0; i<n; i++)
|
for (i = 0; i < n; i++) {
|
||||||
{
|
accumulate -= *new++;
|
||||||
accumulate -= *new++;
|
accumulate += *old++;
|
||||||
accumulate += *old++;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (accumulate < 0)
|
if (accumulate < 0) {
|
||||||
{
|
accumulate = -accumulate;
|
||||||
accumulate = -accumulate;
|
accumulate = (accumulate >> 16) + (accumulate & 0xffff);
|
||||||
accumulate = (accumulate >> 16) + (accumulate & 0xffff);
|
accumulate += accumulate >> 16;
|
||||||
accumulate += accumulate >> 16;
|
*cksum = (u_short) ~ accumulate;
|
||||||
*cksum = (u_short) ~accumulate;
|
} else {
|
||||||
}
|
accumulate = (accumulate >> 16) + (accumulate & 0xffff);
|
||||||
else
|
accumulate += accumulate >> 16;
|
||||||
{
|
*cksum = (u_short) accumulate;
|
||||||
accumulate = (accumulate >> 16) + (accumulate & 0xffff);
|
}
|
||||||
accumulate += accumulate >> 16;
|
|
||||||
*cksum = (u_short) accumulate;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user