Coverage Report

Created: 2026-11-12 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-pagp.c
Line
Count
Source
1
/* packet-pagp.c
2
 * Routines for PAgP (Port Aggregation Protocol - aka FEC) dissection
3
 * Original Author Mark C. Brown <mbrown@hp.com>
4
 * Copyright (C) 2004 Hewlett-Packard Development Company, L.P.
5
 *
6
 * Wireshark - Network traffic analyzer
7
 * By Gerald Combs <gerald@wireshark.org>
8
 * Copyright 1998 Gerald Combs
9
 *
10
 * Copied from packet-slowprotocols.c
11
 *
12
 * SPDX-License-Identifier: GPL-2.0-or-later
13
 */
14
15
#include "config.h"
16
17
#include <epan/packet.h>
18
#include <epan/expert.h>
19
#include <epan/to_str.h>
20
#include <epan/tfs.h>
21
#include <wsutil/array.h>
22
#include "packet-cisco-pid.h"
23
24
void proto_register_pagp(void);
25
void proto_reg_handoff_pagp(void);
26
27
static dissector_handle_t pagp_handle;
28
29
/* Offsets of fields within a PagP PDU */
30
31
0
#define PAGP_VERSION_NUMBER              0
32
33
0
#define PAGP_FLAGS                       1
34
0
#define PAGP_LOCAL_DEVICE_ID             2
35
0
#define PAGP_LOCAL_LEARN_CAP             8
36
0
#define PAGP_LOCAL_PORT_PRIORITY         9
37
0
#define PAGP_LOCAL_SENT_PORT_IFINDEX    10
38
0
#define PAGP_LOCAL_GROUP_CAPABILITY     14
39
0
#define PAGP_LOCAL_GROUP_IFINDEX        18
40
0
#define PAGP_PARTNER_DEVICE_ID          22
41
0
#define PAGP_PARTNER_LEARN_CAP          28
42
0
#define PAGP_PARTNER_PORT_PRIORITY      29
43
0
#define PAGP_PARTNER_SENT_PORT_IFINDEX  30
44
0
#define PAGP_PARTNER_GROUP_CAPABILITY   34
45
0
#define PAGP_PARTNER_GROUP_IFINDEX      38
46
0
#define PAGP_PARTNER_COUNT              42
47
0
#define PAGP_NUM_TLVS                   44
48
0
#define PAGP_FIRST_TLV                  46
49
50
0
#define PAGP_FLUSH_LOCAL_DEVICE_ID       2
51
0
#define PAGP_FLUSH_PARTNER_DEVICE_ID     8
52
0
#define PAGP_FLUSH_TRANSACTION_ID       14
53
54
/* PDU Versions */
55
56
#define PAGP_INFO_PDU                    1
57
0
#define PAGP_FLUSH_PDU                   2
58
59
/* Flag bits */
60
61
16
#define PAGP_FLAGS_SLOW_HELLO           0x01
62
16
#define PAGP_FLAGS_AUTO_MODE            0x02
63
16
#define PAGP_FLAGS_CONSISTENT_STATE     0x04
64
65
/* TLV Types */
66
67
68
0
#define PAGP_TLV_DEVICE_NAME             1
69
0
#define PAGP_TLV_PORT_NAME               2
70
0
#define PAGP_TLV_AGPORT_MAC              3
71
0
#define PAGP_TLV_RESERVED                4
72
73
/* Initialise the protocol and registered fields */
74
75
static int proto_pagp;
76
77
static int hf_pagp_version_number;
78
79
static int hf_pagp_flags;
80
static int hf_pagp_flags_slow_hello;
81
static int hf_pagp_flags_auto_mode;
82
static int hf_pagp_flags_consistent_state;
83
static int hf_pagp_local_device_id;
84
static int hf_pagp_local_learn_cap;
85
static int hf_pagp_local_port_priority;
86
static int hf_pagp_local_sent_port_ifindex;
87
static int hf_pagp_local_group_capability;
88
static int hf_pagp_local_group_ifindex;
89
static int hf_pagp_partner_device_id;
90
static int hf_pagp_partner_learn_cap;
91
static int hf_pagp_partner_port_priority;
92
static int hf_pagp_partner_sent_port_ifindex;
93
static int hf_pagp_partner_group_capability;
94
static int hf_pagp_partner_group_ifindex;
95
static int hf_pagp_partner_count;
96
static int hf_pagp_num_tlvs;
97
static int hf_pagp_tlv;
98
static int hf_pagp_tlv_length;
99
static int hf_pagp_tlv_device_name;
100
static int hf_pagp_tlv_port_name;
101
static int hf_pagp_tlv_agport_mac;
102
103
static int hf_pagp_flush_local_device_id;
104
static int hf_pagp_flush_partner_device_id;
105
static int hf_pagp_flush_transaction_id;
106
107
/* Initialise the subtree pointers */
108
109
static int ett_pagp;
110
static int ett_pagp_flags;
111
static int ett_pagp_tlvs;
112
113
static expert_field ei_pagp_tlv_length;
114
115
/* General declarations and macros */
116
117
static const value_string pdu_vers[] = {
118
    { 1, "Info PDU" },
119
    { 2, "Flush PDU" },
120
    { 0, NULL }
121
};
122
123
static const value_string learn_cap[] = {
124
    { 1, "Source-based Distribution" },
125
    { 2, "Arbitrary Distribution" },
126
    { 0, NULL }
127
};
128
129
static const value_string tlv_types[] = {
130
    { 1, "Device Name TLV" },
131
    { 2, "Physical Port Name TLV" },
132
    { 3, "Agport MAC Address" },
133
    { 4, "Reserved" },
134
    { 0, NULL }
135
};
136
137
static const true_false_string automode = {
138
    "Yes",
139
    "Desirable Mode"
140
};
141
142
/* Code to actually dissect the PAGP packets */
143
static int
144
dissect_pagp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
145
0
{
146
0
    uint32_t raw_word;
147
0
    uint16_t num_tlvs;
148
0
    uint16_t tlv;
149
0
    uint16_t len;
150
0
    uint16_t ii;
151
0
    uint16_t offset = PAGP_FIRST_TLV;
152
0
    uint8_t raw_octet;
153
154
0
    uint8_t flags;
155
156
0
    proto_tree *pagp_tree = NULL;
157
0
    proto_item *pagp_item, *len_item;
158
0
    proto_tree *tlv_tree;
159
0
    static int * const pagp_flags[] = {
160
0
        &hf_pagp_flags_slow_hello,
161
0
        &hf_pagp_flags_auto_mode,
162
0
        &hf_pagp_flags_consistent_state,
163
0
        NULL,
164
0
    };
165
166
167
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "PAGP"); /* PAGP Protocol */
168
169
0
    col_clear(pinfo->cinfo, COL_INFO);
170
171
0
    raw_octet = tvb_get_uint8(tvb, PAGP_VERSION_NUMBER);
172
0
    if (tree) {
173
0
        pagp_item = proto_tree_add_protocol_format(tree, proto_pagp, tvb,
174
0
                                                   0, -1, "Port Aggregation Protocol");
175
0
        pagp_tree = proto_item_add_subtree(pagp_item, ett_pagp);
176
0
        proto_tree_add_uint(pagp_tree, hf_pagp_version_number, tvb,
177
0
                            PAGP_VERSION_NUMBER, 1, raw_octet);
178
0
    }
179
0
    col_append_str(pinfo->cinfo, COL_INFO,
180
0
                   val_to_str_const(raw_octet, pdu_vers, "Unknown PDU version"));
181
182
0
    if (raw_octet == PAGP_FLUSH_PDU) {
183
184
0
        col_append_fstr(pinfo->cinfo, COL_INFO, "; Local DevID: %s",
185
0
                        tvb_ether_to_str(pinfo->pool, tvb, PAGP_FLUSH_LOCAL_DEVICE_ID));
186
187
0
        proto_tree_add_item(pagp_tree, hf_pagp_flush_local_device_id, tvb,
188
0
                            PAGP_FLUSH_LOCAL_DEVICE_ID, 6, ENC_NA);
189
190
0
        col_append_fstr(pinfo->cinfo, COL_INFO, ", Partner DevID: %s",
191
0
                        tvb_ether_to_str(pinfo->pool, tvb, PAGP_FLUSH_PARTNER_DEVICE_ID));
192
193
0
        proto_tree_add_item(pagp_tree, hf_pagp_flush_partner_device_id, tvb,
194
0
                            PAGP_FLUSH_PARTNER_DEVICE_ID, 6, ENC_NA);
195
196
0
        raw_word = tvb_get_ntohl(tvb, PAGP_FLUSH_TRANSACTION_ID);
197
0
        col_append_fstr(pinfo->cinfo, COL_INFO, "; Transaction ID: 0x%x ", raw_word);
198
199
0
        proto_tree_add_uint(pagp_tree, hf_pagp_flush_transaction_id, tvb,
200
0
                            PAGP_FLUSH_TRANSACTION_ID, 4, raw_word);
201
0
        return tvb_captured_length(tvb);
202
0
    }
203
204
    /* Info PDU */
205
206
0
    flags = tvb_get_uint8(tvb, PAGP_FLAGS);
207
0
    col_append_fstr(pinfo->cinfo, COL_INFO, "; Flags 0x%x", flags);
208
209
0
    proto_tree_add_bitmask(pagp_tree, tvb, PAGP_FLAGS, hf_pagp_flags, ett_pagp_flags, pagp_flags, ENC_NA);
210
211
0
    col_append_fstr(pinfo->cinfo, COL_INFO, "; Local DevID: %s",
212
0
                    tvb_ether_to_str(pinfo->pool, tvb, PAGP_LOCAL_DEVICE_ID));
213
214
0
    proto_tree_add_item(pagp_tree, hf_pagp_local_device_id, tvb,
215
0
                        PAGP_LOCAL_DEVICE_ID, 6, ENC_NA);
216
217
0
    if (tree) {
218
0
        proto_tree_add_item(pagp_tree, hf_pagp_local_learn_cap, tvb,
219
0
                            PAGP_LOCAL_LEARN_CAP, 1, ENC_NA);
220
221
0
        proto_tree_add_item(pagp_tree, hf_pagp_local_port_priority, tvb,
222
0
                            PAGP_LOCAL_PORT_PRIORITY, 1, ENC_NA);
223
224
0
        proto_tree_add_item(pagp_tree, hf_pagp_local_sent_port_ifindex, tvb,
225
0
                            PAGP_LOCAL_SENT_PORT_IFINDEX, 4, ENC_BIG_ENDIAN);
226
227
0
        proto_tree_add_item(pagp_tree, hf_pagp_local_group_capability, tvb,
228
0
                            PAGP_LOCAL_GROUP_CAPABILITY, 4, ENC_BIG_ENDIAN);
229
230
0
        proto_tree_add_item(pagp_tree, hf_pagp_local_group_ifindex, tvb,
231
0
                            PAGP_LOCAL_GROUP_IFINDEX, 4, ENC_BIG_ENDIAN);
232
0
    }
233
234
0
    col_append_fstr(pinfo->cinfo, COL_INFO, ", Partner DevID: %s",
235
0
                    tvb_ether_to_str(pinfo->pool, tvb, PAGP_PARTNER_DEVICE_ID));
236
237
0
    proto_tree_add_item(pagp_tree, hf_pagp_partner_device_id, tvb,
238
0
                        PAGP_PARTNER_DEVICE_ID, 6, ENC_NA);
239
240
0
    proto_tree_add_item(pagp_tree, hf_pagp_partner_learn_cap, tvb,
241
0
                        PAGP_PARTNER_LEARN_CAP, 1, ENC_NA);
242
243
0
    proto_tree_add_item(pagp_tree, hf_pagp_partner_port_priority, tvb,
244
0
                        PAGP_PARTNER_PORT_PRIORITY, 1, ENC_NA);
245
246
0
    proto_tree_add_item(pagp_tree, hf_pagp_partner_sent_port_ifindex, tvb,
247
0
                        PAGP_PARTNER_SENT_PORT_IFINDEX, 4, ENC_BIG_ENDIAN);
248
249
0
    proto_tree_add_item(pagp_tree, hf_pagp_partner_group_capability, tvb,
250
0
                        PAGP_PARTNER_GROUP_CAPABILITY, 4, ENC_BIG_ENDIAN);
251
252
0
    proto_tree_add_item(pagp_tree, hf_pagp_partner_group_ifindex, tvb,
253
0
                        PAGP_PARTNER_GROUP_IFINDEX, 4, ENC_BIG_ENDIAN);
254
255
0
    proto_tree_add_item(pagp_tree, hf_pagp_partner_count, tvb,
256
0
                        PAGP_PARTNER_COUNT, 2, ENC_BIG_ENDIAN);
257
258
0
    num_tlvs = tvb_get_ntohs(tvb, PAGP_NUM_TLVS);
259
0
    proto_tree_add_uint(pagp_tree, hf_pagp_num_tlvs, tvb,
260
0
                        PAGP_NUM_TLVS, 2, num_tlvs);
261
262
    /* dump TLV entries */
263
264
0
    for ( ii = 0; ii < num_tlvs; ii++ ) {
265
266
0
        tlv = tvb_get_ntohs(tvb, offset);
267
0
        len = tvb_get_ntohs(tvb, offset + 2);
268
269
0
        tlv_tree = proto_tree_add_subtree_format(pagp_tree, tvb, offset, len,
270
0
                                                 ett_pagp_tlvs, NULL, "TLV Entry #%d", ii+1);
271
272
0
        proto_tree_add_uint(tlv_tree, hf_pagp_tlv, tvb, offset, 2, tlv);
273
0
        len_item = proto_tree_add_uint(tlv_tree, hf_pagp_tlv_length, tvb, offset+2, 2, len);
274
0
        if ( len == 0 ) {
275
0
            expert_add_info_format(pinfo, len_item, &ei_pagp_tlv_length,
276
0
                                   "Unknown data - TLV len=0");
277
0
            return offset;
278
0
        }
279
0
        if ( len < 4 ) {
280
0
            expert_add_info_format(pinfo, len_item, &ei_pagp_tlv_length,
281
0
                                   "TLV length too small (< 4)");
282
0
            return offset;
283
0
        }
284
0
        if ( tvb_reported_length_remaining(tvb, offset) < len ) {
285
0
            expert_add_info_format(pinfo, len_item, &ei_pagp_tlv_length,
286
0
                                   "TLV length too large");
287
0
            return offset;
288
0
        }
289
290
0
        switch (tlv) {
291
0
            case PAGP_TLV_DEVICE_NAME:
292
0
                proto_tree_add_item(tlv_tree, hf_pagp_tlv_device_name,
293
0
                                    tvb, offset+4, len-4, ENC_ASCII);
294
0
                break;
295
0
            case PAGP_TLV_PORT_NAME:
296
0
                proto_tree_add_item(tlv_tree, hf_pagp_tlv_port_name,
297
0
                                    tvb, offset+4, len-4, ENC_ASCII);
298
0
                break;
299
0
            case PAGP_TLV_AGPORT_MAC:
300
0
                proto_tree_add_item(tlv_tree, hf_pagp_tlv_agport_mac,
301
0
                                    tvb, offset+4, 6, ENC_NA);
302
0
                break;
303
0
            case PAGP_TLV_RESERVED:
304
0
                break;
305
0
        }
306
307
0
        offset += len;
308
309
0
    }
310
0
    return tvb_captured_length(tvb);
311
0
}
312
313
314
/* Register the protocol with Wireshark */
315
316
void
317
proto_register_pagp(void)
318
16
{
319
/* Setup list of header fields */
320
321
16
    static hf_register_info hf[] = {
322
323
16
        { &hf_pagp_version_number,
324
16
          { "Version",              "pagp.version",
325
16
            FT_UINT8,       BASE_HEX,       VALS(pdu_vers), 0x0,
326
16
            "Identifies the PAgP PDU version: 1 = Info, 2 = Flush", HFILL }},
327
328
16
        { &hf_pagp_flags,
329
16
          { "Flags",                "pagp.flags",
330
16
            FT_UINT8,       BASE_HEX,       NULL,   0x0,
331
16
            "Information flags", HFILL }},
332
333
16
        { &hf_pagp_flags_slow_hello,
334
16
          { "Slow Hello",           "pagp.flags.slowhello",
335
16
            FT_BOOLEAN,     8,      TFS(&tfs_yes_no), PAGP_FLAGS_SLOW_HELLO,
336
16
            "1 = using Slow Hello, 0 = Slow Hello disabled", HFILL }},
337
338
16
        { &hf_pagp_flags_auto_mode,
339
16
          { "Auto Mode",            "pagp.flags.automode",
340
16
            FT_BOOLEAN,     8,      TFS(&automode), PAGP_FLAGS_AUTO_MODE,
341
16
            "1 = Auto Mode enabled, 0 = Desirable Mode", HFILL }},
342
343
16
        { &hf_pagp_flags_consistent_state,
344
16
          { "Consistent State",     "pagp.flags.state",
345
16
            FT_BOOLEAN,     8,      NULL,   PAGP_FLAGS_CONSISTENT_STATE,
346
16
            "1 = Consistent State, 0 = Not Ready", HFILL }},
347
348
16
        { &hf_pagp_local_device_id,
349
16
          { "Local Device ID",      "pagp.localdevid",
350
16
            FT_ETHER,       BASE_NONE,      NULL,   0x0,
351
16
            NULL, HFILL }},
352
353
16
        { &hf_pagp_local_learn_cap,
354
16
          { "Local Learn Capability",       "pagp.localearncap",
355
16
            FT_UINT8,       BASE_HEX,       VALS(learn_cap),        0x0,
356
16
            NULL, HFILL }},
357
358
16
        { &hf_pagp_local_port_priority,
359
16
          { "Local Port Hot Standby Priority",      "pagp.localportpri",
360
16
            FT_UINT8,       BASE_DEC,       NULL,   0x0,
361
16
            "The local hot standby priority assigned to this port", HFILL }},
362
363
16
        { &hf_pagp_local_sent_port_ifindex,
364
16
          { "Local Sent Port ifindex",      "pagp.localsentportifindex",
365
16
            FT_UINT32,      BASE_DEC,       NULL,   0x0,
366
16
            "The interface index of the local port used to send PDU", HFILL }},
367
368
16
        { &hf_pagp_local_group_capability,
369
16
          { "Local Group Capability",       "pagp.localgroupcap",
370
16
            FT_UINT32,      BASE_HEX,       NULL,   0x0,
371
16
            "The local group capability", HFILL }},
372
373
16
        { &hf_pagp_local_group_ifindex,
374
16
          { "Local Group ifindex",          "pagp.localgroupifindex",
375
16
            FT_UINT32,      BASE_DEC,       NULL,   0x0,
376
16
            "The local group interface index", HFILL }},
377
378
16
        { &hf_pagp_partner_device_id,
379
16
          { "Partner Device ID",            "pagp.partnerdevid",
380
16
            FT_ETHER,       BASE_NONE,      NULL,   0x0,
381
16
            "Remote Device ID (MAC)", HFILL }},
382
383
16
        { &hf_pagp_partner_learn_cap,
384
16
          { "Partner Learn Capability",     "pagp.partnerlearncap",
385
16
            FT_UINT8,       BASE_HEX,       VALS(learn_cap),        0x0,
386
16
            "Remote learn capability", HFILL }},
387
388
16
        { &hf_pagp_partner_port_priority,
389
16
          { "Partner Port Hot Standby Priority",    "pagp.partnerportpri",
390
16
            FT_UINT8,       BASE_DEC,       NULL,   0x0,
391
16
            "Remote port priority", HFILL }},
392
393
16
        { &hf_pagp_partner_sent_port_ifindex,
394
16
          { "Partner Sent Port ifindex",    "pagp.partnersentportifindex",
395
16
            FT_UINT32,      BASE_DEC,       NULL,   0x0,
396
16
            "Remote port interface index sent", HFILL }},
397
398
16
        { &hf_pagp_partner_group_capability,
399
16
          { "Partner Group Capability",     "pagp.partnergroupcap",
400
16
            FT_UINT32,      BASE_HEX,       NULL,   0x0,
401
16
            "Remote group capability", HFILL }},
402
403
16
        { &hf_pagp_partner_group_ifindex,
404
16
          { "Partner Group ifindex",        "pagp.partnergroupifindex",
405
16
            FT_UINT32,      BASE_DEC,       NULL,   0x0,
406
16
            "Remote group interface index", HFILL }},
407
408
16
        { &hf_pagp_partner_count,
409
16
          { "Partner Count",                "pagp.partnercount",
410
16
            FT_UINT16,      BASE_DEC,       NULL,   0x0,
411
16
            NULL, HFILL }},
412
413
16
        { &hf_pagp_num_tlvs,
414
16
          { "Number of TLVs",               "pagp.numtlvs",
415
16
            FT_UINT16,      BASE_DEC,       NULL,   0x0,
416
16
            "Number of TLVs following", HFILL }},
417
418
16
        { &hf_pagp_tlv,
419
16
          { "Type",         "pagp.tlv",
420
16
            FT_UINT16,      BASE_DEC,       VALS(tlv_types),        0x0,
421
16
            "Type/Length/Value", HFILL }},
422
423
16
        { &hf_pagp_tlv_length,
424
16
          { "Length",               "pagp.tlv_length",
425
16
            FT_UINT16,      BASE_DEC,       NULL,   0x0,
426
16
            NULL, HFILL }},
427
428
16
        { &hf_pagp_tlv_device_name,
429
16
          { "Device Name",          "pagp.tlvdevname",
430
16
            FT_STRING,      BASE_NONE,      NULL,   0x0,
431
16
            "sysName of device", HFILL }},
432
433
16
        { &hf_pagp_tlv_port_name,
434
16
          { "Physical Port Name",           "pagp.tlvportname",
435
16
            FT_STRING,      BASE_NONE,      NULL,   0x0,
436
16
            "Name of port used to send PDU", HFILL }},
437
438
16
        { &hf_pagp_tlv_agport_mac,
439
16
          { "Agport MAC Address",           "pagp.tlvagportmac",
440
16
            FT_ETHER,       BASE_NONE,      NULL,   0x0,
441
16
            "Source MAC on frames for this aggregate", HFILL }},
442
443
16
        { &hf_pagp_flush_local_device_id,
444
16
          { "Flush Local Device ID",        "pagp.flushlocaldevid",
445
16
            FT_ETHER,       BASE_NONE,      NULL,   0x0,
446
16
            NULL, HFILL }},
447
448
16
        { &hf_pagp_flush_partner_device_id,
449
16
          { "Flush Partner Device ID",      "pagp.flushpartnerdevid",
450
16
            FT_ETHER,       BASE_NONE,      NULL,   0x0,
451
16
            "Flush remote device ID", HFILL }},
452
453
16
        { &hf_pagp_flush_transaction_id,
454
16
          { "Transaction ID",               "pagp.transid",
455
16
            FT_UINT32,      BASE_HEX,       NULL,   0x0,
456
16
            "Flush transaction ID", HFILL }},
457
458
16
    };
459
460
    /* Setup protocol subtree array */
461
462
16
    static int *ett[] = {
463
16
        &ett_pagp,
464
16
        &ett_pagp_flags,
465
16
        &ett_pagp_tlvs,
466
16
    };
467
468
16
    static ei_register_info ei[] = {
469
16
        { &ei_pagp_tlv_length, { "pagp.tlv_length.invalid", PI_PROTOCOL, PI_WARN, "Invalid TLV length", EXPFILL }},
470
16
    };
471
16
    expert_module_t* expert_pagp;
472
473
    /* Register the protocol name and description */
474
475
16
    proto_pagp = proto_register_protocol("Port Aggregation Protocol", "PAGP", "pagp");
476
477
    /* Required function calls to register the header fields and subtrees used */
478
479
16
    proto_register_field_array(proto_pagp, hf, array_length(hf));
480
16
    proto_register_subtree_array(ett, array_length(ett));
481
16
    expert_pagp = expert_register_protocol(proto_pagp);
482
16
    expert_register_field_array(expert_pagp, ei, array_length(ei));
483
16
    pagp_handle = register_dissector("pagp", dissect_pagp, proto_pagp);
484
16
}
485
486
487
void
488
proto_reg_handoff_pagp(void)
489
16
{
490
16
    dissector_add_uint("llc.cisco_pid", CISCO_PID_PAGP, pagp_handle);
491
16
}
492
493
/*
494
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
495
 *
496
 * Local variables:
497
 * c-basic-offset: 4
498
 * tab-width: 8
499
 * indent-tabs-mode: nil
500
 * End:
501
 *
502
 * vi: set shiftwidth=4 tabstop=8 expandtab:
503
 * :indentSize=4:tabSize=8:noTabs=true:
504
 */