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:
Dag-Erling Smørgrav 2004-03-16 21:30:41 +00:00
parent f02660b050
commit f0f93429cf
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=127094
28 changed files with 9898 additions and 10066 deletions

File diff suppressed because it is too large Load Diff

View File

@ -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 */

View File

@ -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

View File

@ -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
} }
} }

View File

@ -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:

View File

@ -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_ */

View File

@ -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);
} }

View File

@ -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)
{ {

View File

@ -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

View File

@ -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);
}
} }

View File

@ -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);
}
}
}
}
} }

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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
} }
} }

View File

@ -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:

View File

@ -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_ */

View File

@ -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);
} }

View File

@ -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)
{ {

View File

@ -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

View File

@ -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);
}
} }

View File

@ -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);
}
}
}
}
} }

View File

@ -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;
}
} }