blob: 27b1078afda94e216201c0f23a5484ff31f9b8d5 [file] [log] [blame] [raw]
/*
decode.c
Copyright (c) 2000 Dug Song <dugsong@monkey.org>
$Id: decode.c,v 1.12 2000/12/15 20:03:26 dugsong Exp $
*/
#include "config.h"
#include <sys/types.h>
#include <arpa/telnet.h>
#include <rpc/rpc.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "decode.h"
extern int decode_hex(u_char *, int, u_char *, int);
extern int decode_ftp(u_char *, int, u_char *, int);
extern int decode_telnet(u_char *, int, u_char *, int);
extern int decode_smtp(u_char *, int, u_char *, int);
extern int decode_pptp(u_char *, int, u_char *, int);
extern int decode_http(u_char *, int, u_char *, int);
extern int decode_ospf(u_char *, int, u_char *, int);
extern int decode_poppass(u_char *, int, u_char *, int);
extern int decode_pop(u_char *, int, u_char *, int);
extern int decode_nntp(u_char *, int, u_char *, int);
extern int decode_smb(u_char *, int, u_char *, int);
extern int decode_imap(u_char *, int, u_char *, int);
extern int decode_snmp(u_char *, int, u_char *, int);
extern int decode_ldap(u_char *, int, u_char *, int);
extern int decode_mmxp(u_char *, int, u_char *, int);
extern int decode_rlogin(u_char *, int, u_char *, int);
extern int decode_rip(u_char *, int, u_char *, int);
extern int decode_socks(u_char *, int, u_char *, int);
extern int decode_citrix(u_char *, int, u_char *, int);
extern int decode_oracle(u_char *, int, u_char *, int);
extern int decode_tds(u_char *, int, u_char *, int);
extern int decode_sniffer(u_char *, int, u_char *, int);
extern int decode_cvs(u_char *, int, u_char *, int);
extern int decode_icq(u_char *, int, u_char *, int);
extern int decode_napster(u_char *, int, u_char *, int);
extern int decode_aim(u_char *, int, u_char *, int);
extern int decode_postgresql(u_char *, int, u_char *, int);
extern int decode_pcanywhere(u_char *, int, u_char *, int);
extern int decode_x11(u_char *, int, u_char *, int);
extern int decode_irc(u_char *, int, u_char *, int);
extern int decode_portmap(u_char *, int, u_char *, int);
extern int decode_mountd(u_char *, int, u_char *, int);
extern int decode_vrrp(u_char *, int, u_char *, int);
extern int decode_ypserv(u_char *, int, u_char *, int);
extern int decode_yppasswd(u_char *, int, u_char *, int);
static struct decode decodes[] = {
{ "hex", decode_hex },
{ "ftp", decode_ftp },
{ "telnet", decode_telnet },
{ "smtp", decode_smtp },
{ "pptp", decode_pptp },
{ "http", decode_http },
{ "ospf", decode_ospf },
{ "poppass", decode_poppass },
{ "pop", decode_pop },
{ "nntp", decode_nntp },
{ "smb", decode_smb },
{ "imap", decode_imap },
{ "snmp", decode_snmp },
{ "ldap", decode_ldap },
{ "mmxp", decode_mmxp },
{ "rlogin", decode_rlogin },
{ "rip", decode_rip },
{ "socks", decode_socks },
{ "citrix", decode_citrix },
{ "oracle", decode_oracle },
{ "tds", decode_tds },
{ "sniffer", decode_sniffer },
{ "cvs", decode_cvs },
{ "icq", decode_icq },
{ "napster", decode_napster },
{ "aim", decode_aim },
{ "postgresql", decode_postgresql },
{ "pcanywhere", decode_pcanywhere },
{ "vrrp", decode_vrrp },
{ "x11", decode_x11 },
{ "irc", decode_irc },
{ "portmap", decode_portmap },
{ "mountd", decode_mountd },
{ "ypserv", decode_ypserv },
{ "yppasswd", decode_yppasswd },
{ NULL }
};
struct decode *
getdecodebyname(const char *name)
{
struct decode *dc;
for (dc = decodes; dc->dc_name != NULL; dc++) {
if (strcasecmp(dc->dc_name, name) == 0)
return (dc);
}
return (NULL);
}
/* Strip telnet options, as well as suboption data. */
int
strip_telopts(u_char *buf, int len)
{
int i, j, subopt = 0;
char *p, *q;
for (i = j = 0; i < len; i++) {
if (buf[i] == IAC) {
if (++i >= len) break;
else if (buf[i] > SB)
i++;
else if (buf[i] == SB) {
/* XXX - check for autologin username. */
p = buf + i + 1;
if ((q = bufbuf(p, len - i, "\xff", 1))
!= NULL) {
if ((p = bufbuf(p, q - p, "USER\x01",
5)) != NULL) {
p += 5;
buf[j++] = '[';
memcpy(buf + j, p, q - p);
j += q - p;
buf[j++] = ']';
buf[j++] = '\n';
}
}
subopt = 1;
}
else if (buf[i] == SE) {
if (!subopt) j = 0;
subopt = 0;
}
}
else if (!subopt) {
/* XXX - convert isolated returns to newlines. */
if (buf[i] == '\r' && i + 1 < len &&
buf[i + 1] != '\n')
buf[j++] = '\n';
/* XXX - strip binary nulls. */
else if (buf[i] != '\0')
buf[j++] = buf[i];
}
}
buf[j] = '\0';
return (j);
}
/* Strip a string buffer down to a maximum number of lines. */
int
strip_lines(char *buf, int max_lines)
{
char *p;
int lines, nonascii;
if (!buf) return (0);
lines = nonascii = 0;
for (p = buf; *p && lines < max_lines; p++) {
if (*p == '\n') lines++;
if (!isascii(*p)) nonascii++;
}
if (*p) *p = '\0';
/* XXX - lame ciphertext heuristic */
if (nonascii * 3 > p - buf)
return (0);
return (lines);
}
int
is_ascii_string(char *buf, int len)
{
int i;
for (i = 0; i < len; i++)
if (!isascii(buf[i])) return (0);
return (1);
}
u_char *
bufbuf(u_char *big, int blen, u_char *little, int llen)
{
u_char *p;
for (p = big; p <= big + blen - llen; p++) {
if (memcmp(p, little, llen) == 0)
return (p);
}
return (NULL);
}