1193323Sed/*
2193323Sed * Copyright (c) 1998-2004  Hannes Gredler <hannes@gredler.at>
3193323Sed *      The TCPDUMP project
4193323Sed *
5193323Sed * Redistribution and use in source and binary forms, with or without
6193323Sed * modification, are permitted provided that: (1) source code
7193323Sed * distributions retain the above copyright notice and this paragraph
8193323Sed * in its entirety, and (2) distributions including binary code include
9193323Sed * the above copyright notice and this paragraph in its entirety in
10193323Sed * the documentation or other materials provided with the distribution.
11193323Sed * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
12193323Sed * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
13193323Sed * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
14193323Sed * FOR A PARTICULAR PURPOSE.
15193323Sed */
16193323Sed
17193323Sed/* \summary: Syslog protocol printer */
18193323Sed/* specification: RFC 3164 (not RFC 5424) */
19218893Sdim
20193323Sed#ifdef HAVE_CONFIG_H
21193323Sed#include <config.h>
22193323Sed#endif
23193323Sed
24193323Sed#include "netdissect-stdinc.h"
25193323Sed
26193323Sed#include "netdissect.h"
27193323Sed#include "extract.h"
28193323Sed
29193323Sed
30193323Sed/*
31193323Sed * tokenlists and #defines taken from Ethereal - Network traffic analyzer
32193323Sed * by Gerald Combs <gerald@ethereal.com>
33193323Sed */
34193323Sed
35193323Sed#define SYSLOG_SEVERITY_MASK 0x0007  /* 0000 0000 0000 0111 */
36193323Sed#define SYSLOG_FACILITY_MASK 0x03f8  /* 0000 0011 1111 1000 */
37193323Sed#define SYSLOG_MAX_DIGITS 3 /* The maximum number of priority digits to read in. */
38193323Sed
39218893Sdimstatic const struct tok syslog_severity_values[] = {
40193323Sed  { 0,      "emergency" },
41193323Sed  { 1,      "alert" },
42193323Sed  { 2,      "critical" },
43193323Sed  { 3,      "error" },
44193323Sed  { 4,      "warning" },
45193323Sed  { 5,      "notice" },
46218893Sdim  { 6,      "info" },
47193323Sed  { 7,      "debug" },
48193323Sed  { 0, NULL },
49234353Sdim};
50193323Sed
51193323Sedstatic const struct tok syslog_facility_values[] = {
52193323Sed  { 0,     "kernel" },
53193323Sed  { 1,     "user" },
54193323Sed  { 2,     "mail" },
55193323Sed  { 3,     "daemon" },
56193323Sed  { 4,     "auth" },
57193323Sed  { 5,     "syslog" },
58193323Sed  { 6,     "lpr" },
59193323Sed  { 7,     "news" },
60193323Sed  { 8,     "uucp" },
61193323Sed  { 9,     "cron" },
62193323Sed  { 10,    "authpriv" },
63193323Sed  { 11,    "ftp" },
64193323Sed  { 12,    "ntp" },
65193323Sed  { 13,    "security" },
66193323Sed  { 14,    "console" },
67193323Sed  { 15,    "cron" },
68218893Sdim  { 16,    "local0" },
69193323Sed  { 17,    "local1" },
70193323Sed  { 18,    "local2" },
71193323Sed  { 19,    "local3" },
72208599Srdivacky  { 20,    "local4" },
73193323Sed  { 21,    "local5" },
74193323Sed  { 22,    "local6" },
75193323Sed  { 23,    "local7" },
76193323Sed  { 0, NULL },
77198892Srdivacky};
78193323Sed
79193323Sedvoid
80198892Srdivackysyslog_print(netdissect_options *ndo,
81193323Sed             const u_char *pptr, u_int len)
82218893Sdim{
83208599Srdivacky    uint16_t msg_off = 0;
84193323Sed    uint16_t pri = 0;
85193323Sed    uint16_t facility,severity;
86193323Sed
87234353Sdim    ndo->ndo_protocol = "syslog";
88193323Sed    /* extract decimal figures that are
89193323Sed     * encapsulated within < > tags
90193323Sed     * based on this decimal figure extract the
91234353Sdim     * severity and facility values
92193323Sed     */
93198892Srdivacky
94193323Sed    if (GET_U_1(pptr) != '<')
95198892Srdivacky        goto invalid;
96193323Sed    msg_off++;
97193323Sed
98193323Sed    while (msg_off <= SYSLOG_MAX_DIGITS &&
99193323Sed           GET_U_1(pptr + msg_off) >= '0' &&
100193323Sed           GET_U_1(pptr + msg_off) <= '9') {
101193323Sed        pri = pri * 10 + (GET_U_1(pptr + msg_off) - '0');
102193323Sed        msg_off++;
103193323Sed    }
104193323Sed
105193323Sed    if (GET_U_1(pptr + msg_off) != '>')
106218893Sdim        goto invalid;
107193323Sed    msg_off++;
108193323Sed
109218893Sdim    facility = (pri & SYSLOG_FACILITY_MASK) >> 3;
110193323Sed    severity = pri & SYSLOG_SEVERITY_MASK;
111193323Sed
112193323Sed    if (ndo->ndo_vflag < 1 )
113193323Sed    {
114193323Sed        ND_PRINT("SYSLOG %s.%s, length: %u",
115193323Sed               tok2str(syslog_facility_values, "unknown (%u)", facility),
116193323Sed               tok2str(syslog_severity_values, "unknown (%u)", severity),
117193323Sed               len);
118208599Srdivacky        return;
119208599Srdivacky    }
120208599Srdivacky
121208599Srdivacky    ND_PRINT("SYSLOG, length: %u\n\tFacility %s (%u), Severity %s (%u)\n\tMsg: ",
122210299Sed           len,
123208599Srdivacky           tok2str(syslog_facility_values, "unknown (%u)", facility),
124208599Srdivacky           facility,
125208599Srdivacky           tok2str(syslog_severity_values, "unknown (%u)", severity),
126208599Srdivacky           severity);
127208599Srdivacky
128208599Srdivacky    /* print the syslog text in verbose mode */
129208599Srdivacky    /*
130208599Srdivacky     * RFC 3164 Section 4.1.3: "There is no ending delimiter to this part.
131208599Srdivacky     * The MSG part of the syslog packet MUST contain visible (printing)
132208599Srdivacky     * characters."
133208599Srdivacky     *
134208599Srdivacky     * RFC 5424 Section 8.2: "This document does not impose any mandatory
135208599Srdivacky     * restrictions on the MSG or PARAM-VALUE content.  As such, they MAY
136208599Srdivacky     * contain control characters, including the NUL character."
137208599Srdivacky     *
138208599Srdivacky     * Hence, to aid in protocol debugging, print the full MSG without
139208599Srdivacky     * beautification to make it clear what was transmitted on the wire.
140218893Sdim     */
141218893Sdim    if (len > msg_off)
142218893Sdim        (void)nd_printn(ndo, pptr + msg_off, len - msg_off, NULL);
143218893Sdim
144218893Sdim    if (ndo->ndo_vflag > 1)
145218893Sdim        print_unknown_data(ndo, pptr, "\n\t", len);
146218893Sdim    return;
147218893Sdim
148218893Sdiminvalid:
149218893Sdim    nd_print_invalid(ndo);
150218893Sdim}
151218893Sdim