aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-ipos.c
blob: f012738f572f5600c9be07b84bdc6f1c9b27c42f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
/* packet-ipos.c
 * Routines for IPOS dissection
 * Copyright 2015, Chuan He <chuan.he@ericsson.com>
 *                 Anders Broman <anders.broman@ericsson.com>
 *
 * Wireshark - Network traffic analyzer
 * By Gerald Combs <gerald@wireshark.org>
 * Copyright 1998 Gerald Combs
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

/*
 * This is a dissector for Ericsson IPOS Linux kernel packets' header
 * exchanged between kernel and linecard. All fields are in network byte order.
 * This header follow the Linux cooked-mode capture(SLL) and will call REDBACK
 * dissector.
 *
 * IPOS is the network operating system running on a few Ericsson platforms
 * including SSR 8000 routers, Router 6000 series, and SP routers.
 *
 * Product details for Ericsson's IP Metro and Backhaul routers using IPOS:
 * http://www.ericsson.com/ourportfolio/products/ip-metro-and-backhaul
 *
 */
#include "config.h"
#include <epan/packet.h>
#include <epan/expert.h>

void proto_reg_handoff_ipos(void);
void proto_register_ipos(void);

static dissector_handle_t ipos_handle;
static dissector_handle_t redback_handle;

static int proto_ipos = -1;
static int hf_ipos_protocol = -1;
static int hf_ipos_priority = -1;
static int hf_ipos_ppe = -1;
static int hf_ipos_slot = -1;
static gint ett_ipos = -1;

/* static expert_field ei_ipos_protocol = EI_INIT; */

#define LINUX_SLL_P_IPOS_NETIPC	 0x0030	/* IPOS IPC frames to/from AF_IPC module */
#define LINUX_SLL_P_IPOS_RBN     0x0031  /* IPOS IP frames to/from CTX module */
#define LINUX_SLL_P_IPOS_NETLINK 0x0032 /* IPOS data frames to/from AF_RBN_NETLINK module */
#define LINUX_SLL_P_IPOS_XCRP    0x0033 /* IPOS data frames to/from XCRP driver */
#define LINUX_SLL_P_IPOS_ISIS    0x0034 /* IPOS data frames to/from ISIS module */
#define LINUX_SLL_P_IPOS_PAKIO   0x0035 /* IPOS data frames to/from AF_RBN_PAKIO module */

static const value_string prototypenames[] = {
    { 0, "L2 Protocol" },
    { 1, "L3 Protocol" },
    { 2, "Control (IPC) message" },
    { 3, "ISIS packet" },
    { 4, "PAKIO packet" },
    { 0,  NULL }
};

static const value_string ppetypenames[] = {
    { 4,  "Output PPA" },
    { 6,  "Input PPA" },
    { 10, "SPPA" },
    { 0,   NULL }
};

/**
 *   Dissect a buffer containing IPOS kernel packet bit string.
 *
 *   @param tvb   The buffer to dissect.
 *   @param pinfo Packet Info.
 *   @param tree  The protocol tree.
 **/
static int
dissect_ipos(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
{
    proto_item	*ti = NULL;
    proto_tree	*ipos_tree = NULL;
    tvbuff_t	*next_tvb;
    int         offset = 0;

    col_set_str(pinfo->cinfo, COL_PROTOCOL, "IPOS");
    col_clear(pinfo->cinfo, COL_INFO);

    if (tree) {
        ti = proto_tree_add_item(tree, proto_ipos, tvb, 0, -1, ENC_NA);
        ipos_tree = proto_item_add_subtree(ti, ett_ipos);
        proto_tree_add_item(ipos_tree, hf_ipos_protocol, tvb, offset, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(ipos_tree, hf_ipos_priority, tvb, offset, 1, ENC_BIG_ENDIAN);
        offset += 1;
        proto_tree_add_item(ipos_tree, hf_ipos_ppe, tvb, offset, 1, ENC_BIG_ENDIAN);
        offset += 1;
        proto_tree_add_item(ipos_tree, hf_ipos_slot, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
    }

    if (redback_handle) {
        next_tvb = tvb_new_subset_remaining(tvb, offset);
        call_dissector(redback_handle, next_tvb, pinfo, tree);
    }

    return tvb_reported_length(tvb);
}

void
proto_register_ipos(void)
{
    static hf_register_info hf[] = {
        { &hf_ipos_protocol,
        { "Protocol", "ipos.proto", FT_UINT8, BASE_DEC, VALS(prototypenames), 0xF0,
        NULL, HFILL }},

        { &hf_ipos_priority,
        { "Priority", "ipos.priority", FT_UINT8, BASE_DEC, NULL, 0x0F,
        NULL, HFILL }},

        { &hf_ipos_ppe,
        { "Packet Processing Engine", "ipos.ppe", FT_UINT8, BASE_HEX, VALS(ppetypenames), 0x0,
        NULL, HFILL }},

        { &hf_ipos_slot,
        { "Destination (source) Slot", "ipos.slot", FT_UINT16, BASE_DEC, NULL, 0x0,
        NULL, HFILL }}
    };

    static gint *ett[] = {
        &ett_ipos
    };

#if 0
    static ei_register_info ei[] = {
        { &ei_ipos_protocol,
        { "ipos.protocol.unknown", PI_PROTOCOL, PI_WARN,
        "Unknown Protocol Data", EXPFILL }}
    };

    expert_module_t* expert_ipos;
#endif

    proto_ipos = proto_register_protocol("IPOS Kernel Packet Protocol", "IPOS", "ipos");
    proto_register_field_array(proto_ipos, hf, array_length(hf));
    proto_register_subtree_array(ett, array_length(ett));
#if 0
    expert_ipos = expert_register_protocol(proto_ipos);
    expert_register_field_array(expert_ipos, ei, array_length(ei));
#endif
    ipos_handle = register_dissector("ipos", dissect_ipos, proto_ipos);
}

void
proto_reg_handoff_ipos(void)
{
    redback_handle = find_dissector_add_dependency("redback", proto_ipos);

    /*dissector_add_uint("wtap_encap", WTAP_ENCAP_IPOS, ipos_handle); */
    dissector_add_uint("sll.ltype", LINUX_SLL_P_IPOS_NETIPC, ipos_handle);
    dissector_add_uint("sll.ltype", LINUX_SLL_P_IPOS_RBN, ipos_handle);
    dissector_add_uint("sll.ltype", LINUX_SLL_P_IPOS_NETLINK, ipos_handle);
    dissector_add_uint("sll.ltype", LINUX_SLL_P_IPOS_XCRP, ipos_handle);
    dissector_add_uint("sll.ltype", LINUX_SLL_P_IPOS_ISIS, ipos_handle);
    dissector_add_uint("sll.ltype", LINUX_SLL_P_IPOS_PAKIO, ipos_handle);
}

/*
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
 *
 * Local variables:
 * c-basic-offset: 4
 * tab-width: 8
 * indent-tabs-mode: nil
 * End:
 *
 * vi: set shiftwidth=4 tabstop=8 expandtab:
 * :indentSize=4:tabSize=8:noTabs=true:
 */