Skip to content

Instantly share code, notes, and snippets.

@enkiusz
Created February 9, 2021 21:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save enkiusz/3c598f8981a901f7b5e66de1532c6275 to your computer and use it in GitHub Desktop.
Save enkiusz/3c598f8981a901f7b5e66de1532c6275 to your computer and use it in GitHub Desktop.
Planet GSD-800S switch binary configuration dump format.
//------------------------------------------------
//--- 010 Editor v8.0 Binary Template
//
// File: Planet GSD-800S switch binary configuration dump format.
// Authors: Maciej Grela <enki@fsck.pl>
// Version: 0.8
// Purpose:
// Category:
// File Mask:
// ID Bytes:
// History:
//------------------------------------------------
/*
Planet GSD-800S switch binary configuration dump format.
Copyright (C) 2017 Maciej Grela <enki@fsck.pl>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
BigEndian();
enum <ubyte> FLAG { YES = 1, NO = 0 };
// Bitmask of switch ports.
// Please note, that the port labels on the front of the switch
// are not the same as actual port numbers.
typedef struct PORTMASK {
byte port4: 1;
byte port6: 1;
byte port8: 1;
byte port7: 1;
byte port5: 1;
byte port3: 1;
byte port2: 1;
byte port1: 1;
} portmask;
// A single switch port number:
// Please note, that the port labels on the front of the switch
// are not the same as actual port numbers.
typedef enum <byte> PORTNUM {
PORT1 = 0,
PORT2 = 1,
PORT3 = 2,
PORT4 = 7,
PORT5 = 3,
PORT6 = 6,
PORT7 = 4,
PORT8 = 5
} portnum;
typedef ubyte MAC48[6] <read=MAC48Read>;
string MAC48Read( MAC48 mac ) {
string s;
SPrintf(s, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
return s;
}
typedef ubyte IPv4[4] <read=IPv4Read>;
string IPv4Read( IPv4 ip ) {
string s;
SPrintf(s, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
return s;
}
struct CFG_CHUNK {
// <comment="Always 0xBA 0xBE">
byte sig[2];
byte type;
byte unk;
uint16 length;
switch (type) {
case 0x00: // Switch configuration
byte unk1[11];
// <comment="System -> Misc Configuration -> Inactivity Timeout">
uint16 inactivity_timeout;
byte admin_passwd[17];
byte system_name[17];
byte system_descr[33];
// Port Configuration -> Mode
// 0x13 -> Disabled,
// 0x53 -> Auto Speed
// 0x52 -> 1000 Full Duplex
// 0x51 -> 100 Full Duplex
// 0x41 -> 100 Half Duplex
// 0x50 -> 10 Full Duplex
// 0x40 -> 10 Half Duplex
//
// Note: Add 0x20 to port mode to enable flow control, for example 0x73 -> Auto Speed, Flow Control Enable
//
enum <ubyte> PORT_SPEEDS { SPEED_10 = 0, SPEED_100 = 1, SPEED_1000 = 2, SPEED_AUTO = 3 };
struct PORT_MODE {
BitfieldDisablePadding();
ubyte unk4: 1;
FLAG emable: 1;
FLAG flow_control: 1;
FLAG full_duplex: 1;
ubyte unk5: 2;
PORT_SPEEDS speed: 2;
};
//byte port_modes[8];
PORT_MODE port1_mode;
PORT_MODE port2_mode;
PORT_MODE port3_mode;
PORT_MODE port5_mode;
PORT_MODE port7_mode;
PORT_MODE port8_mode;
PORT_MODE port6_mode;
PORT_MODE port4_mode;
byte port1_name[8];
byte port2_name[8];
byte port3_name[8];
byte port5_name[8];
byte port7_name[8];
byte port8_name[8];
byte port6_name[8];
byte port4_name[8];
byte unk95[8];
// <comment="VLANs -> VLAN Per Port Configuration -> Acceptable Frame Type">
enum <byte> ACCEPTABLE_FRAME_TYPES { ALL = 0xDD, TAGGED_ONLY = 0xFD } port_acceptable_frames[8];
byte unk94[17];
// Port PVID (order like for port name)
// <comment="0x0010 -> VLAN 1, 0x0640 -> VLAN 100, last 4 bits are dropped">
uint16 port_pvid[8];
struct VLAN_RECORD {
// <comment="VLAN ID (1-4094)">
uint16 vlan_id;
portmask ports;
// <format=hex, comment="always 0xC0 if VLAN is enabled">
byte flag;
} vlans[64];
byte unk96[8];
// <comment="Mirroring destination port">
portnum mirror_destination_port;
// <comment="Enabled ports as sources for mirror">
portmask mirror_source_ports;
byte unk99[7];
struct STATIC_MAC_RECORD {
// <comment="VLAN ID (1-4094), 0xFFFF if entry is unused">
uint16 vlan_id;
MAC48 mac;
portnum port;
} static_mac[16];
// <comment="VLANs -> VLAN Per Port Configuration -> Ingress Filtering Enabled: 0 - Disabled, 1 -> Enabled)">
portmask port_ingress_filter;
// <comment="VLANs -> VLAN Per Port Configuration -> Link Type: 0 - UnTag, 1 -> Tag)">
portmask port_link_type;
// <comment="VLANs -> VLAN Per Port Configuration -> VLAN Type">
enum <byte> VLAN_TYPES { PORT_BASED = 0x00, VLAN_8021Q = 0x01 } vlan_type;
// <comment="Port Configuration -> All Ports Jumbo Frames Setting">
enum <byte> JUMBO_ENABLES { DISABLED = 0x00, JUMBO_4K = 0x01, JUMBO_9K = 0x02 } jumbo_enable;
break;
case 0x01: // Quality of Service
// <comment="Quality of Service -> 802.1p as QOS Mode -> 802.1p Configuration">
enum <uint16> PRIO_8021Q { PRIO_8021Q_LOW = 0x00, PRIO_8021Q_NORMAL = 0x5555, PRIO_8021Q_MEDIUM = 0xAAAA, PRIO_8021Q_HIGH = 0xFFFF } prio_8021q[8];
byte portstate2[8];
enum <byte> QOS_MODES { QOS_DISABLED = 0x00, QOS_8021_P = 0x01, QOS_DSCP = 0x02 } qos_mode;
struct DSCP_ENTRY {
// <comment="DSCP Value(0..63), 0x80 means 'Default', 0xFF means entry is unused">
byte dscp_id;
enum <byte> PRIORITIES { PRIO_DSCP_LOW = 0x00, PRIO_DSCP_NORMAL = 0x01, PRIO_DSCP_MEDIUM = 0x02, PRIO_DSCP_HIGH = 0x03 } priority;
} dscp_entries[8];
// <comment="Always 0x00">
byte unk94[5];
// <comment="Quality of Service -> Queue Mode">
enum <byte> QUEUE_MODE { STRICT = 0, WRR = 1 } queue_mode;
// <comment="Quality of Service -> WRR Weight (The ratio of Low/Normal/Medium/High queue)">
enum <byte> WRR_WEIGHTS {
W_1_1_1_5 = 0,
W_1_1_2_4 = 1,
W_1_1_2_6 = 2,
W_1_1_3_3 = 3,
W_1_1_3_5 = 4,
W_1_2_2_3 = 5,
W_1_2_2_5 = 6,
W_1_2_3_4 = 7,
W_1_3_3_3 = 8,
W_2_2_2_2 = 9,
W_2_2_2_4 = 10
} wrr_weights;
break;
case 0x02: // Static network configuration
byte unk3[3];
IPv4 ip;
IPv4 gw;
IPv4 netmask;
break;
case 0x03: // DHCP network configuration
FLAG dhcp_enabled;
// <comment="This is the IP address given to us by the DHCP server">
IPv4 ip;
break;
case 0x05:
IPv4 snmp_trap_ip;
FLAG snmp_enable;
break;
case 0x06:
byte snmp_read_community[21];
byte snmp_write_community[21];
byte snmp_trap_community[21];
break;
case 0x07: // LACP
// <format=hex, comment="Link Aggregation -> LACP -> Protocol Enabled">
enum <byte> PORT_LACP_STATES { LACP_DISABLED = 0xFC, LACP_ENABLED = 0xFD } port_lacp_enabled[8];
byte unk94[48];
break;
case 0x0A: // 802.1X Configuration
// <comment="802.1X Management -> 802.1X Configuration -> Mode">
FLAG radius_enable;
// <comment="802.1X Configuration -> Admin State: Force UnAuthorized">
portmask port_admin_force_auth;
// <comment="802.1X Configuration -> Admin State: Force Authorized">
portmask port_admin_force_unauth;
// State: Auto -> both bits are 0
IPv4 radius_ip;
uint16 radius_port;
byte radius_secret[15];
struct RADIUS_PARAMS {
BitfieldDisablePadding();
// <comment="802.1X Configuration -> Parameters -> Reauthentication Enabled">
uint reauth_enabled: 1;
uint unk7: 3;
// <comment="Timeout in seconds, 3600 sec default">
uint reauth_periond: 12;
byte eap_timeout;
} params;
break;
default:
byte data[length];
break;
}
};
struct GSD800S_Config_Hdr {
// <comment="Always 0x43 0x4f 0x4e 0x46 ('CONF')">
byte sig[4];
// <comment="Number of bytes in the header, including padding">
byte hdr_len;
// <comment="Always 0x01, even in different switches">
byte cfg_format;
// <comment="A sum16 checksum of all the data after the header, check using jacksum <DATA without first 32 bytes> to verify">
uint16 data_checksum;
// <comment="Number of bytes after header">
uint32 data_length;
// <comment="Always 0x01">
byte unk3;
// <comment="sum8 checksum of header bytes, verify using jacksum -a sum8 $hdrfile">
byte hdr_checksum;
// <comment="Always 0x73 0x98, even on different switches">
byte unk6[2];
};
struct GSD800S_Config {
GSD800S_Config_Hdr hdr;
byte padding[hdr.hdr_len - sizeof(hdr)];
while( !FEof() ) {
CFG_CHUNK chunk;
}
};
struct GSD800S_Config cfg;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment