wireshark/plugins/epan/ethercat/packet-ams.c

1246 lines
52 KiB
C

/* packet-ams.c
* Routines for ethercat packet disassembly
*
* Copyright (c) 2007 by Beckhoff Automation GmbH
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
/* Include files */
#include "config.h"
#include <epan/packet.h>
#include "packet-ams.h"
void proto_register_ams(void);
void proto_reg_handoff_ams(void);
#define AMS_TCP_PORT 48898 /* Not IANA registered */
/* Define the ams proto */
int proto_ams = -1;
/* Define the tree for ams */
static int ett_ams = -1;
static int ett_ams_stateflags = -1;
static int ett_ams_adsreadrequest = -1;
static int ett_ams_adsreadresponse = -1;
static int ett_ams_adswriterequest = -1;
static int ett_ams_adswriteresponse = -1;
static int ett_ams_adsreadwriterequest = -1;
static int ett_ams_adsreadwriteresponse = -1;
static int ett_ams_adsreadstaterequest = -1;
static int ett_ams_adsreadstateresponse = -1;
static int ett_ams_adswritectrlrequest = -1;
static int ett_ams_adswritectrlresponse = -1;
static int ett_ams_adsreaddinforequest = -1;
static int ett_ams_adsreaddinforesponse = -1;
static int ett_ams_adsadddnrequest = -1;
static int ett_ams_adsadddnresponse = -1;
static int ett_ams_adsdeldnrequest = -1;
static int ett_ams_adsdeldnresponse = -1;
static int ett_ams_adsdnrequest = -1;
static int hf_ams_sendernetid = -1;
static int hf_ams_senderport = -1;
static int hf_ams_targetnetid = -1;
static int hf_ams_targetport = -1;
static int hf_ams_cmdid = -1;
static int hf_ams_stateflags = -1;
static int hf_ams_stateresponse = -1;
static int hf_ams_statenoreturn = -1;
static int hf_ams_stateadscmd = -1;
static int hf_ams_statesyscmd = -1;
static int hf_ams_statehighprio = -1;
static int hf_ams_statetimestampadded = -1;
static int hf_ams_stateudp = -1;
static int hf_ams_stateinitcmd = -1;
static int hf_ams_statebroadcast = -1;
static int hf_ams_cbdata = -1;
static int hf_ams_errorcode = -1;
static int hf_ams_invokeid = -1;
static int hf_ams_data = -1;
/*ads Commands */
static int hf_ams_adsindexgroup = -1;
static int hf_ams_adsindexoffset = -1;
static int hf_ams_adscblength = -1;
static int hf_ams_adsreadrequest = -1;
static int hf_ams_adsreadresponse = -1;
static int hf_ams_adsinvokeid = -1;
static int hf_ams_adsresult = -1;
static int hf_ams_adsdata = -1;
static int hf_ams_adswriterequest = -1;
static int hf_ams_adswriteresponse = -1;
static int hf_ams_adsreadwriterequest = -1;
static int hf_ams_adsreadwriteresponse = -1;
static int hf_ams_adscbreadlength = -1;
static int hf_ams_adscbwritelength = -1;
static int hf_ams_adsstate = -1;
static int hf_ams_adsdevicestate = -1;
static int hf_ams_adsnotificationhandle = -1;
static int hf_ams_adsreadstaterequest = -1;
static int hf_ams_adsreadstateresponse = -1;
static int hf_ams_adswritectrlrequest = -1;
static int hf_ams_adswritectrlresponse = -1;
static int hf_ams_adsreaddinforequest = -1;
static int hf_ams_adsreaddinforesponse = -1;
static int hf_ams_adsadddnrequest = -1;
static int hf_ams_adsadddnresponse = -1;
static int hf_ams_adsdeldnrequest = -1;
static int hf_ams_adsdeldnresponse = -1;
static int hf_ams_adsdnrequest = -1;
/* static int hf_ams_adsdnresponse = -1; */
/* static int hf_ams_adsnoteattrib = -1; */
/* static int hf_ams_adsnoteblocks = -1; */
/* static int hf_ams_adsversion = -1; */
static int hf_ams_adsdevicename = -1;
static int hf_ams_adsversionversion = -1;
static int hf_ams_adsversionrevision = -1;
static int hf_ams_adsversionbuild = -1;
static int hf_ams_adsnoteblocksstamps = -1;
/* static int hf_ams_adsnoteblocksstamp = -1; */
/* static int hf_ams_adstimestamp = -1; */
/* static int hf_ams_adssamplecnt = -1; */
/* static int hf_ams_adsnoteblockssample = -1; */
static int hf_ams_adstransmode = -1;
static int hf_ams_adsmaxdelay = -1;
static int hf_ams_adscycletime = -1;
/* static int hf_ams_adscmpmax = -1; */
/* static int hf_ams_adscmpmin = -1; */
static dissector_handle_t ams_handle;
static const value_string TransMode[] =
{
{ 0, "NO TRANS"},
{ 1, "CLIENT CYCLE"},
{ 2, "CLIENT ON CHANGE"},
{ 3, "SERVER CYCLE"},
{ 4, "SERVER ON CHANGE"},
{ 10, "CLIENT FIRST REQUEST"},
{ 0, NULL }
};
static const value_string ErrorCode[] =
{
{ ERR_NOERROR, "NO ERROR"},
{ ERR_INTERNAL, "INTERNAL"},
{ ERR_NORTIME, "NO RTIME"},
{ ERR_ALLOCLOCKEDMEM, "ALLOC LOCKED MEM"},
{ ERR_INSERTMAILBOX, "INSERT MAILBOX"},
{ ERR_WRONGRECEIVEHMSG, "WRONGRECEIVEHMSG"},
{ ERR_TARGETPORTNOTFOUND, "TARGET PORT NOT FOUND"},
{ ERR_TARGETMACHINENOTFOUND, "TARGET MACHINE NOT FOUND"},
{ ERR_UNKNOWNCMDID, "UNKNOWN CMDID"},
{ ERR_BADTASKID, "BAD TASKID"},
{ ERR_NOIO, "NOIO"},
{ ERR_UNKNOWNAMSCMD, "UNKNOWN AMSCMD"},
{ ERR_WIN32ERROR, "WIN32 ERROR"},
{ ERR_PORTNOTCONNECTED, "PORT NOT CONNECTED"},
{ ERR_INVALIDAMSLENGTH, "INVALID AMS LENGTH"},
{ ERR_INVALIDAMSNETID, "INVALID AMS NETID"},
{ ERR_LOWINSTLEVEL, "LOW INST LEVEL"},
{ ERR_NODEBUGINTAVAILABLE, "NO DEBUG INT AVAILABLE"},
{ ERR_PORTDISABLED, "PORT DISABLED"},
{ ERR_PORTALREADYCONNECTED, "PORT ALREADY CONNECTED"},
{ ERR_AMSSYNC_W32ERROR, "AMSSYNC_W32ERROR"},
{ ERR_AMSSYNC_TIMEOUT, "AMSSYNC_TIMEOUT"},
{ ERR_AMSSYNC_AMSERROR, "AMSSYNC_AMSERROR"},
{ ERR_AMSSYNC_NOINDEXINMAP, "AMSSYNC_NOINDEXINMAP"},
{ ERR_INVALIDAMSPORT, "INVALID AMSPORT"},
{ ERR_NOMEMORY, "NO MEMORY"},
{ ERR_TCPSEND, "TCP SEND"},
{ ERR_HOSTUNREACHABLE, "HOST UNREACHABLE"},
{ ROUTERERR_NOLOCKEDMEMORY, "ROUTERERR_NOLOCKEDMEMORY"},
{ ROUTERERR_RESIZEMEMORY, "ROUTERERR_RESIZEMEMORY"},
{ ROUTERERR_MAILBOXFULL, "ROUTERERR_MAILBOXFULL"},
{ ROUTERERR_DEBUGBOXFULL, "ROUTERERR_DEBUGBOXFULL"},
{ ROUTERERR_UNKNOWNPORTTYPE, "ROUTERERR_UNKNOWNPORTTYPE"},
{ ROUTERERR_NOTINITIALIZED, "ROUTERERR_NOTINITIALIZED"},
{ ROUTERERR_PORTALREADYINUSE, "ROUTERERR_PORTALREADYINUSE"},
{ ROUTERERR_NOTREGISTERED, "ROUTERERR_NOTREGISTERED "},
{ ROUTERERR_NOMOREQUEUES, "ROUTERERR_NOMOREQUEUES"},
{ ROUTERERR_INVALIDPORT, "ROUTERERR_INVALIDPORT"},
{ ROUTERERR_NOTACTIVATED, "ROUTERERR_NOTACTIVATED"},
{ IOERR_INTERNAL, "IOERR_INTERNAL"},
{ IOERR_BADCARDNO, "IOERR_BADCARDNO"},
{ IOERR_INVALIDCARDADDR, "IOERR_INVALIDCARDADDR"},
{ IOERR_CDLLISTFULL, "IOERR_CDLLISTFULL"},
{ IOERR_BADCDLPARAM, "IOERR_BADCDLPARAM"},
{ IOERR_OPENIOFAILED, "IOERR_OPENIOFAILED"},
{ IOERR_RESETIOFAILED, "IOERR_RESETIOFAILED"},
{ IOERR_UNKNOWNDEVICE, "IOERR_UNKNOWNDEVICE"},
{ IOERR_UNKNOWNDEVICEID, "IOERR_UNKNOWNDEVICEID"},
{ IOERR_UNKNOWNIMAGEID, "IOERR_UNKNOWNIMAGEID"},
{ IOERR_GETIOSTATE, "IOERR_GETIOSTATE"},
{ IOERR_BADIMAGEID, "IOERR_BADIMAGEID"},
{ IOERR_NOMORECLIENTSPACE, "IOERR_NOMORECLIENTSPACE"},
{ IOERR_CLIENTINFONOTFOUND, "IOERR_CLIENTINFONOTFOUND"},
{ IOERR_CDLNOTINUSE, "IOERR_CDLNOTINUSE"},
{ IOERR_TIMEOUTWITHDEVICE, "IOERR_TIMEOUTWITHDEVICE"},
{ IOERR_C1220FUNC_1, "IOERR_C1220FUNC_1"},
{ IOERR_C1220FUNC_9, "IOERR_C1220FUNC_9"},
{ IOERR_C1220FUNC_C, "IOERR_C1220FUNC_C"},
{ IOERR_C1220FUNC_10, "IOERR_C1220FUNC_10"},
{ IOERR_C1220FUNC_1_MAXSEND, "IOERR_C1220FUNC_1_MAXSEND"},
{ IOERR_C1220FUNC_1_ADDRSET, "IOERR_C1220FUNC_1_ADDRSET"},
{ IOERR_C1220FUNC_1_BREAK, "IOERR_C1220FUNC_1_BREAK"},
{ IOERR_C1220FUNC_1_BREAK0, "IOERR_C1220FUNC_1_BREAK0"},
{ IOERR_C1220FUNC_1_BREAK1, "IOERR_C1220FUNC_1_BREAK1"},
{ IOERR_C1220FUNC_1_BREAK2, "IOERR_C1220FUNC_1_BREAK2"},
{ IOERR_C1220FUNC_1_BREAK3, "IOERR_C1220FUNC_1_BREAK3"},
{ IOERR_C1220FUNC_1_BREAK4, "IOERR_C1220FUNC_1_BREAK4"},
{ IOERR_C1220FUNC_1_BREAK5, "IOERR_C1220FUNC_1_BREAK5"},
{ IOERR_C1220FUNC_1_BREAK6, "IOERR_C1220FUNC_1_BREAK6"},
{ IOERR_C1220FUNC_1_BREAK7, "IOERR_C1220FUNC_1_BREAK7"},
{ IOERR_C1220FUNC_1_BREAK8, "IOERR_C1220FUNC_1_BREAK8"},
{ IOERR_C1220FUNC_1_BREAK9, "IOERR_C1220FUNC_1_BREAK9"},
{ IOERR_C1220FUNC_1_BREAK10, "IOERR_C1220FUNC_1_BREAK10"},
{ IOERR_C1220FUNC_1_BREAK11, "IOERR_C1220FUNC_1_BREAK11"},
{ IOERR_C1220FUNC_1_BREAK12, "IOERR_C1220FUNC_1_BREAK12"},
{ IOERR_C1220FUNC_1_BREAK13, "IOERR_C1220FUNC_1_BREAK13"},
{ IOERR_C1220FUNC_1_BREAK14, "IOERR_C1220FUNC_1_BREAK14"},
{ IOERR_C1220FUNC_1_BREAK15, "IOERR_C1220FUNC_1_BREAK15"},
{ IOERR_C1220FUNC_1_BREAK16, "IOERR_C1220FUNC_1_BREAK16"},
{ IOERR_SPC3DEVINITDP, "IOERR_SPC3DEVINITDP"},
{ IOERR_SPC3UPDATEOUTPUT, "IOERR_SPC3UPDATEOUTPUT"},
{ IOERR_CIF30READDIAG, "IOERR_CIF30READDIAG"},
{ IOERR_CIF30COMMNOTSTARTED, "IOERR_CIF30COMMNOTSTARTED"},
{ IOERR_CIF30SLAVEPARASIZE, "IOERR_CIF30SLAVEPARASIZE"},
{ IOERR_CIF30NOPARAS, "IOERR_CIF30NOPARAS"},
{ IOERR_CIF30SLAVEERROR, "IOERR_CIF30SLAVEERROR"},
{ IOERR_CIF30WATCHDOGEXPIRED, "IOERR_CIF30WATCHDOGEXPIRED"},
{ IOERR_UNKNOWNDEVICECMD, "IOERR_UNKNOWNDEVICECMD"},
{ IOERR_CIF40MESSAGEHANDLING, "IOERR_CIF40MESSAGEHANDLING"},
{ IOERR_CIF40PARAERROR, "IOERR_CIF40PARAERROR"},
{ IOERR_CIF40WATCHDOGEXPIRED, "IOERR_CIF40WATCHDOGEXPIRED"},
{ IOERR_CIF40FLAGERROR, "IOERR_CIF40FLAGERROR"},
{ IOERR_CIF40COMMNOTSTARTED, "IOERR_CIF40COMMNOTSTARTED"},
{ IOERR_CIF40READDIAG, "IOERR_CIF40READDIAG"},
{ IOERR_CIF40SLAVEERROR, "IOERR_CIF40SLAVEERROR"},
{ IOERR_CIF40GLOBALERROR, "IOERR_CIF40GLOBALERROR"},
{ IOERR_CIF40CONFIGLIST, "IOERR_CIF40CONFIGLIST"},
{ IOERR_CP5412A2SLAVEPARASIZE, "IOERR_CP5412A2SLAVEPARASIZE"},
{ IOERR_CP5412A2NOPARAS, "IOERR_CP5412A2NOPARAS"},
{ IOERR_CP5412A2SLAVEERROR, "IOERR_CP5412A2SLAVEERROR"},
{ IOERR_CP5412A2FATAL, "IOERR_CP5412A2FATAL"},
{ IOERR_CP5412A2MAILBOXUSED, "IOERR_CP5412A2MAILBOXUSED"},
{ IOERR_BEGINCONFIGWHILETICKER, "IOERR_BEGINCONFIGWHILETICKER"},
{ IOERR_UNEXPECTEDBOXCOUNT, "IOERR_UNEXPECTEDBOXCOUNT"},
{ IOERR_C1200CHECKADDR, "IOERR_C1200CHECKADDR"},
{ IOERR_C1200INTENSITYTEST, "IOERR_C1200INTENSITYTEST"},
{ IOERR_NOIMAGE, "IOERR_NOIMAGE"},
{ IOERR_INVALIDIMAGEOFFSSIZE, "IOERR_INVALIDIMAGEOFFSSIZE"},
{ IOERR_FORCESCOUNTEXCEEDEDMAXIMUM, "IOERR_FORCESCOUNTEXCEEDEDMAXIMUM"},
{ IOERR_SERCOSLIFECOUNTERERR, "IOERR_SERCOSLIFECOUNTERERR"},
{ IOERR_C1220NOTFOUND, "IOERR_C1220NOTFOUND"},
{ IOERR_AMSDEVICENOAMSINTF, "IOERR_AMSDEVICENOAMSINTF"},
{ IOERR_AMSDEVICEAMSCMDIDNOTSUPP, "IOERR_AMSDEVICEAMSCMDIDNOTSUPP"},
{ IOERR_AMSDEVICEAMSSERVICERUNNING, "IOERR_AMSDEVICEAMSSERVICERUNNING"},
{ IOERR_PLCINTERFACE_BUSY, "IOERR_PLCINTERFACE_BUSY"},
{ IOERR_PLCINTERFACE_FAULT, "IOERR_PLCINTERFACE_FAULT"},
{ IOERR_PLCINTERFACE_TIMEOUT, "IOERR_PLCINTERFACE_TIMEOUT"},
{ IOERR_PLCINTERFACE_RESETTIMEOUT, "IOERR_PLCINTERFACE_RESETTIMEOUT"},
{ IOERR_PLCINTERFACE_NODATAEXCH, "IOERR_PLCINTERFACE_NODATAEXCH"},
{ IOERR_PLCINTERFACE_RESET, "IOERR_PLCINTERFACE_RESET"},
{ IOERR_CP5412A2INVALIDADDR, "IOERR_CP5412A2INVALIDADDR"},
{ IOERR_CP5412A2INVALIDPORT, "IOERR_CP5412A2INVALIDPORT"},
{ IOERR_AMSDEVICEBADBOXNO, "IOERR_AMSDEVICEBADBOXNO"},
{ IOERR_AMSDEVICEBADTYPE, "IOERR_AMSDEVICEBADTYPE"},
{ IOERR_AMSDEVICEILLEGALADDRESS, "IOERR_AMSDEVICEILLEGALADDRESS"},
{ IOERR_CP5412A2INVALIDBOX, "IOERR_CP5412A2INVALIDBOX"},
{ IOERR_AMSDEVICEFIFOOVERFLOW, "IOERR_AMSDEVICEFIFOOVERFLOW"},
{ IOERR_AMSDEVICEAMSSEQUENCEERROR, "IOERR_AMSDEVICEAMSSEQUENCEERROR"},
{ IOERR_CP5412A2DPV1SYNTAXERROR, "IOERR_CP5412A2DPV1SYNTAXERROR"},
{ IOERR_CP5412A2DEVICENOTRUNNING, "IOERR_CP5412A2DEVICENOTRUNNING"},
{ IOERR_AMSDEVICENOTRUNNING, "IOERR_AMSDEVICENOTRUNNING"},
{ IOERR_AMSDEVICEBOXNOTDEFINED, "IOERR_AMSDEVICEBOXNOTDEFINED"},
{ IOERR_CP5412A2BADSERVICEPARA, "IOERR_CP5412A2BADSERVICEPARA"},
{ IOERR_CP5412A2FIFOOVERFLOW, "IOERR_CP5412A2FIFOOVERFLOW"},
{ IOERR_COMPORTOPENFAILED, "IOERR_COMPORTOPENFAILED"},
{ IOERR_CIF30BADMESSAGERESPONSE, "IOERR_CIF30BADMESSAGERESPONSE"},
{ IOERR_CIF30DELETEDATABASE, "IOERR_CIF30DELETEDATABASE"},
{ IOERR_CIF30STARTSEQFAILED, "IOERR_CIF30STARTSEQFAILED"},
{ IOERR_CIF30DOWNLOADFAILED, "IOERR_CIF30DOWNLOADFAILED"},
{ IOERR_CIF30ENDSEQFAILED, "IOERR_CIF30ENDSEQFAILED"},
{ IOERR_CIF30BUSLOADFAILED, "IOERR_CIF30BUSLOADFAILED"},
{ IOERR_PLCINTERFACE_RESETREQ, "IOERR_PLCINTERFACE_RESETREQ"},
{ IOERR_CP5412A2INVALIDCYCLETICKS, "IOERR_CP5412A2INVALIDCYCLETICKS"},
{ IOERR_CP5412A2DPBUSFAULT, "IOERR_CP5412A2DPBUSFAULT"},
{ IOERR_INVALIDTERMCONFIG, "IOERR_INVALIDTERMCONFIG"},
{ IOERR_SERCANSBREAK, "IOERR_SERCANSBREAK"},
{ IOERR_SERCANSPHASE0, "IOERR_SERCANSPHASE0"},
{ IOERR_SERCANSPHASE1, "IOERR_SERCANSPHASE1"},
{ IOERR_SERCANSPHASE2, "IOERR_SERCANSPHASE2"},
{ IOERR_SERCANSPHASE3, "IOERR_SERCANSPHASE3"},
{ IOERR_SERCANSPHASE4, "IOERR_SERCANSPHASE4"},
{ IOERR_SERCANSNCSERVICECHNFAILED, "IOERR_SERCANSNCSERVICECHNFAILED"},
{ IOERR_RESOURCECONFICT, "IOERR_RESOURCECONFICT"},
{ IOERR_C1220INITSTRINGCOMM, "IOERR_C1220INITSTRINGCOMM"},
{ IOERR_C1220REGSTRINGSLAVE, "IOERR_C1220REGSTRINGSLAVE"},
{ IOERR_C1220STRREGFAULT, "IOERR_C1220STRREGFAULT"},
{ IOERR_IOSTATEBUSY, "IOERR_IOSTATEBUSY"},
{ IOERR_IBSSCITWATCHDOGEXPIRED, "IOERR_IBSSCITWATCHDOGEXPIRED"},
{ IOERR_IBSSCITSYNCMAILBOXERROR, "IOERR_IBSSCITSYNCMAILBOXERROR"},
{ IOERR_IBSSCITCONFIRMDIAGERROR, "IOERR_IBSSCITCONFIRMDIAGERROR"},
{ IOERR_IBSSCITCREATECFGERROR, "IOERR_IBSSCITCREATECFGERROR"},
{ 0, NULL }
};
static const value_string AdsErrorMode[] =
{
{ ADSERR_NOERR, "NO ERROR", },
{ ADSERR_DEVICE_ERROR, "ERROR", },
{ ADSERR_DEVICE_SRVNOTSUPP, "SRV NOT SUPP", },
{ ADSERR_DEVICE_INVALIDGRP, "INVALID GRP", },
{ ADSERR_DEVICE_INVALIDOFFSET, "INVALID OFFSET", },
{ ADSERR_DEVICE_INVALIDACCESS, "INVALID ACCESS", },
{ ADSERR_DEVICE_INVALIDSIZE, "INVALID SIZE", },
{ ADSERR_DEVICE_INVALIDDATA, "INVALID DATA", },
{ ADSERR_DEVICE_NOTREADY, "NOT READY", },
{ ADSERR_DEVICE_BUSY, "BUSY", },
{ ADSERR_DEVICE_INVALIDCONTEXT, "INVALID CONTEXT", },
{ ADSERR_DEVICE_NOMEMORY, "NO MEMORY", },
{ ADSERR_DEVICE_INVALIDPARM, "INVALID PARM", },
{ ADSERR_DEVICE_NOTFOUND, "NOT FOUND", },
{ ADSERR_DEVICE_SYNTAX, "SYNTAX", },
{ ADSERR_DEVICE_INCOMPATIBLE, "INCOMPATIBLE", },
{ ADSERR_DEVICE_EXISTS, "EXISTS", },
{ ADSERR_DEVICE_SYMBOLNOTFOUND, "SYMBOL NOT FOUND", },
{ ADSERR_DEVICE_SYMBOLVERSIONINVALID, "SYMBOL VERSION INVALID", },
{ ADSERR_DEVICE_INVALIDSTATE, "INVALID STATE", },
{ ADSERR_DEVICE_TRANSMODENOTSUPP, "TRANS MODE NOT SUPP", },
{ ADSERR_DEVICE_NOTIFYHNDINVALID, "NOTIFY HND INVALID", },
{ ADSERR_DEVICE_CLIENTUNKNOWN, "CLIENT UNKNOWN", },
{ ADSERR_DEVICE_NOMOREHDLS, "NO MORE HDLS", },
{ ADSERR_DEVICE_INVALIDWATCHSIZE, "INVALID WATCHSIZE", },
{ ADSERR_DEVICE_NOTINIT, "NOT INIT", },
{ ADSERR_DEVICE_TIMEOUT, "TIMEOUT", },
{ ADSERR_DEVICE_NOINTERFACE, "NO INTERFACE", },
{ ADSERR_DEVICE_INVALIDINTERFACE, "INVALID INTERFACE", },
{ ADSERR_DEVICE_INVALIDCLSID, "INVALID CLSID", },
{ ADSERR_DEVICE_INVALIDOBJID, "INVALID OBJID", },
{ ADSERR_DEVICE_PENDING, "PENDING", },
{ ADSERR_DEVICE_ABORTED, "ABORTED", },
{ ADSERR_DEVICE_WARNING, "WARNING", },
{ ADSERR_DEVICE_INVALIDARRAYIDX, "INVALID ARRAY IDX", },
{ ADSERR_CLIENT_ERROR, "CLIENT ERROR", },
{ ADSERR_CLIENT_INVALIDPARM, "CLIENT INVALID PARM", },
{ ADSERR_CLIENT_LISTEMPTY, "CLIENT LIST EMPTY", },
{ ADSERR_CLIENT_VARUSED, "CLIENT VAR USED", },
{ ADSERR_CLIENT_DUPLINVOKEID, "CLIENT DUPL INVOKEID", },
{ ADSERR_CLIENT_SYNCTIMEOUT, "CLIENT SYNC TIMEOUT", },
{ ADSERR_CLIENT_W32ERROR, "CLIENT W32ERROR", },
{ ADSERR_CLIENT_TIMEOUTINVALID, "CLIENT TIMEOUT INVALID", },
{ ADSERR_CLIENT_PORTNOTOPEN, "CLIENT PORT NOT OPEN", },
{ ADSERR_CLIENT_NOAMSADDR, "CLIENT NO AMS ADDR", },
{ ADSERR_CLIENT_SYNCINTERNAL, "CLIENT SYNC INTERNAL", },
{ ADSERR_CLIENT_ADDHASH, "CLIENT ADD HASH", },
{ ADSERR_CLIENT_REMOVEHASH, "CLIENT REMOVE HASH", },
{ ADSERR_CLIENT_NOMORESYM, "CLIENT NO MORE SYM", },
{ ADSERR_CLIENT_SYNCRESINVALID, "CLIENT SYNC RES INVALID", },
{ ADSERR_CLIENT_SYNCPORTLOCKED, "CLIENT SYNC PORT LOCKED", },
{ 0, NULL }
};
/* AMS Command Id
* https://infosys.beckhoff.com/english.php?content=../content/1033/tcadsamsspec/html/tcadsamsspec_adscmd_readstate.htm&id=10652
*/
static const value_string AMS_CommandId_vals[] =
{
{ ADSSRVID_INVALID, "Invalid", },
{ ADSSRVID_READDEVICEINFO, "ADS Read Device Info", },
{ ADSSRVID_READ, "ADS Read", },
{ ADSSRVID_WRITE, "ADS Write", },
{ ADSSRVID_READSTATE, "ADS Read State", },
{ ADSSRVID_WRITECTRL, "ADS Write Control", },
{ ADSSRVID_ADDDEVICENOTE, "ADS Add Device Notification", },
{ ADSSRVID_DELDEVICENOTE, "ADS Delete Device Notification", },
{ ADSSRVID_DEVICENOTE, "ADS Device Notification", },
{ ADSSRVID_READWRITE, "ADS Read Write", },
{ 0, NULL }
};
static void NetIdFormater(tvbuff_t *tvb, guint offset, char *szText, gint nMax)
{
snprintf ( szText, nMax, "%d.%d.%d.%d.%d.%d", tvb_get_guint8(tvb, offset),
tvb_get_guint8(tvb, offset+1),
tvb_get_guint8(tvb, offset+2),
tvb_get_guint8(tvb, offset+3),
tvb_get_guint8(tvb, offset+4),
tvb_get_guint8(tvb, offset+5)
);
}
/*ams*/
static gint dissect_ams_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
{
proto_item *ti, *anItem;
proto_tree *ams_tree = NULL, *ams_adstree, *ams_statetree;
guint ams_length = tvb_reported_length(tvb);
guint16 stateflags = 0;
guint16 cmdId = 0;
guint32 cbdata = 0;
char szText[200];
int nMax = sizeof(szText)-1;
col_set_str(pinfo->cinfo, COL_PROTOCOL, "AMS");
col_clear(pinfo->cinfo, COL_INFO);
if( ams_length < AmsHead_Len )
return offset;
if (tree)
{
ti = proto_tree_add_item(tree, proto_ams, tvb, 0, -1, ENC_NA);
ams_tree = proto_item_add_subtree(ti, ett_ams);
NetIdFormater(tvb, offset, szText, nMax);
proto_tree_add_string(ams_tree, hf_ams_targetnetid, tvb, offset, AmsNetId_Len, szText);
offset += AmsNetId_Len;
proto_tree_add_item(ams_tree, hf_ams_targetport, tvb, offset, (int)sizeof(guint16), ENC_LITTLE_ENDIAN);
offset += (int)sizeof(guint16);
NetIdFormater(tvb, offset, szText, nMax);
proto_tree_add_string(ams_tree, hf_ams_sendernetid, tvb, offset, AmsNetId_Len, szText);
offset += AmsNetId_Len;
proto_tree_add_item(ams_tree, hf_ams_senderport, tvb, offset, (int)sizeof(guint16), ENC_LITTLE_ENDIAN);
offset += (int)sizeof(guint16);
proto_tree_add_item(ams_tree, hf_ams_cmdid, tvb, offset, (int)sizeof(guint16), ENC_LITTLE_ENDIAN);
cmdId = tvb_get_letohs(tvb, offset);
offset+=(int)sizeof(guint16);
anItem = proto_tree_add_item(ams_tree, hf_ams_stateflags, tvb, offset, (int)sizeof(guint16), ENC_LITTLE_ENDIAN);
ams_statetree = proto_item_add_subtree(anItem, ett_ams_stateflags);
proto_tree_add_item(ams_statetree, hf_ams_stateresponse,tvb, offset, (int)sizeof(guint16), ENC_LITTLE_ENDIAN);
proto_tree_add_item(ams_statetree, hf_ams_statenoreturn,tvb, offset, (int)sizeof(guint16), ENC_LITTLE_ENDIAN);
proto_tree_add_item(ams_statetree, hf_ams_stateadscmd,tvb, offset, (int)sizeof(guint16), ENC_LITTLE_ENDIAN);
proto_tree_add_item(ams_statetree, hf_ams_statesyscmd,tvb, offset, (int)sizeof(guint16), ENC_LITTLE_ENDIAN);
proto_tree_add_item(ams_statetree, hf_ams_statehighprio,tvb, offset, (int)sizeof(guint16), ENC_LITTLE_ENDIAN);
proto_tree_add_item(ams_statetree, hf_ams_statetimestampadded,tvb, offset, (int)sizeof(guint16), ENC_LITTLE_ENDIAN);
proto_tree_add_item(ams_statetree, hf_ams_stateudp,tvb, offset, (int)sizeof(guint16), ENC_LITTLE_ENDIAN);
proto_tree_add_item(ams_statetree, hf_ams_stateinitcmd,tvb, offset, (int)sizeof(guint16), ENC_LITTLE_ENDIAN);
proto_tree_add_item(ams_statetree, hf_ams_statebroadcast,tvb, offset, (int)sizeof(guint16), ENC_LITTLE_ENDIAN);
stateflags = tvb_get_letohs(tvb, offset);
offset+=(int)sizeof(guint16);
proto_tree_add_item(ams_tree, hf_ams_cbdata, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN);
cbdata = tvb_get_letohl(tvb,offset);
offset+=(int)sizeof(guint32);
proto_tree_add_item(ams_tree, hf_ams_errorcode, tvb, offset, (int)sizeof(guint32),ENC_LITTLE_ENDIAN);
offset+=(int)sizeof(guint32);
proto_tree_add_item(ams_tree, hf_ams_invokeid, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN);
offset+=(int)sizeof(guint32);
}
else
{
offset+=AmsHead_Len;
}
if ( (stateflags & AMSCMDSF_ADSCMD) != 0 )
{
/* ADS */
if ( (stateflags & AMSCMDSF_RESPONSE) == 0 )
{
/* Request */
switch ( cmdId )
{
case ADSSRVID_READ:
{
col_append_str(pinfo->cinfo, COL_INFO, "ADS Read Request");
if( tree )
{
anItem = proto_tree_add_item(ams_tree, hf_ams_adsreadrequest, tvb, offset, ams_length-offset, ENC_NA);
if( ams_length-offset >= TAdsReadReq_Len )
{
ams_adstree = proto_item_add_subtree(anItem, ett_ams_adsreadrequest);
proto_tree_add_item(ams_adstree, hf_ams_adsindexgroup, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN);
offset+=(int)sizeof(guint32);
proto_tree_add_item(ams_adstree, hf_ams_adsindexoffset, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN);
offset+=(int)sizeof(guint32);
proto_tree_add_item(ams_adstree, hf_ams_adscblength, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN);
offset+=(int)sizeof(guint32);
}
}
}
break;
case ADSSRVID_WRITE:
{
col_append_str(pinfo->cinfo, COL_INFO, "ADS Write Request");
if( tree )
{
anItem = proto_tree_add_item(ams_tree, hf_ams_adswriterequest, tvb, offset, ams_length-offset, ENC_NA);
if( ams_length-offset >= TAdsWriteReq_Len - (int)sizeof(guint16) )
{
ams_adstree = proto_item_add_subtree(anItem, ett_ams_adswriterequest);
proto_tree_add_item(ams_adstree, hf_ams_adsindexgroup, tvb, offset, 4, ENC_LITTLE_ENDIAN);
offset+=(int)sizeof(guint32);
proto_tree_add_item(ams_adstree, hf_ams_adsindexoffset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
offset+=(int)sizeof(guint32);
proto_tree_add_item(ams_adstree, hf_ams_adscblength, tvb, offset, 4, ENC_LITTLE_ENDIAN);
offset+=(int)sizeof(guint32);
proto_tree_add_item(ams_adstree, hf_ams_adsdata, tvb, offset, ams_length-offset, ENC_NA);
}
}
}
break;
case ADSSRVID_READWRITE:
{
col_append_str(pinfo->cinfo, COL_INFO, "ADS Read Write Request");
if( tree )
{
anItem = proto_tree_add_item(ams_tree, hf_ams_adsreadwriterequest, tvb, offset, ams_length-offset, ENC_NA);
if( ams_length-offset >= TAdsReadWriteReq_Len - (int)sizeof(guint16))
{
ams_adstree = proto_item_add_subtree(anItem, ett_ams_adsreadwriterequest);
proto_tree_add_item(ams_adstree, hf_ams_adsindexgroup, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN);
offset+=(int)sizeof(guint32);
proto_tree_add_item(ams_adstree, hf_ams_adsindexoffset, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN);
offset+=(int)sizeof(guint32);
proto_tree_add_item(ams_adstree, hf_ams_adscbreadlength, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN);
offset+=(int)sizeof(guint32);
proto_tree_add_item(ams_adstree, hf_ams_adscbwritelength, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN);
offset+=(int)sizeof(guint32);
proto_tree_add_item(ams_adstree, hf_ams_adsdata, tvb, offset, ams_length-offset, ENC_NA);
}
}
}
break;
case ADSSRVID_READSTATE:
{
col_append_str(pinfo->cinfo, COL_INFO, "ADS Read State Request");
if( tree && cbdata !=0 )
{
anItem = proto_tree_add_item(ams_tree, hf_ams_adsreadstaterequest, tvb, offset, ams_length-offset, ENC_NA);
if( ams_length-offset >= TAdsReadStateReq_Len )
{
ams_adstree = proto_item_add_subtree(anItem, ett_ams_adsreadstaterequest);
proto_tree_add_item(ams_adstree, hf_ams_adsinvokeid, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN);
}
}
}
break;
case ADSSRVID_WRITECTRL:
{
col_append_str(pinfo->cinfo, COL_INFO, "ADS Write Control Request");
if( tree )
{
anItem = proto_tree_add_item(ams_tree, hf_ams_adswritectrlrequest, tvb, offset, ams_length-offset, ENC_NA);
if( ams_length-offset >= TAdsWriteControlReq_Len - (int)sizeof(guint16) )
{
ams_adstree = proto_item_add_subtree(anItem, ett_ams_adswritectrlrequest);
proto_tree_add_item(ams_adstree, hf_ams_adsstate, tvb, offset, 2, ENC_LITTLE_ENDIAN);
offset+=(int)sizeof(guint16);
proto_tree_add_item(ams_adstree, hf_ams_adsdevicestate, tvb, offset, 2, ENC_LITTLE_ENDIAN);
offset+=(int)sizeof(guint16);
proto_tree_add_item(ams_adstree, hf_ams_adscblength, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN);
offset+=(int)sizeof(guint32);
proto_tree_add_item(ams_adstree, hf_ams_adsdata, tvb, offset, ams_length-offset, ENC_NA);
}
}
}
break;
case ADSSRVID_READDEVICEINFO:
{
col_append_str(pinfo->cinfo, COL_INFO, "ADS Read Device Info Request");
if( tree && cbdata !=0 )
{
anItem = proto_tree_add_item(ams_tree, hf_ams_adsreaddinforequest, tvb, offset, ams_length-offset, ENC_NA);
if( ams_length-offset >= TAdsReadDeviceInfoReq_Len )
{
ams_adstree = proto_item_add_subtree(anItem, ett_ams_adsreaddinforequest);
proto_tree_add_item(ams_adstree, hf_ams_adsresult, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN);
}
}
}
break;
case ADSSRVID_ADDDEVICENOTE:
{
col_append_str(pinfo->cinfo, COL_INFO, "ADS Add Device Notification Request");
if( tree )
{
anItem = proto_tree_add_item(ams_tree, hf_ams_adsadddnrequest, tvb, offset, ams_length-offset, ENC_NA);
if( ams_length-offset >= TAdsAddDeviceNotificationReq_Len )
{
ams_adstree = proto_item_add_subtree(anItem, ett_ams_adsadddnrequest);
proto_tree_add_item(ams_adstree, hf_ams_adsindexgroup, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN);
offset+=(int)sizeof(guint32);
proto_tree_add_item(ams_adstree, hf_ams_adsindexoffset, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN);
offset+=(int)sizeof(guint32);
proto_tree_add_item(ams_adstree, hf_ams_adscblength, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN);
offset+=(int)sizeof(guint32);
proto_tree_add_item(ams_adstree, hf_ams_adstransmode, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN);
offset+=(int)sizeof(guint32);
proto_tree_add_item(ams_adstree, hf_ams_adsmaxdelay, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN);
offset+=(int)sizeof(guint32);
proto_tree_add_item(ams_adstree, hf_ams_adscycletime, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN);
offset+=(int)sizeof(guint32);
}
}
}
break;
case ADSSRVID_DELDEVICENOTE:
{
col_append_str(pinfo->cinfo, COL_INFO, "ADS Delete Device Notification Request");
if( tree )
{
anItem = proto_tree_add_item(ams_tree, hf_ams_adsdeldnrequest, tvb, offset, ams_length-offset, ENC_NA);
if( ams_length-offset >= TAdsDelDeviceNotificationReq_Len )
{
ams_adstree = proto_item_add_subtree(anItem, ett_ams_adsdeldnrequest);
proto_tree_add_item(ams_adstree, hf_ams_adsnotificationhandle, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN);
}
}
}
break;
case ADSSRVID_DEVICENOTE:
{
col_append_str(pinfo->cinfo, COL_INFO, "ADS Device Notification Request");
if( tree )
{
/*guint32 cbLength;
guint32 nStamps;*/
anItem = proto_tree_add_item(ams_tree, hf_ams_adsdnrequest, tvb, offset, ams_length-offset, ENC_NA);
if( ams_length-offset >= TAdsDeviceNotificationReq_Len )
{
ams_adstree = proto_item_add_subtree(anItem, ett_ams_adsdnrequest);
proto_tree_add_item(ams_adstree, hf_ams_adscblength, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN);
/*cbLength = tvb_get_letohs(tvb, offset);*/
offset+=(int)sizeof(guint32);
proto_tree_add_item(ams_adstree, hf_ams_adsnoteblocksstamps, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN);
/*nStamps = tvb_get_letohs(tvb, offset);*/
offset+=(int)sizeof(guint32);
/*ToDo: dissect noteblocks*/
}
}
}
break;
}
}
else
{
/* Response */
switch ( cmdId )
{
case ADSSRVID_READ:
{
col_append_str(pinfo->cinfo, COL_INFO, "ADS Read Response");
if( tree )
{
anItem = proto_tree_add_item(ams_tree, hf_ams_adsreadresponse, tvb, offset, ams_length-offset, ENC_NA);
if( ams_length-offset >= TAdsReadRes_Len - (int)sizeof(guint16) )
{
ams_adstree = proto_item_add_subtree(anItem, ett_ams_adsreadresponse);
proto_tree_add_item(ams_adstree, hf_ams_adsresult, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN);
offset+=(int)sizeof(guint32);
proto_tree_add_item(ams_adstree, hf_ams_adscblength, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN);
offset+=(int)sizeof(guint32);
proto_tree_add_item(ams_adstree, hf_ams_adsdata, tvb, offset, ams_length-offset, ENC_NA);
}
}
}
break;
case ADSSRVID_WRITE:
{
col_append_str(pinfo->cinfo, COL_INFO, "ADS Write Response");
if( tree )
{
anItem = proto_tree_add_item(ams_tree, hf_ams_adswriteresponse, tvb, offset, ams_length-offset, ENC_NA);
if( ams_length-offset >= TAdsWriteRes_Len )
{
ams_adstree = proto_item_add_subtree(anItem, ett_ams_adswriteresponse);
proto_tree_add_item(ams_adstree, hf_ams_adsresult, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN);
}
}
}
break;
case ADSSRVID_READWRITE:
{
col_append_str(pinfo->cinfo, COL_INFO, "ADS Read Write Response");
if( tree )
{
anItem = proto_tree_add_item(ams_tree, hf_ams_adsreadwriteresponse, tvb, offset, ams_length-offset, ENC_NA);
if( ams_length-offset >= TAdsReadWriteRes_Len - (int)sizeof(guint16) )
{
ams_adstree = proto_item_add_subtree(anItem, ett_ams_adsreadwriteresponse);
proto_tree_add_item(ams_adstree, hf_ams_adsresult, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN);
offset+=(int)sizeof(guint32);
proto_tree_add_item(ams_adstree, hf_ams_adscblength, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN);
offset+=(int)sizeof(guint32);
proto_tree_add_item(ams_adstree, hf_ams_adsdata, tvb, offset, ams_length-offset, ENC_NA);
}
}
}
break;
case ADSSRVID_READSTATE:
{
col_append_str(pinfo->cinfo, COL_INFO, "ADS Read State Response");
if( tree )
{
anItem = proto_tree_add_item(ams_tree, hf_ams_adsreadstateresponse, tvb, offset, ams_length-offset, ENC_NA);
if( ams_length-offset >= TAdsReadStateRes_Len )
{
ams_adstree = proto_item_add_subtree(anItem, ett_ams_adsreadstateresponse);
proto_tree_add_item(ams_adstree, hf_ams_adsresult, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN);
offset+=(int)sizeof(guint32);
proto_tree_add_item(ams_adstree, hf_ams_adsstate, tvb, offset, (int)sizeof(guint16), ENC_LITTLE_ENDIAN);
offset+=(int)sizeof(guint16);
proto_tree_add_item(ams_adstree, hf_ams_adsdevicestate, tvb, offset, (int)sizeof(guint16), ENC_LITTLE_ENDIAN);
}
}
}
break;
case ADSSRVID_WRITECTRL:
{
col_append_str(pinfo->cinfo, COL_INFO, "ADS Write Control Response");
if( tree )
{
anItem = proto_tree_add_item(ams_tree, hf_ams_adswritectrlresponse, tvb, offset, ams_length-offset, ENC_NA);
if( ams_length-offset >= TAdsWriteControlRes_Len )
{
ams_adstree = proto_item_add_subtree(anItem, ett_ams_adswritectrlresponse);
proto_tree_add_item(ams_adstree, hf_ams_adsresult, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN);
}
}
}
break;
case ADSSRVID_READDEVICEINFO:
{
col_append_str(pinfo->cinfo, COL_INFO, "ADS Read Device Info Response");
if( tree )
{
anItem = proto_tree_add_item(ams_tree, hf_ams_adsreaddinforesponse, tvb, offset, ams_length-offset, ENC_NA);
if( ams_length-offset >= TAdsReadDeviceInfoRes_Len )
{
ams_adstree = proto_item_add_subtree(anItem, ett_ams_adsreaddinforesponse);
proto_tree_add_item(ams_adstree, hf_ams_adsresult, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN);
offset+=(int)sizeof(guint32);
proto_tree_add_item(ams_adstree, hf_ams_adsversionversion, tvb, offset++, (int)sizeof(guint8), ENC_LITTLE_ENDIAN);
proto_tree_add_item(ams_adstree, hf_ams_adsversionrevision, tvb, offset++, (int)sizeof(guint8), ENC_LITTLE_ENDIAN);
proto_tree_add_item(ams_adstree, hf_ams_adsversionbuild, tvb, offset, (int)sizeof(guint16), ENC_LITTLE_ENDIAN);
offset+=(int)sizeof(guint16);
proto_tree_add_item(ams_adstree, hf_ams_adsdevicename, tvb, offset, ams_length-offset, ENC_ASCII|ENC_NA);
}
}
}
break;
case ADSSRVID_ADDDEVICENOTE:
{
col_append_str(pinfo->cinfo, COL_INFO, "ADS Device Notification Response");
if( tree )
{
anItem = proto_tree_add_item(ams_tree, hf_ams_adsadddnresponse, tvb, offset, ams_length-offset, ENC_NA);
if( ams_length-offset >= TAdsAddDeviceNotificationRes_Len )
{
ams_adstree = proto_item_add_subtree(anItem, ett_ams_adsadddnresponse);
proto_tree_add_item(ams_adstree, hf_ams_adsresult, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN);
offset+=(int)sizeof(guint32);
proto_tree_add_item(ams_adstree, hf_ams_adsnotificationhandle, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN);
}
}
}
break;
case ADSSRVID_DELDEVICENOTE:
{
col_append_str(pinfo->cinfo, COL_INFO, "ADS Delete Device Notification Response");
if( tree )
{
anItem = proto_tree_add_item(ams_tree, hf_ams_adsdeldnresponse, tvb, offset, ams_length-offset, ENC_NA);
if( ams_length-offset >= TAdsDelDeviceNotificationRes_Len )
{
ams_adstree = proto_item_add_subtree(anItem, ett_ams_adsdeldnresponse);
proto_tree_add_item(ams_adstree, hf_ams_adsresult, tvb, offset, (int)sizeof(guint32), ENC_LITTLE_ENDIAN);
}
}
}
break;
}
}
}
else
{
if ( (stateflags & AMSCMDSF_RESPONSE) == 0 )
col_append_str(pinfo->cinfo, COL_INFO, "AMS Request");
else
col_append_str(pinfo->cinfo, COL_INFO, "AMS Response");
if( tree && ams_length-offset > 0 )
proto_tree_add_item(ams_tree, hf_ams_data, tvb, offset, ams_length-offset, ENC_NA);
}
return offset;
}
/*ams*/
static gint dissect_ams(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
{
return dissect_ams_pdu(tvb, pinfo, tree, 0);
}
static gint dissect_amstcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
{
if( TcpAdsParserHDR_Len > tvb_reported_length(tvb))
return 0;
return dissect_ams_pdu(tvb, pinfo, tree, TcpAdsParserHDR_Len);
}
void proto_register_ams(void)
{
static const true_false_string flags_set_truth =
{
"Set",
"Not set"
};
static hf_register_info hf[] =
{
{ &hf_ams_sendernetid,
{ "AMS Sender Net Id", "ams.sendernetid",
FT_STRING, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_senderport,
{ "AMS Sender port", "ams.senderport",
FT_UINT16, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_targetnetid,
{ "AMS Target Net Id", "ams.targetnetid",
FT_STRING, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_targetport,
{ "AMS Target port", "ams.targetport",
FT_UINT16, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_cmdid,
{ "CmdId", "ams.cmdid",
FT_UINT16, BASE_DEC, VALS(AMS_CommandId_vals), 0x0,
NULL, HFILL }
},
{ &hf_ams_stateflags,
{ "StateFlags", "ams.stateflags",
FT_UINT16, BASE_HEX, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_stateresponse,
{ "RESPONSE", "ams.state_response",
FT_BOOLEAN, 16, TFS(&flags_set_truth), AMSCMDSF_RESPONSE,
NULL, HFILL }
},
{ &hf_ams_statenoreturn,
{ "NO RETURN", "ams.state_noreturn",
FT_BOOLEAN, 16, TFS(&flags_set_truth), AMSCMDSF_NORETURN,
NULL, HFILL }
},
{ &hf_ams_stateadscmd,
{ "ADS COMMAND", "ams.state_adscmd",
FT_BOOLEAN, 16, TFS(&flags_set_truth), AMSCMDSF_ADSCMD,
NULL, HFILL }
},
{ &hf_ams_statesyscmd,
{ "SYSTEM COMMAND", "ams.state_syscmd",
FT_BOOLEAN, 16, TFS(&flags_set_truth), AMSCMDSF_SYSCMD,
NULL, HFILL }
},
{ &hf_ams_statehighprio,
{ "HIGH PRIORITY COMMAND", "ams.state_highprio",
FT_BOOLEAN, 16, TFS(&flags_set_truth), AMSCMDSF_HIGHPRIO,
NULL, HFILL }
},
{ &hf_ams_statetimestampadded,
{ "TIMESTAMP ADDED", "ams.state_timestampadded",
FT_BOOLEAN, 16, TFS(&flags_set_truth), AMSCMDSF_TIMESTAMPADDED,
NULL, HFILL }
},
{ &hf_ams_stateudp,
{ "UDP COMMAND", "ams.state_udp",
FT_BOOLEAN, 16, TFS(&flags_set_truth), AMSCMDSF_UDP,
NULL, HFILL }
},
{ &hf_ams_stateinitcmd,
{ "INIT COMMAND", "ams.state_initcmd",
FT_BOOLEAN, 16, TFS(&flags_set_truth), AMSCMDSF_INITCMD,
NULL, HFILL }
},
{ &hf_ams_statebroadcast,
{ "BROADCAST", "ams.state_broadcast",
FT_BOOLEAN, 16, TFS(&flags_set_truth), AMSCMDSF_BROADCAST,
NULL, HFILL }
},
{ &hf_ams_cbdata,
{ "cbData", "ams.cbdata",
FT_UINT32, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_errorcode,
{ "ErrorCode", "ams.errorcode",
FT_UINT32, BASE_HEX, VALS(ErrorCode), 0x0,
NULL, HFILL }
},
{ &hf_ams_invokeid,
{ "InvokeId", "ams.invokeid",
FT_UINT32, BASE_HEX, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_adsdata,
{ "Data", "ams.ads_data",
FT_NONE, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_data,
{ "Data", "ams.data",
FT_NONE, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_adsindexgroup,
{ "IndexGroup", "ams.ads_indexgroup",
FT_UINT32, BASE_HEX, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_adsindexoffset,
{ "IndexOffset", "ams.ads_indexoffset",
FT_UINT32, BASE_HEX, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_adscblength,
{ "CbLength", "ams.ads_cblength",
FT_UINT32, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_adsreadrequest,
{ "ADS Read Request", "ams.ads_read_req",
FT_NONE, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_adsreadresponse,
{ "ADS Read Response", "ams.ads_read_res",
FT_NONE, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_adsinvokeid,
{ "InvokeId", "ams.ads_invokeid",
FT_UINT32, BASE_HEX, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_adsresult,
{ "Result", "ams.adsresult",
FT_UINT32, BASE_HEX, VALS(AdsErrorMode), 0x0,
NULL, HFILL }
},
{ &hf_ams_adswriterequest,
{ "ADS Write Request", "ams.ads_write_req",
FT_NONE, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_adswriteresponse,
{ "ADS Write Response", "ams.ads_write_res",
FT_NONE, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_adsreadwriterequest,
{ "ADS ReadWrite Request", "ams.ads_readwrite_req",
FT_NONE, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_adsreadwriteresponse,
{ "ADS ReadWrite Response", "ams.ads_readwrite_res",
FT_NONE, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_adscbreadlength,
{ "CBReadLength", "ams.ads_cbreadlength",
FT_UINT32, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_adscbwritelength,
{ "CBWriteLength", "ams.ads_cbwritelength",
FT_UINT32, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_adsstate,
{ "AdsState", "ams.ads_state",
FT_UINT16, BASE_HEX, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_adsdevicestate,
{ "DeviceState", "ams.ads_devicestate",
FT_UINT16, BASE_HEX, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_adsnotificationhandle,
{ "NotificationHandle", "ams.ads_notificationhandle",
FT_UINT32, BASE_HEX, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_adsreadstaterequest,
{ "ADS Read State Request", "ams.ads_readstate_req",
FT_NONE, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_adsreadstateresponse,
{ "ADS Read State Response", "ams.ads_readstate_res",
FT_NONE, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_adswritectrlrequest,
{ "ADS Write Ctrl Request", "ams.ads_writectrl_req",
FT_NONE, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_adswritectrlresponse,
{ "ADS Write Ctrl Response", "ams.ads_writectrl_res",
FT_NONE, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_adsreaddinforequest,
{ "ADS Read Device Info Request", "ams.ads_readdinfo_req",
FT_NONE, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_adsreaddinforesponse,
{ "ADS Read Device Info Response", "ams.ads_readdinfo_res",
FT_NONE, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_adsadddnrequest,
{ "ADS Add Device Notification Request", "ams.ads_adddn_req",
FT_NONE, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_adsadddnresponse,
{ "ADS Add Device Notification Response", "ams.ads_adddn_res",
FT_NONE, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_adsdeldnrequest,
{ "ADS Delete Device Notification Request", "ams.ads_deldn_req",
FT_NONE, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_adsdeldnresponse,
{ "ADS Delete Device Notification Response", "ams.ads_deldn_res",
FT_NONE, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_adsdnrequest,
{ "ADS Device Notification Request", "ams.ads_dn_req",
FT_NONE, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
#if 0
{ &hf_ams_adsdnresponse,
{ "ADS Device Notification Response", "ams.ads_dn_res",
FT_NONE, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_adsnoteattrib,
{ "InvokeId", "ams.ads_noteattrib",
FT_NONE, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_adsnoteblocks,
{ "InvokeId", "ams.ads_noteblocks",
FT_NONE, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_adsversion,
{ "ADS Version", "ams.ads_version",
FT_UINT32, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
#endif
{ &hf_ams_adsdevicename,
{ "Device Name","ams.ads_devicename",
FT_STRING, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_adsversionversion,
{ "ADS Major Version", "ams.ads_versionversion",
FT_UINT8, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_adsversionrevision,
{ "ADS Minor Version", "ams.ads_versionrevision",
FT_UINT8, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_adsversionbuild,
{ "ADS Version Build", "ams.ads_versionbuild",
FT_UINT16, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_adsnoteblocksstamps,
{ "Count of Stamps", "ams.ads_noteblocksstamps",
FT_UINT32, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
#if 0
{ &hf_ams_adsnoteblocksstamp,
{ "Notification Stamp", "ams.ads_noteblocksstamp",
FT_NONE, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_adstimestamp,
{ "Time Stamp", "ams.ads_timestamp",
FT_UINT64, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_adssamplecnt,
{ "Count of Stamps", "ams.ads_samplecnt",
FT_UINT32, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_adsnoteblockssample,
{ "Notification Sample", "ams.ads_noteblockssample",
FT_NONE, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
#endif
{ &hf_ams_adstransmode,
{ "Trans Mode", "ams.ads_transmode",
FT_UINT32, BASE_DEC, VALS(TransMode), 0x0,
NULL, HFILL }
},
{ &hf_ams_adsmaxdelay,
{ "Max Delay", "ams.ads_maxdelay",
FT_UINT32, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_adscycletime,
{ "Cycle Time", "ams.ads_cycletime",
FT_UINT32, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
#if 0
{ &hf_ams_adscmpmax,
{ "Cmp Mad", "ams.ads_cmpmax",
FT_NONE, BASE_NONE, NULL, 0x0,
NULL, HFILL }
},
{ &hf_ams_adscmpmin,
{ "Cmp Min", "ams.ads_cmpmin",
FT_NONE, BASE_NONE, NULL, 0x0,
NULL, HFILL }
}
#endif
};
static gint *ett[] =
{
&ett_ams,
&ett_ams_stateflags,
&ett_ams_adsreadrequest,
&ett_ams_adsreadresponse,
&ett_ams_adswriterequest,
&ett_ams_adswriteresponse,
&ett_ams_adsreadwriterequest,
&ett_ams_adsreadwriteresponse,
&ett_ams_adsreadstaterequest,
&ett_ams_adsreadstateresponse,
&ett_ams_adswritectrlrequest,
&ett_ams_adswritectrlresponse,
&ett_ams_adsreaddinforequest,
&ett_ams_adsreaddinforesponse,
&ett_ams_adsadddnrequest,
&ett_ams_adsadddnresponse,
&ett_ams_adsdeldnrequest,
&ett_ams_adsdeldnresponse,
&ett_ams_adsdnrequest
};
proto_ams = proto_register_protocol("AMS", "AMS", "ams");
proto_register_field_array(proto_ams, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
ams_handle = register_dissector("ams", dissect_ams, proto_ams);
}
/* The registration hand-off routing */
void proto_reg_handoff_ams(void)
{
dissector_handle_t amstcp_handle;
amstcp_handle = create_dissector_handle( dissect_amstcp, proto_ams );
dissector_add_uint_with_preference("tcp.port", AMS_TCP_PORT, amstcp_handle);
dissector_add_uint("ecatf.type", 2, ams_handle);
}
/*
* Editor modelines - https://www.wireshark.org/tools/modelines.html
*
* Local Variables:
* c-basic-offset: 3
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
* ex: set shiftwidth=3 tabstop=8 expandtab:
* :indentSize=3:tabSize=8:noTabs=true:
*/