aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/profinet
diff options
context:
space:
mode:
authorulfl <ulfl@f5534014-38df-0310-8fa8-9805f1628bb7>2005-04-30 20:52:20 +0000
committerulfl <ulfl@f5534014-38df-0310-8fa8-9805f1628bb7>2005-04-30 20:52:20 +0000
commit4c356420c3c22128d9a48c026d611ab6ddd76821 (patch)
treec7f782c4a8a83cee2605cff41c291eaa57527c9a /plugins/profinet
parent9b8f91b672b82c26fb3c2652f7041b7baad274f9 (diff)
move the profinet related files to a plugin (step by step), to make prototyping and further development easier (at least for me :-)
git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@14248 f5534014-38df-0310-8fa8-9805f1628bb7
Diffstat (limited to 'plugins/profinet')
-rw-r--r--plugins/profinet/AUTHORS3
-rw-r--r--plugins/profinet/COPYING340
-rw-r--r--plugins/profinet/ChangeLog16
-rw-r--r--plugins/profinet/INSTALL0
-rw-r--r--plugins/profinet/Makefile.am44
-rw-r--r--plugins/profinet/Makefile.nmake29
-rw-r--r--plugins/profinet/NEWS0
-rw-r--r--plugins/profinet/moduleinfo.h17
-rw-r--r--plugins/profinet/packet-dcerpc-pn-io.c1439
-rw-r--r--plugins/profinet/profinet.c73
10 files changed, 1961 insertions, 0 deletions
diff --git a/plugins/profinet/AUTHORS b/plugins/profinet/AUTHORS
new file mode 100644
index 0000000000..f0154bc9e4
--- /dev/null
+++ b/plugins/profinet/AUTHORS
@@ -0,0 +1,3 @@
+Author :
+Ulf Lamping <ulf.lamping@web.de>
+
diff --git a/plugins/profinet/COPYING b/plugins/profinet/COPYING
new file mode 100644
index 0000000000..fbdd65f6f8
--- /dev/null
+++ b/plugins/profinet/COPYING
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/plugins/profinet/ChangeLog b/plugins/profinet/ChangeLog
new file mode 100644
index 0000000000..dcd6347895
--- /dev/null
+++ b/plugins/profinet/ChangeLog
@@ -0,0 +1,16 @@
+$Id: ChangeLog 11400 2004-07-18 00:24:25Z guy $
+
+Overview of changes in Art-Net Ethereal plugin:
+
+Version 0.0.0:
+
+* initial implementation
+
+Version 0.0.1:
+
+* some experiments
+
+Version 0.1.0:
+
+* first official plugin
+
diff --git a/plugins/profinet/INSTALL b/plugins/profinet/INSTALL
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/plugins/profinet/INSTALL
diff --git a/plugins/profinet/Makefile.am b/plugins/profinet/Makefile.am
new file mode 100644
index 0000000000..46d330f80d
--- /dev/null
+++ b/plugins/profinet/Makefile.am
@@ -0,0 +1,44 @@
+# Makefile.am
+# Automake file for Ethereal/plugins/profinet
+#
+# $Id: Makefile.am 11400 2004-07-18 00:24:25Z guy $
+#
+# Ethereal - Network traffic analyzer
+# By Gerald Combs <gerald@ethereal.com>
+# Copyright 1998 Gerald Combs
+#
+# 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 2
+# 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+
+INCLUDES = -I$(top_srcdir)
+
+plugindir = @plugindir@
+
+plugin_LTLIBRARIES = profinet.la
+profinet_la_SOURCES = profinet.c packet-dcerpc-pn-io.c moduleinfo.h
+profinet_la_LDFLAGS = -module -avoid-version
+profinet_la_LIBADD = @PLUGIN_LIBS@
+
+# Libs must be cleared, or else libtool won't create a shared module.
+# If your module needs to be linked against any particular libraries,
+# add them here.
+LIBS =
+
+CLEANFILES = \
+ profinet \
+ *~
+
+EXTRA_DIST = \
+ Makefile.nmake
diff --git a/plugins/profinet/Makefile.nmake b/plugins/profinet/Makefile.nmake
new file mode 100644
index 0000000000..4a2368b4de
--- /dev/null
+++ b/plugins/profinet/Makefile.nmake
@@ -0,0 +1,29 @@
+#
+# $Id: Makefile.nmake 12176 2004-10-01 19:50:03Z guy $
+#
+
+include ..\..\config.nmake
+
+############### no need to modify below this line #########
+
+CFLAGS=/DHAVE_CONFIG_H /I../.. /I../../wiretap $(GLIB_CFLAGS) \
+ /I$(PCAP_DIR)\include -D_U_="" $(LOCAL_CFLAGS)
+
+LDFLAGS = /NOLOGO /INCREMENTAL:no /MACHINE:I386 $(LOCAL_LDFLAGS)
+
+!IFDEF ENABLE_LIBETHEREAL
+LINK_PLUGIN_WITH=..\..\epan\libethereal.lib
+CFLAGS=/DHAVE_WIN32_LIBETHEREAL_LIB /D_NEED_VAR_IMPORT_ $(CFLAGS)
+
+OBJECTS=profinet.obj packet-dcerpc-pn-io.obj
+
+profinet.dll profinet.exp profinet.lib : $(OBJECTS) $(LINK_PLUGIN_WITH)
+ link -dll /out:profinet.dll $(LDFLAGS) $(OBJECTS) $(LINK_PLUGIN_WITH) \
+ $(GLIB_LIBS)
+
+!ENDIF
+
+clean:
+ rm -f $(OBJECTS) profinet.dll profinet.exp profinet.lib *.pdb
+
+distclean: clean
diff --git a/plugins/profinet/NEWS b/plugins/profinet/NEWS
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/plugins/profinet/NEWS
diff --git a/plugins/profinet/moduleinfo.h b/plugins/profinet/moduleinfo.h
new file mode 100644
index 0000000000..939775092a
--- /dev/null
+++ b/plugins/profinet/moduleinfo.h
@@ -0,0 +1,17 @@
+/* Included *after* config.h, in order to re-define these macros */
+
+#ifdef PACKAGE
+#undef PACKAGE
+#endif
+
+/* Name of package */
+#define PACKAGE "profinet"
+
+
+#ifdef VERSION
+#undef VERSION
+#endif
+
+/* Version number of package */
+#define VERSION "0.1.0"
+
diff --git a/plugins/profinet/packet-dcerpc-pn-io.c b/plugins/profinet/packet-dcerpc-pn-io.c
new file mode 100644
index 0000000000..dc7cefd28c
--- /dev/null
+++ b/plugins/profinet/packet-dcerpc-pn-io.c
@@ -0,0 +1,1439 @@
+/* packet-dcerpc-pn-io.c
+ * Routines for PROFINET IO dissection.
+ *
+ * $Id$
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@ethereal.com>
+ * Copyright 1998 Gerald Combs
+ *
+ * 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * The PN-IO protocol is a field bus protocol related to decentralized
+ * periphery and is developed by the PROFIBUS Nutzerorganisation e.V. (PNO),
+ * see: www.profibus.com
+ *
+ *
+ * PN-IO is based on the common DCE-RPC and the "lightweight" PN-RT
+ * (ethernet type 0x8892) protocols.
+ *
+ * The context manager (CM) part is handling context information
+ * (like establishing, ...) and is using DCE-RPC as it's underlying
+ * protocol.
+ *
+ * The actual cyclic data transfer and acyclic notification uses the
+ * "lightweight" PN-RT protocol.
+ *
+ * There are some other related PROFINET protocols (e.g. PN-DCP, which is
+ * handling addressing topics).
+ *
+ * Please note: the PROFINET CBA protocol is independant of the PN-IO protocol!
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#include <string.h>
+
+#include <glib.h>
+#include <epan/packet.h>
+#include <epan/dissectors/packet-dcerpc.h>
+
+
+
+static int proto_pn_io = -1;
+
+static int hf_pn_io_opnum = -1;
+static int hf_pn_io_reserved16 = -1;
+
+static int hf_pn_io_array = -1;
+static int hf_pn_io_status = -1;
+static int hf_pn_io_args_max = -1;
+static int hf_pn_io_args_len = -1;
+static int hf_pn_io_array_max_count = -1;
+static int hf_pn_io_array_offset = -1;
+static int hf_pn_io_array_act_count = -1;
+
+static int hf_pn_io_data = -1;
+
+static int hf_pn_io_ar_uuid = -1;
+static int hf_pn_io_api = -1;
+static int hf_pn_io_slot_nr = -1;
+static int hf_pn_io_subslot_nr = -1;
+static int hf_pn_io_index = -1;
+static int hf_pn_io_seq_number = -1;
+static int hf_pn_io_record_data_length = -1;
+static int hf_pn_io_padding = -1;
+static int hf_pn_io_add_val1 = -1;
+static int hf_pn_io_add_val2 = -1;
+
+static int hf_pn_io_block = -1;
+static int hf_pn_io_block_type = -1;
+static int hf_pn_io_block_length = -1;
+static int hf_pn_io_block_version_high = -1;
+static int hf_pn_io_block_version_low = -1;
+
+static int hf_pn_io_sessionkey = -1;
+static int hf_pn_io_control_command = -1;
+static int hf_pn_io_control_command_prmend = -1;
+static int hf_pn_io_control_command_applready = -1;
+static int hf_pn_io_control_command_release = -1;
+static int hf_pn_io_control_command_done = -1;
+static int hf_pn_io_control_block_properties = -1;
+
+static int hf_pn_io_error_code = -1;
+static int hf_pn_io_error_decode = -1;
+static int hf_pn_io_error_code1 = -1;
+static int hf_pn_io_error_code2 = -1;
+static int hf_pn_io_error_code1_pniorw = -1;
+static int hf_pn_io_error_code1_pnio = -1;
+
+static int hf_pn_io_alarm_type = -1;
+static int hf_pn_io_alarm_specifier = -1;
+static int hf_pn_io_alarm_specifier_sequence = -1;
+static int hf_pn_io_alarm_specifier_channel = -1;
+static int hf_pn_io_alarm_specifier_manufacturer = -1;
+static int hf_pn_io_alarm_specifier_submodule = -1;
+static int hf_pn_io_alarm_specifier_ardiagnosis = -1;
+
+static int hf_pn_io_alarm_dst_endpoint = -1;
+static int hf_pn_io_alarm_src_endpoint = -1;
+static int hf_pn_io_pdu_type = -1;
+static int hf_pn_io_pdu_type_type = -1;
+static int hf_pn_io_pdu_type_version = -1;
+static int hf_pn_io_add_flags = -1;
+static int hf_pn_io_window_size = -1;
+static int hf_pn_io_tack = -1;
+static int hf_pn_io_send_seq_num = -1;
+static int hf_pn_io_ack_seq_num = -1;
+static int hf_pn_io_var_part_len = -1;
+
+static int hf_pn_io_module_ident_number = -1;
+static int hf_pn_io_submodule_ident_number = -1;
+
+static int hf_pn_io_ioxs = -1;
+static int hf_pn_io_ioxs_extension = -1;
+static int hf_pn_io_ioxs_res14 = -1;
+static int hf_pn_io_ioxs_instance = -1;
+static int hf_pn_io_ioxs_datastate = -1;
+
+
+static gint ett_pn_io = -1;
+static gint ett_pn_io_block = -1;
+static gint ett_pn_io_status = -1;
+static gint ett_pn_io_rtc = -1;
+static gint ett_pn_io_rta = -1;
+static gint ett_pn_io_pdu_type = -1;
+static gint ett_pn_io_add_flags = -1;
+static gint ett_pn_io_control_command = -1;
+static gint ett_pn_io_ioxs = -1;
+
+
+static e_uuid_t uuid_pn_io_device = { 0xDEA00001, 0x6C97, 0x11D1, { 0x82, 0x71, 0x00, 0xA0, 0x24, 0x42, 0xDF, 0x7D } };
+static guint16 ver_pn_io_device = 1;
+
+static e_uuid_t uuid_pn_io_controller = { 0xDEA00002, 0x6C97, 0x11D1, { 0x82, 0x71, 0x00, 0xA0, 0x24, 0x42, 0xDF, 0x7D } };
+static guint16 ver_pn_io_controller = 1;
+
+static e_uuid_t uuid_pn_io_supervisor = { 0xDEA00003, 0x6C97, 0x11D1, { 0x82, 0x71, 0x00, 0xA0, 0x24, 0x42, 0xDF, 0x7D } };
+static guint16 ver_pn_io_supervisor = 1;
+
+static e_uuid_t uuid_pn_io_parameterserver = { 0xDEA00004, 0x6C97, 0x11D1, { 0x82, 0x71, 0x00, 0xA0, 0x24, 0x42, 0xDF, 0x7D } };
+static guint16 ver_pn_io_parameterserver = 1;
+
+
+static const value_string pn_io_block_type[] = {
+ { 0x0000, "Reserved" },
+ { 0x0001, "Alarm Notification High"},
+ { 0x0002, "Alarm Notification Low"},
+ { 0x0008, "WriteRecordReq"},
+ { 0x8008, "WriteRecordRes"},
+ { 0x0009, "ReadRecordReq"},
+ { 0x8009, "ReadRecordRes"},
+ { 0x0010, "ManufacturerSpecificDiagnosisBlock"},
+ { 0x0011, "ChannelDiagnosisBlock"},
+ { 0x0012, "ExpectedIdentificationDataBlock"},
+ { 0x0014, "SubstituteValue RecordDataRead"},
+ { 0x0015, "RecordInputDataObjectElement"},
+ { 0x0016, "RecordOutputDataObjectElement"},
+ { 0x0017, "RecordOutputDataSubstituteObjectElement"},
+ { 0x0018, "ARData"},
+ { 0x0019, "LogData"},
+ { 0x001A, "APIData"},
+ { 0x0020, "I&M0"},
+ { 0x0021, "I&M1"},
+ { 0x0022, "I&M2"},
+ { 0x0023, "I&M3"},
+ { 0x0024, "I&M4"},
+ { 0x8001, "Alarm Ack High"},
+ { 0x8002, "Alarm Ack Low"},
+ { 0x0101, "ARBlockReq"},
+ { 0x8101, "ARBlockRes"},
+ { 0x0102, "IOCRBlockReq"},
+ { 0x8102, "IOCRBlockRes"},
+ { 0x0103, "AlarmCRBlockReq"},
+ { 0x8103, "AlarmCRBlockRes"},
+ { 0x0104, "ExpectedSubmoduleBlockReq"},
+ { 0x8104, "ModuleDiffBlock"},
+ { 0x0105, "PrmServerBlockReq"},
+ { 0x8105, "PrmServerBlockRes"},
+ { 0x0110, "IODBlockReq"},
+ { 0x8110, "IODBlockRes"},
+ { 0x0111, "IODBlockReq"},
+ { 0x8111, "IODBlockRes"},
+ { 0x0112, "IOXBlockReq"},
+ { 0x8112, "IOXBlockRes"},
+ { 0x0113, "IOXBlockReq"},
+ { 0x8113, "IOXBlockRes"},
+ { 0x0114, "ReleaseBlockReq"},
+ { 0x8114, "ReleaseBlockRes"},
+ { 0, NULL }
+};
+
+static const value_string pn_io_alarm_type[] = {
+ { 0x0000, "Reserved" },
+ { 0x0001, "Diagnosis" },
+ { 0x0002, "Process" },
+ { 0x0003, "Pull" },
+ { 0x0004, "Plug" },
+ { 0x0005, "Status" },
+ { 0x0006, "Update" },
+ { 0x0007, "Redundancy" },
+ { 0x0008, "Controlled by supervisor" },
+ { 0x0009, "Released by supervisor" },
+ { 0x000A, "Plug wrong submodule" },
+ { 0x000B, "Return of submodule" },
+ /* 0x000C - 0x001F reserved */
+ /* 0x0020 - 0x007F manufacturer specific */
+ /* 0x0080 - 0x00FF reserved for profiles */
+ /* 0x0100 - 0xFFFF reserved */
+ { 0, NULL }
+};
+
+static const value_string pn_io_pdu_type[] = {
+ { 0x01, "Data-RTA-PDU" },
+ { 0x02, "NACK-RTA-PDU" },
+ { 0x03, "ACK-RTA-PDU" },
+ { 0x04, "ERR-RTA-PDU" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_error_code[] = {
+ { 0x00, "OK" },
+ { 0x81, "PNIO" },
+ { 0xCF, "RTA error" },
+ { 0xDA, "AlarmAck" },
+ { 0xDB, "IODConnectRes" },
+ { 0xDC, "IODReleaseRes" },
+ { 0xDD, "IODControlRes" },
+ { 0xDE, "IODReadRes" },
+ { 0xDF, "IODWriteRes" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_error_decode[] = {
+ { 0x00, "OK" },
+ { 0x80, "PNIORW" },
+ { 0x81, "PNIO" },
+ { 0, NULL }
+};
+
+/*
+XXX: the next 2 are dependant on error_code and error_decode
+
+e.g.: CL-RPC error:
+error_code .. see above
+error_decode .. 0x81
+error_code1 .. 0x69
+error_code2 ..
+1 RPC_ERR_REJECTED
+2 RPC_ERR_FAULTED
+3 RPC_ERR_TIMEOUT
+4 RPC_ERR_IN_ARGS
+5 RPC_ERR_OUT_ARGS
+6 RPC_ERR_DECODE
+7 RPC_ERR_PNIO_OUT_ARGS
+8 Application Timeout
+*/
+
+/* XXX: add some more error codes here */
+static const value_string pn_io_error_code1[] = {
+ { 0x00, "OK" },
+ { 0, NULL }
+};
+
+/* XXX: add some more error codes here */
+static const value_string pn_io_error_code2[] = {
+ { 0x00, "OK" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_error_code1_pniorw[] = {
+ { 0x0a /* 10*/, "application" },
+ { 0x0b /* 11*/, "access" },
+ { 0x0c /* 12*/, "resource" },
+ { 0x0d /* 13*/, "user specific(13)" },
+ { 0x0e /* 14*/, "user specific(14)" },
+ { 0x0f /* 15*/, "user specific(15)" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_error_code1_pnio[] = {
+ { 0x00 /* 0*/, "Reserved" },
+ { 0x01 /* 1*/, "Connect: Faulty ARBlockReq" },
+ { 0x02 /* 2*/, "Connect: Faulty IOCRBlockReq" },
+ { 0x03 /* 3*/, "Connect: Faulty ExpectedSubmoduleBlockReq" },
+ { 0x04 /* 4*/, "Connect: Faulty AlarmCRBlockReq" },
+ { 0x05 /* 5*/, "Connect: Faulty PrmServerBlockReq" },
+
+ { 0x14 /* 20*/, "IODControl: Faulty ControlBlockConnect" },
+ { 0x15 /* 21*/, "IODControl: Faulty ControlBlockPlug" },
+ { 0x16 /* 22*/, "IOXControl: Faulty ControlBlock after a connect est." },
+ { 0x17 /* 23*/, "IOXControl: Faulty ControlBlock a plug alarm" },
+
+ { 0x28 /* 40*/, "Release: Faulty ReleaseBlock" },
+
+ { 0x3c /* 60*/, "AlarmAck Error Codes" },
+ { 0x3d /* 61*/, "CMDEV" },
+ { 0x3e /* 62*/, "CMCTL" },
+ { 0x3f /* 63*/, "NRPM" },
+ { 0x40 /* 64*/, "RMPM" },
+ { 0x41 /* 65*/, "ALPMI" },
+ { 0x42 /* 66*/, "ALPMR" },
+ { 0x43 /* 67*/, "LMPM" },
+ { 0x44 /* 68*/, "MMAC" },
+ { 0x45 /* 69*/, "RPC" },
+ { 0x46 /* 70*/, "APMR" },
+ { 0x47 /* 71*/, "APMS" },
+ { 0x48 /* 72*/, "CPM" },
+ { 0x49 /* 73*/, "PPM" },
+ { 0x4a /* 74*/, "DCPUCS" },
+ { 0x4b /* 75*/, "DCPUCR" },
+ { 0x4c /* 76*/, "DCPMCS" },
+ { 0x4d /* 77*/, "DCPMCR" },
+ { 0x4e /* 78*/, "FSPM" },
+ { 0xfd /*253*/, "RTA_ERR_CLS_PROTOCOL" },
+ { 0, NULL }
+};
+
+static const value_string pn_io_ioxs[] = {
+ { 0x00 /* 0*/, "detected by subslot" },
+ { 0x01 /* 1*/, "detected by slot" },
+ { 0x02 /* 2*/, "detected by IO device" },
+ { 0x03 /* 3*/, "detected by IO controller" },
+};
+
+
+/* dissect the four status (error) fields */
+static int
+dissect_PNIO_status(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+ guint8 u8ErrorCode;
+ guint8 u8ErrorDecode;
+ guint8 u8ErrorCode1;
+ guint8 u8ErrorCode2;
+
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ guint32 u32SubStart;
+ int bytemask = (drep[0] & 0x10) ? 3 : 0;
+ const value_string *error_code1_vals;
+
+
+
+ /* status */
+ sub_item = proto_tree_add_item(tree, hf_pn_io_status, tvb, offset, 0, FALSE);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_status);
+ u32SubStart = offset;
+
+ /* the PNIOStatus field is existing in both the RPC and the application data,
+ * depending on the current PDU.
+ * As the byte representation of these layers are different, this has to be handled
+ * in a somewhat different way than elsewhere. */
+
+ dissect_dcerpc_uint8(tvb, offset+(0^bytemask), pinfo, sub_tree, drep,
+ hf_pn_io_error_code, &u8ErrorCode);
+ dissect_dcerpc_uint8(tvb, offset+(1^bytemask), pinfo, sub_tree, drep,
+ hf_pn_io_error_decode, &u8ErrorDecode);
+
+ switch(u8ErrorDecode) {
+ case(0x80): /* PNIORW */
+ dissect_dcerpc_uint8(tvb, offset+(2^bytemask), pinfo, sub_tree, drep,
+ hf_pn_io_error_code1_pniorw, &u8ErrorCode1);
+ error_code1_vals = pn_io_error_code1_pniorw;
+ break;
+ case(0x81): /* PNIO */
+ dissect_dcerpc_uint8(tvb, offset+(2^bytemask), pinfo, sub_tree, drep,
+ hf_pn_io_error_code1_pnio, &u8ErrorCode1);
+ error_code1_vals = pn_io_error_code1_pnio;
+ break;
+ default:
+ dissect_dcerpc_uint8(tvb, offset+(2^bytemask), pinfo, sub_tree, drep,
+ hf_pn_io_error_code1, &u8ErrorCode1);
+ error_code1_vals = pn_io_error_code1;
+ }
+
+ /* XXX - this has to be decode specific too */
+ dissect_dcerpc_uint8(tvb, offset+(3^bytemask), pinfo, sub_tree, drep,
+ hf_pn_io_error_code2, &u8ErrorCode2);
+
+ offset +=4;
+
+ if(u8ErrorCode == 0 && u8ErrorDecode == 0 && u8ErrorCode1 == 0 && u8ErrorCode2 == 0) {
+ proto_item_append_text(sub_item, ": OK");
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_str(pinfo->cinfo, COL_INFO, ", OK");
+ } else {
+ proto_item_append_text(sub_item, ": Error Code: \"%s\", Decode: \"%s\", Code1: \"%s\" Code2: 0x%x",
+ val_to_str(u8ErrorCode, pn_io_error_code, "(0x%x)"),
+ val_to_str(u8ErrorDecode, pn_io_error_decode, "(0x%x)"),
+ val_to_str(u8ErrorCode1, error_code1_vals, "(0x%x)"),
+ u8ErrorCode2);
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", Error Code: %s, Decode: %s, Code1: 0x%x Code2: 0x%x",
+ val_to_str(u8ErrorCode, pn_io_error_code, "(0x%x)"),
+ val_to_str(u8ErrorDecode, pn_io_error_decode, "(0x%x)"),
+ u8ErrorCode1,
+ u8ErrorCode2);
+ }
+ proto_item_set_len(sub_item, offset - u32SubStart);
+
+ return offset;
+}
+
+
+/* dissect the alarm specifier */
+static int
+dissect_Alarm_specifier(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+ guint16 u16AlarmSpecifierSequence;
+ guint16 u16AlarmSpecifierChannel;
+ guint16 u16AlarmSpecifierManufacturer;
+ guint16 u16AlarmSpecifierSubmodule;
+ guint16 u16AlarmSpecifierAR;
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+ /* alarm specifier */
+ sub_item = proto_tree_add_item(tree, hf_pn_io_alarm_specifier, tvb, offset, 2, FALSE);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_pdu_type);
+
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_alarm_specifier_sequence, &u16AlarmSpecifierSequence);
+ u16AlarmSpecifierSequence &= 0x07FF;
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_alarm_specifier_channel, &u16AlarmSpecifierChannel);
+ u16AlarmSpecifierChannel = (u16AlarmSpecifierChannel &0x0800) >> 11;
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_alarm_specifier_manufacturer, &u16AlarmSpecifierManufacturer);
+ u16AlarmSpecifierManufacturer = (u16AlarmSpecifierManufacturer &0x1000) >> 12;
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_alarm_specifier_submodule, &u16AlarmSpecifierSubmodule);
+ u16AlarmSpecifierSubmodule = (u16AlarmSpecifierSubmodule & 0x2000) >> 13;
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_alarm_specifier_ardiagnosis, &u16AlarmSpecifierAR);
+ u16AlarmSpecifierAR = (u16AlarmSpecifierAR & 0x8000) >> 15;
+
+
+ proto_item_append_text(sub_item, ", Sequence: %u, Channel: %u, Manuf: %u, Submodule: %u AR: %u",
+ u16AlarmSpecifierSequence, u16AlarmSpecifierChannel,
+ u16AlarmSpecifierManufacturer, u16AlarmSpecifierSubmodule, u16AlarmSpecifierAR);
+
+ return offset;
+}
+
+
+/* dissect the alarm header */
+static int
+dissect_Alarm_header(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+ guint16 u16AlarmType;
+ guint32 u32Api;
+ guint16 u16SlotNr;
+ guint16 u16SubslotNr;
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_alarm_type, &u16AlarmType);
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_api, &u32Api);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_slot_nr, &u16SlotNr);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_subslot_nr, &u16SubslotNr);
+
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", %s, Slot: %u/%u",
+ val_to_str(u16AlarmType, pn_io_alarm_type, "Unknown"),
+ u16SlotNr, u16SubslotNr);
+
+ return offset;
+}
+
+
+/* dissect the alarm note block */
+static int
+dissect_Alarm_note_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep, guint16 body_length)
+{
+ guint32 u32ModuleIdentNumber;
+ guint32 u32SubmoduleIdentNumber;
+
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_str(pinfo->cinfo, COL_INFO, ", Alarm Notification");
+
+ offset = dissect_Alarm_header(tvb, offset, pinfo, tree, drep);
+
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_module_ident_number, &u32ModuleIdentNumber);
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_submodule_ident_number, &u32SubmoduleIdentNumber);
+
+ offset = dissect_Alarm_specifier(tvb, offset, pinfo, tree, drep);
+
+ /* XXX - dissect AlarmItem */
+ body_length -= 20;
+ proto_tree_add_string_format(tree, hf_pn_io_data, tvb, offset, body_length, "data",
+ "Alarm Item Data: %u bytes", body_length);
+ offset += body_length;
+
+ return offset;
+}
+
+
+/* dissect the alarm acknowledge block */
+static int
+dissect_Alarm_ack_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_str(pinfo->cinfo, COL_INFO, ", Alarm Ack");
+
+ offset = dissect_Alarm_header(tvb, offset, pinfo, tree, drep);
+
+ offset = dissect_Alarm_specifier(tvb, offset, pinfo, tree, drep);
+
+ offset = dissect_PNIO_status(tvb, offset, pinfo, tree, drep);
+
+ return offset;
+}
+
+
+/* dissect the read/write header */
+static int
+dissect_ReadWrite_header(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+ e_uuid_t uuid;
+ guint32 u32Api;
+ guint16 u16SlotNr;
+ guint16 u16SubslotNr;
+ guint16 u16Index;
+ guint16 u16SeqNr;
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_seq_number, &u16SeqNr);
+
+ offset = dissect_ndr_uuid_t(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_ar_uuid, &uuid);
+
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_api, &u32Api);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_slot_nr, &u16SlotNr);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_subslot_nr, &u16SubslotNr);
+ proto_tree_add_string_format(tree, hf_pn_io_padding, tvb, offset, 2, "padding", "Padding: 2 bytes");
+ offset += 2;
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_index, &u16Index);
+
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", Api: %u, Slot: %u/%u",
+ u32Api, u16SlotNr, u16SubslotNr);
+
+ return offset;
+}
+
+
+/* dissect the read/write request block */
+static int
+dissect_ReadWrite_rqst_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+ guint32 u32RecDataLen;
+
+
+ offset = dissect_ReadWrite_header(tvb, offset, pinfo, tree, drep);
+
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_record_data_length, &u32RecDataLen);
+ /* XXX: don't know how to handle the optional TargetARUUID */
+
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", %u bytes",
+ u32RecDataLen);
+
+ return offset;
+}
+
+
+/* dissect the read/write response block */
+static int
+dissect_ReadWrite_resp_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+ guint32 u32RecDataLen;
+ guint16 u16AddVal1;
+ guint16 u16AddVal2;
+
+
+ offset = dissect_ReadWrite_header(tvb, offset, pinfo, tree, drep);
+
+ offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_record_data_length, &u32RecDataLen);
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_add_val1, &u16AddVal1);
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_add_val2, &u16AddVal2);
+
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", %u bytes",
+ u32RecDataLen);
+
+ return offset;
+}
+
+
+/* dissect the control/connect block */
+static int
+dissect_ControlConnect_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+ e_uuid_t ar_uuid;
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ guint16 u16PrmEnd;
+ guint16 u16ApplReady;
+ guint16 u16Release;
+ guint16 u16CmdDone;
+
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_reserved16, NULL);
+
+ offset = dissect_ndr_uuid_t(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_ar_uuid, &ar_uuid);
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_sessionkey, NULL);
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_reserved16, NULL);
+
+ sub_item = proto_tree_add_item(tree, hf_pn_io_control_command, tvb, offset, 2, FALSE);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_control_command);
+
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_control_command_prmend, &u16PrmEnd);
+ if(u16PrmEnd & 0x0001) {
+ proto_item_append_text(sub_item, ", Parameter End");
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", Command: \"Parameter End\"");
+ }
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_control_command_applready, &u16ApplReady);
+ if((u16ApplReady >> 1) & 0x0001) {
+ proto_item_append_text(sub_item, ", Application Ready");
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", Command: \"Application Ready\"");
+ }
+ dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_control_command_release, &u16Release);
+ if((u16Release >> 2) & 0x0001) {
+ proto_item_append_text(sub_item, ", Release");
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", Command: \"Release\"");
+ }
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_control_command_done, &u16CmdDone);
+ if((u16CmdDone >> 3) & 0x0001) {
+ proto_item_append_text(sub_item, ", Done");
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", Command: \"Done\"");
+ }
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_control_block_properties, NULL);
+
+ return offset;
+}
+
+
+/* dissect one PN-IO block (depending on the block type) */
+static int
+dissect_block(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep, guint32 u32Idx)
+{
+ guint16 u16BlockType;
+ guint16 u16BlockLength;
+ guint8 u8BlockVersionHigh;
+ guint8 u8BlockVersionLow;
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ guint32 u32SubStart;
+ guint16 u16BodyLength;
+
+
+ /* from here, we only have big endian (network byte ordering) */
+ drep[0] &= ~0x10;
+
+ sub_item = proto_tree_add_item(tree, hf_pn_io_block, tvb, offset, 0, FALSE);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_block);
+ u32SubStart = offset;
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_block_type, &u16BlockType);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_block_length, &u16BlockLength);
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_block_version_high, &u8BlockVersionHigh);
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_block_version_low, &u8BlockVersionLow);
+
+ /* block length is without type and length fields, but with version field */
+ /* as it's already dissected, remove it */
+ u16BodyLength = u16BlockLength - 2;
+
+ switch(u16BlockType) {
+ case(0x0001):
+ case(0x0002):
+ dissect_Alarm_note_block(tvb, offset, pinfo, sub_tree, drep, u16BodyLength);
+ break;
+ case(0x0110):
+ case(0x0112):
+ case(0x0114):
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
+ val_to_str(u16BlockType, pn_io_block_type, "Unknown"));
+ dissect_ControlConnect_block(tvb, offset, pinfo, sub_tree, drep);
+ break;
+ case(0x0008):
+ case(0x0009):
+ dissect_ReadWrite_rqst_block(tvb, offset, pinfo, sub_tree, drep);
+ break;
+ case(0x8001):
+ case(0x8002):
+ dissect_Alarm_ack_block(tvb, offset, pinfo, sub_tree, drep);
+ break;
+ case(0x8008):
+ case(0x8009):
+ dissect_ReadWrite_resp_block(tvb, offset, pinfo, sub_tree, drep);
+ break;
+ case(0x8110):
+ case(0x8112):
+ case(0x8114):
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
+ val_to_str(u16BlockType, pn_io_block_type, "Unknown"));
+ dissect_ControlConnect_block(tvb, offset, pinfo, sub_tree, drep);
+ break;
+ default:
+ if (check_col(pinfo->cinfo, COL_INFO) && u32Idx < 3)
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
+ val_to_str(u16BlockType, pn_io_block_type, "Unknown"));
+ proto_tree_add_string_format(sub_tree, hf_pn_io_data, tvb, offset, u16BodyLength, "undecoded", "Undecoded Data: %d bytes", u16BodyLength);
+ }
+ offset += u16BodyLength;
+
+ proto_item_append_text(sub_item, "[%u]: Type=\"%s\" (0x%04x), Length=%u(+4), Version=%u.%u",
+ u32Idx, val_to_str(u16BlockType, pn_io_block_type, "Unknown"), u16BlockType,
+ u16BlockLength, u8BlockVersionHigh, u8BlockVersionLow);
+ proto_item_set_len(sub_item, offset - u32SubStart);
+
+ return offset;
+}
+
+
+/* dissect any number of PN-IO blocks */
+static int
+dissect_blocks(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+ guint32 u32Idx = 0;
+
+
+ while(tvb_length(tvb) > (guint) offset) {
+ offset = dissect_block(tvb, offset, pinfo, tree, drep, u32Idx);
+ u32Idx++;
+ }
+
+ if(u32Idx > 3) {
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", ... (%u blocks)",
+ u32Idx);
+ }
+ return offset;
+}
+
+
+/* dissect a PN-IO (DCE-RPC) request header */
+static int
+dissect_IPNIO_rqst_header(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+ guint32 u32ArgsMax;
+ guint32 u32ArgsLen;
+ guint32 u32MaxCount;
+ guint32 u32Offset;
+ guint32 u32ArraySize;
+
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ guint32 u32SubStart;
+
+
+ if (check_col(pinfo->cinfo, COL_PROTOCOL))
+ col_add_str(pinfo->cinfo, COL_PROTOCOL, "PNIO-CM");
+
+ /* args_max */
+ offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_args_max, &u32ArgsMax);
+ /* args_len */
+ offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_args_len, &u32ArgsLen);
+
+ sub_item = proto_tree_add_item(tree, hf_pn_io_array, tvb, offset, 0, FALSE);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io);
+ u32SubStart = offset;
+
+ /* RPC array header */
+ offset = dissect_ndr_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_array_max_count, &u32MaxCount);
+ offset = dissect_ndr_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_array_offset, &u32Offset);
+ offset = dissect_ndr_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_array_act_count, &u32ArraySize);
+
+ proto_item_append_text(sub_item, ": Max: %u, Offset: %u, Size: %u",
+ u32MaxCount, u32Offset, u32ArraySize);
+ proto_item_set_len(sub_item, offset - u32SubStart);
+
+ return offset;
+}
+
+
+/* dissect a PN-IO (DCE-RPC) response header */
+static int
+dissect_IPNIO_resp_header(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+ guint32 u32ArgsLen;
+ guint32 u32MaxCount;
+ guint32 u32Offset;
+ guint32 u32ArraySize;
+
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+ guint32 u32SubStart;
+
+
+ if (check_col(pinfo->cinfo, COL_PROTOCOL))
+ col_add_str(pinfo->cinfo, COL_PROTOCOL, "PNIO-CM");
+
+ offset = dissect_PNIO_status(tvb, offset, pinfo, tree, drep);
+
+ /* args_len */
+ offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+ hf_pn_io_args_len, &u32ArgsLen);
+
+ sub_item = proto_tree_add_item(tree, hf_pn_io_array, tvb, offset, 0, FALSE);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io);
+ u32SubStart = offset;
+
+ /* RPC array header */
+ offset = dissect_ndr_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_array_max_count, &u32MaxCount);
+ offset = dissect_ndr_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_array_offset, &u32Offset);
+ offset = dissect_ndr_uint32(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_array_act_count, &u32ArraySize);
+
+ proto_item_append_text(sub_item, ": Max: %u, Offset: %u, Size: %u",
+ u32MaxCount, u32Offset, u32ArraySize);
+ proto_item_set_len(sub_item, offset - u32SubStart);
+
+ return offset;
+}
+
+
+/* dissect a PN-IO connect request */
+static int
+dissect_IPNIO_Connect_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+
+ offset = dissect_IPNIO_rqst_header(tvb, offset, pinfo, tree, drep);
+
+ offset = dissect_blocks(tvb, offset, pinfo, tree, drep);
+
+ return offset;
+}
+
+
+/* dissect a PN-IO connect response */
+static int
+dissect_IPNIO_Connect_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+
+ offset = dissect_IPNIO_resp_header(tvb, offset, pinfo, tree, drep);
+
+ offset = dissect_blocks(tvb, offset, pinfo, tree, drep);
+
+ return offset;
+}
+
+
+/* dissect a PN-IO release request */
+static int
+dissect_IPNIO_Release_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+
+ offset = dissect_IPNIO_rqst_header(tvb, offset, pinfo, tree, drep);
+
+ offset = dissect_blocks(tvb, offset, pinfo, tree, drep);
+
+ return offset;
+}
+
+
+/* dissect a PN-IO release response */
+static int
+dissect_IPNIO_Release_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+
+ offset = dissect_IPNIO_resp_header(tvb, offset, pinfo, tree, drep);
+
+ offset = dissect_blocks(tvb, offset, pinfo, tree, drep);
+
+ return offset;
+}
+
+
+/* dissect a PN-IO control request */
+static int
+dissect_IPNIO_Control_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+
+ offset = dissect_IPNIO_rqst_header(tvb, offset, pinfo, tree, drep);
+
+ offset = dissect_blocks(tvb, offset, pinfo, tree, drep);
+
+ return offset;
+}
+
+
+/* dissect a PN-IO control response */
+static int
+dissect_IPNIO_Control_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+
+ offset = dissect_IPNIO_resp_header(tvb, offset, pinfo, tree, drep);
+
+ offset = dissect_blocks(tvb, offset, pinfo, tree, drep);
+
+ return offset;
+}
+
+
+/* dissect a PN-IO read request */
+static int
+dissect_IPNIO_Read_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+
+ offset = dissect_IPNIO_rqst_header(tvb, offset, pinfo, tree, drep);
+
+ offset = dissect_block(tvb, offset, pinfo, tree, drep, 0);
+
+ return offset;
+}
+
+
+/* dissect a PN-IO read response */
+static int
+dissect_IPNIO_Read_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+ gint remain;
+
+ offset = dissect_IPNIO_resp_header(tvb, offset, pinfo, tree, drep);
+
+ offset = dissect_block(tvb, offset, pinfo, tree, drep, 0);
+
+ /* XXX - remaining bytes: dissection not yet implemented */
+ remain = tvb_length_remaining(tvb, offset);
+ proto_tree_add_string_format(tree, hf_pn_io_data, tvb, offset, remain, "data", "User Data: %d bytes", remain);
+ offset += remain;
+
+ return offset;
+}
+
+
+/* dissect a PN-IO write request */
+static int
+dissect_IPNIO_Write_rqst(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+ gint remain;
+
+ offset = dissect_IPNIO_rqst_header(tvb, offset, pinfo, tree, drep);
+
+ offset = dissect_block(tvb, offset, pinfo, tree, drep, 0);
+
+ /* XXX - remaining bytes: dissection not yet implemented */
+ remain = tvb_length_remaining(tvb, offset);
+ proto_tree_add_string_format(tree, hf_pn_io_data, tvb, offset, remain, "data", "User Data: %d bytes", remain);
+ offset += remain;
+
+ return offset;
+}
+
+
+/* dissect a PN-IO write response */
+static int
+dissect_IPNIO_Write_resp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+
+ offset = dissect_IPNIO_resp_header(tvb, offset, pinfo, tree, drep);
+
+ offset = dissect_block(tvb, offset, pinfo, tree, drep, 0);
+
+ return offset;
+}
+
+
+/* dissect the IOxS (IOCS, IOPS) field */
+static int
+dissect_PNIO_IOxS(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tree, guint8 *drep _U_)
+{
+ guint8 u8IOxS;
+ proto_item *ioxs_item = NULL;
+ proto_tree *ioxs_tree = NULL;
+
+
+ u8IOxS = tvb_get_guint8(tvb, offset);
+
+ /* add ioxs subtree */
+ ioxs_item = proto_tree_add_uint_format(tree, hf_pn_io_ioxs,
+ tvb, offset, 1, u8IOxS,
+ "IOxS: 0x%02x (%s%s)",
+ u8IOxS,
+ (u8IOxS & 0x01) ? "another IOxS follows " : "",
+ (u8IOxS & 0x80) ? "good" : "bad");
+ ioxs_tree = proto_item_add_subtree(ioxs_item, ett_pn_io_ioxs);
+
+ proto_tree_add_uint(ioxs_tree, hf_pn_io_ioxs_extension, tvb, offset, 1, u8IOxS);
+ proto_tree_add_uint(ioxs_tree, hf_pn_io_ioxs_res14, tvb, offset, 1, u8IOxS);
+ proto_tree_add_uint(ioxs_tree, hf_pn_io_ioxs_instance, tvb, offset, 1, u8IOxS);
+ proto_tree_add_uint(ioxs_tree, hf_pn_io_ioxs_datastate, tvb, offset, 1, u8IOxS);
+
+ return offset + 1;
+}
+
+
+/* dissect a PN-IO Cyclic Service Data Unit (on top of PN-RT protocol) */
+static int
+dissect_PNIO_C_SDU(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+ proto_item *data_item;
+ proto_tree *data_tree;
+
+
+ if (check_col(pinfo->cinfo, COL_PROTOCOL))
+ col_add_str(pinfo->cinfo, COL_PROTOCOL, "PNIO");
+
+ if(tree) {
+ data_item = proto_tree_add_protocol_format(tree, proto_pn_io, tvb, offset, tvb_length(tvb),
+ "PROFINET IO Cyclic Service Data Unit: %u bytes", tvb_length(tvb));
+ data_tree = proto_item_add_subtree(data_item, ett_pn_io_rtc);
+
+ offset = dissect_PNIO_IOxS(tvb, offset, pinfo, data_tree, drep);
+
+ /* XXX - dissect the remaining data */
+ /* this will be one or more DataItems followed by an optional GAP and RTCPadding */
+ /* as we don't have the required context information to dissect the specific DataItems, this will be tricky :-( */
+ data_item = proto_tree_add_protocol_format(data_tree, proto_pn_io, tvb, offset, tvb_length_remaining(tvb, offset),
+ "Data: %u bytes (including GAP and RTCPadding)", tvb_length_remaining(tvb, offset));
+ }
+
+ return offset;
+}
+
+
+/* dissect a PN-IO RTA PDU (on top of PN-RT protocol) */
+static int
+dissect_PNIO_RTA(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+ guint16 u16AlarmDstEndpoint;
+ guint16 u16AlarmSrcEndpoint;
+ guint8 u8PDUType;
+ guint8 u8PDUVersion;
+ guint8 u8WindowSize;
+ guint8 u8Tack;
+ guint16 u16SendSeqNum;
+ guint16 u16AckSeqNum;
+ guint16 u16VarPartLen;
+ int start_offset = offset;
+
+ proto_item *rta_item;
+ proto_tree *rta_tree;
+
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+
+ if (check_col(pinfo->cinfo, COL_PROTOCOL))
+ col_add_str(pinfo->cinfo, COL_PROTOCOL, "PNIO-AL");
+
+ rta_item = proto_tree_add_protocol_format(tree, proto_pn_io, tvb, offset, tvb_length(tvb),
+ "PROFINET IO Alarm");
+ rta_tree = proto_item_add_subtree(rta_item, ett_pn_io_rta);
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, rta_tree, drep,
+ hf_pn_io_alarm_dst_endpoint, &u16AlarmDstEndpoint);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, rta_tree, drep,
+ hf_pn_io_alarm_src_endpoint, &u16AlarmSrcEndpoint);
+
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", Src: 0x%x, Dst: 0x%x",
+ u16AlarmSrcEndpoint, u16AlarmDstEndpoint);
+
+ /* PDU type */
+ sub_item = proto_tree_add_item(rta_tree, hf_pn_io_pdu_type, tvb, offset, 1, FALSE);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_pdu_type);
+ dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_pdu_type_type, &u8PDUType);
+ u8PDUType &= 0x0F;
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_pdu_type_version, &u8PDUVersion);
+ u8PDUVersion >>= 4;
+ proto_item_append_text(sub_item, ", Type: %s, Version: %u",
+ val_to_str(u8PDUType, pn_io_pdu_type, "Unknown"),
+ u8PDUVersion);
+
+ /* additional flags */
+ sub_item = proto_tree_add_item(rta_tree, hf_pn_io_add_flags, tvb, offset, 1, FALSE);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_add_flags);
+ dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_window_size, &u8WindowSize);
+ u8WindowSize &= 0x0F;
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_tack, &u8Tack);
+ u8Tack >>= 4;
+ proto_item_append_text(sub_item, ", Window Size: %u, Tack: %u",
+ u8WindowSize, u8Tack);
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, rta_tree, drep,
+ hf_pn_io_send_seq_num, &u16SendSeqNum);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, rta_tree, drep,
+ hf_pn_io_ack_seq_num, &u16AckSeqNum);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, rta_tree, drep,
+ hf_pn_io_var_part_len, &u16VarPartLen);
+
+ switch(u8PDUType & 0x0F) {
+ case(1): /* Data-RTA */
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_str(pinfo->cinfo, COL_INFO, ", Data-RTA");
+ offset = dissect_block(tvb, offset, pinfo, rta_tree, drep, 0);
+ break;
+ case(2): /* NACK-RTA */
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_str(pinfo->cinfo, COL_INFO, ", NACK-RTA");
+ /* no additional data */
+ break;
+ case(3): /* ACK-RTA */
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_str(pinfo->cinfo, COL_INFO, ", ACK-RTA");
+ /* no additional data */
+ break;
+ case(4): /* ERR-RTA */
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_str(pinfo->cinfo, COL_INFO, ", ERR-RTA");
+ offset = dissect_PNIO_status(tvb, offset, pinfo, rta_tree, drep);
+ break;
+ default:
+ proto_tree_add_string_format(tree, hf_pn_io_data, tvb, 0, tvb_length(tvb), "data",
+ "PN-IO Alarm: unknown PDU type 0x%x", u8PDUType);
+ }
+
+ proto_item_set_len(rta_item, offset - start_offset);
+
+ return offset;
+}
+
+
+/* possibly dissect a PN-IO related PN-RT packet */
+static gboolean
+dissect_PNIO_heur(tvbuff_t *tvb,
+ packet_info *pinfo, proto_tree *tree)
+{
+ guint8 drep_data = 0;
+ guint8 *drep = &drep_data;
+ guint8 u8CBAVersion;
+ guint16 u16FrameID;
+
+
+ /* the sub tvb will NOT contain the frame_id here! */
+ u16FrameID = GPOINTER_TO_UINT(pinfo->private_data);
+
+ u8CBAVersion = tvb_get_guint8 (tvb, 0);
+
+ /* is this a PNIO class 2 data packet? */
+ /* frame id must be in valid range (cyclic Real-Time, class=2) */
+ if (u16FrameID >= 0x8000 && u16FrameID < 0xbf00) {
+ dissect_PNIO_C_SDU(tvb, 0, pinfo, tree, drep);
+ return TRUE;
+ }
+
+ /* is this a PNIO class 1 data packet? */
+ /* frame id must be in valid range (cyclic Real-Time, class=1) and
+ * first byte (CBA version field) has to be != 0x11 */
+ if (u16FrameID >= 0xc000 && u16FrameID < 0xfb00 && u8CBAVersion != 0x11) {
+ dissect_PNIO_C_SDU(tvb, 0, pinfo, tree, drep);
+ return TRUE;
+ }
+
+ /* is this a PNIO high priority alarm packet? */
+ if(u16FrameID == 0xfc01) {
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_add_str(pinfo->cinfo, COL_INFO, "Alarm High");
+
+ dissect_PNIO_RTA(tvb, 0, pinfo, tree, drep);
+ return TRUE;
+ }
+
+ /* is this a PNIO low priority alarm packet? */
+ if(u16FrameID == 0xfe01) {
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_add_str(pinfo->cinfo, COL_INFO, "Alarm Low");
+
+ dissect_PNIO_RTA(tvb, 0, pinfo, tree, drep);
+ return TRUE;
+ }
+
+ /* this PN-RT packet doesn't seem to be PNIO specific */
+ return FALSE;
+}
+
+
+/* the PNIO dcerpc interface table */
+static dcerpc_sub_dissector pn_io_dissectors[] = {
+{ 0, "Connect", dissect_IPNIO_Connect_rqst, dissect_IPNIO_Connect_resp },
+{ 1, "Release", dissect_IPNIO_Release_rqst, dissect_IPNIO_Release_resp },
+{ 2, "Read", dissect_IPNIO_Read_rqst, dissect_IPNIO_Read_resp },
+{ 3, "Write", dissect_IPNIO_Write_rqst, dissect_IPNIO_Write_resp },
+{ 4, "Control", dissect_IPNIO_Control_rqst, dissect_IPNIO_Control_resp },
+ { 0, NULL, NULL, NULL }
+};
+
+
+void
+proto_register_pn_io (void)
+{
+ static hf_register_info hf[] = {
+ { &hf_pn_io_opnum,
+ { "Operation", "pn_io.opnum", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_pn_io_reserved16,
+ { "Reserved", "pn_io.reserved16", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }},
+ { &hf_pn_io_array,
+ { "Array", "pn_io.array", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }},
+ { &hf_pn_io_status,
+ { "Status", "pn_io.status", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }},
+ { &hf_pn_io_args_max,
+ { "ArgsMaximum", "pn_io.args_max", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_pn_io_args_len,
+ { "ArgsLength", "pn_io.args_len", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_pn_io_array_max_count,
+ { "MaximumCount", "pn_io.array_max_count", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_pn_io_array_offset,
+ { "Offset", "pn_io.array_offset", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_pn_io_array_act_count,
+ { "ActualCount", "pn_io.array_act_count", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_pn_io_ar_uuid,
+ { "ARUUID", "pn_io.ar_uuid", FT_STRING, BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_pn_io_api,
+ { "API", "pn_io.api", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
+ { &hf_pn_io_slot_nr,
+ { "SlotNumber", "pn_io.slot_nr", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_pn_io_subslot_nr,
+ { "SubslotNumber", "pn_io.subslot_nr", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_pn_io_index,
+ { "Index", "pn_io.index", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_pn_io_seq_number,
+ { "SeqNumber", "pn_io.seq_number", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_pn_io_record_data_length,
+ { "RecordDataLength", "pn_io.record_data_length", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_pn_io_padding,
+ { "Padding", "pn_io.padding", FT_STRING, BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_pn_io_add_val1,
+ { "AdditionalValue1", "pn_io.add_val1", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_pn_io_add_val2,
+ { "AdditionalValue2", "pn_io.add_val2", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_pn_io_block_type,
+ { "BlockType", "pn_io.block_type", FT_UINT16, BASE_HEX, VALS(pn_io_block_type), 0x0, "", HFILL }},
+ { &hf_pn_io_block_length,
+ { "BlockLength", "pn_io.block_length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_pn_io_block_version_high,
+ { "BlockVersionHigh", "pn_io.block_version_high", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_pn_io_block_version_low,
+ { "BlockVersionLow", "pn_io.block_version_low", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_pn_io_sessionkey,
+ { "SessionKey", "pn_io.session_key", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_pn_io_control_command,
+ { "ControlCommand", "pn_io.control_command", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }},
+ { &hf_pn_io_control_command_prmend,
+ { "PrmEnd", "pn_io.control_command.prmend", FT_UINT16, BASE_DEC, NULL, 0x0001, "", HFILL }},
+ { &hf_pn_io_control_command_applready,
+ { "ApplicationReady", "pn_io.control_command.applready", FT_UINT16, BASE_DEC, NULL, 0x0002, "", HFILL }},
+ { &hf_pn_io_control_command_release,
+ { "Release", "pn_io.control_command.release", FT_UINT16, BASE_DEC, NULL, 0x0004, "", HFILL }},
+ { &hf_pn_io_control_command_done,
+ { "Done", "pn_io.control_command.done", FT_UINT16, BASE_DEC, NULL, 0x0008, "", HFILL }},
+ { &hf_pn_io_control_block_properties,
+ { "ControlBlockProperties", "pn_io.control_block_properties", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
+
+ { &hf_pn_io_error_code,
+ { "ErrorCode", "pn_io.error_code", FT_UINT8, BASE_HEX, VALS(pn_io_error_code), 0x0, "", HFILL }},
+ { &hf_pn_io_error_decode,
+ { "ErrorDecode", "pn_io.error_decode", FT_UINT8, BASE_HEX, VALS(pn_io_error_decode), 0x0, "", HFILL }},
+ { &hf_pn_io_error_code1,
+ { "ErrorCode1", "pn_io.error_code1", FT_UINT8, BASE_HEX, VALS(pn_io_error_code1), 0x0, "", HFILL }},
+ { &hf_pn_io_error_code2,
+ { "ErrorCode2", "pn_io.error_code2", FT_UINT8, BASE_HEX, VALS(pn_io_error_code2), 0x0, "", HFILL }},
+ { &hf_pn_io_error_code1_pniorw,
+ { "ErrorCode1 (PNIORW)", "pn_io.error_code1", FT_UINT8, BASE_HEX, VALS(pn_io_error_code1_pniorw), 0x0, "", HFILL }},
+ { &hf_pn_io_error_code1_pnio,
+ { "ErrorCode1 (PNIO)", "pn_io.error_code1", FT_UINT8, BASE_HEX, VALS(pn_io_error_code1_pnio), 0x0, "", HFILL }},
+ { &hf_pn_io_block,
+ { "Block", "pn_io.block", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }},
+ { &hf_pn_io_data,
+ { "Undecoded Data", "pn_io.data", FT_STRING, BASE_DEC, NULL, 0x0, "", HFILL }},
+
+ { &hf_pn_io_alarm_type,
+ { "AlarmType", "pn_io.alarm_type", FT_UINT16, BASE_HEX, VALS(pn_io_alarm_type), 0x0, "", HFILL }},
+
+ { &hf_pn_io_alarm_specifier,
+ { "AlarmSpecifier", "pn_io.alarm_specifier", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }},
+ { &hf_pn_io_alarm_specifier_sequence,
+ { "SequenceNumber", "pn_io.alarm_specifier.sequence", FT_UINT16, BASE_HEX, NULL, 0x07FF, "", HFILL }},
+ { &hf_pn_io_alarm_specifier_channel,
+ { "ChannelDiagnosis", "pn_io.alarm_specifier.channel", FT_UINT16, BASE_HEX, NULL, 0x0800, "", HFILL }},
+ { &hf_pn_io_alarm_specifier_manufacturer,
+ { "ManufacturerSpecificDiagnosis", "pn_io.alarm_specifier.manufacturer", FT_UINT16, BASE_HEX, NULL, 0x1000, "", HFILL }},
+ { &hf_pn_io_alarm_specifier_submodule,
+ { "SubmoduleDiagnosisState", "pn_io.alarm_specifier.submodule", FT_UINT16, BASE_HEX, NULL, 0x2000, "", HFILL }},
+ { &hf_pn_io_alarm_specifier_ardiagnosis,
+ { "ARDiagnosisState", "pn_io.alarm_specifier.ardiagnosis", FT_UINT16, BASE_HEX, NULL, 0x8000, "", HFILL }},
+
+ { &hf_pn_io_alarm_dst_endpoint,
+ { "AlarmDstEndpoint", "pn_io.alarm_dst_endpoint", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }},
+ { &hf_pn_io_alarm_src_endpoint,
+ { "AlarmSrcEndpoint", "pn_io.alarm_src_endpoint", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }},
+ { &hf_pn_io_pdu_type,
+ { "PDUType", "pn_io.pdu_type", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }},
+ { &hf_pn_io_pdu_type_type,
+ { "Type", "pn_io.pdu_type.type", FT_UINT8, BASE_HEX, VALS(pn_io_pdu_type), 0x0F, "", HFILL }},
+ { &hf_pn_io_pdu_type_version,
+ { "Version", "pn_io.pdu_type.version", FT_UINT8, BASE_HEX, NULL, 0xF0, "", HFILL }},
+ { &hf_pn_io_add_flags,
+ { "AddFlags", "pn_io.add_flags", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }},
+ { &hf_pn_io_window_size,
+ { "WindowSize", "pn_io.window_size", FT_UINT8, BASE_DEC, NULL, 0x0F, "", HFILL }},
+ { &hf_pn_io_tack,
+ { "TACK", "pn_io.tack", FT_UINT8, BASE_HEX, NULL, 0xF0, "", HFILL }},
+ { &hf_pn_io_send_seq_num,
+ { "SendSeqNum", "pn_io.send_seq_num", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }},
+ { &hf_pn_io_ack_seq_num,
+ { "AckSeqNum", "pn_io.ack_seq_num", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }},
+ { &hf_pn_io_var_part_len,
+ { "VarPartLen", "pn_io.var_part_len", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }},
+ { &hf_pn_io_module_ident_number,
+ { "ModuleIdentNumber", "pn_io.module_ident_number", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
+ { &hf_pn_io_submodule_ident_number,
+ { "SubmoduleIdentNumber", "pn_io.submodule_ident_number", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
+
+ { &hf_pn_io_ioxs,
+ { "IOxS", "pn_io.ioxs", FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL }},
+ { &hf_pn_io_ioxs_extension,
+ { "Extension (1:another IOxS follows/0:no IOxS follows)", "pn_io.ioxs.extension", FT_UINT8, BASE_HEX, NULL, 0x01, "", HFILL }},
+ { &hf_pn_io_ioxs_res14,
+ { "Reserved (should be zero)", "pn_io.ioxs.res14", FT_UINT8, BASE_HEX, NULL, 0x1E, "", HFILL }},
+ { &hf_pn_io_ioxs_instance,
+ { "Instance (only valid, if DataState is bad)", "pn_io.ioxs.instance", FT_UINT8, BASE_HEX, VALS(pn_io_ioxs), 0x60, "", HFILL }},
+ { &hf_pn_io_ioxs_datastate,
+ { "DataState (1:good/0:bad)", "pn_io.ioxs.datastate", FT_UINT8, BASE_HEX, NULL, 0x80, "", HFILL }}
+ };
+
+ static gint *ett[] = {
+ &ett_pn_io,
+ &ett_pn_io_block,
+ &ett_pn_io_status,
+ &ett_pn_io_rtc,
+ &ett_pn_io_rta,
+ &ett_pn_io_pdu_type,
+ &ett_pn_io_add_flags,
+ &ett_pn_io_control_command,
+ &ett_pn_io_ioxs
+ };
+
+ proto_pn_io = proto_register_protocol ("PROFINET IO", "PNIO", "pn_io");
+ proto_register_field_array (proto_pn_io, hf, array_length (hf));
+ proto_register_subtree_array (ett, array_length (ett));
+}
+
+void
+proto_reg_handoff_pn_io (void)
+{
+ /* Register the protocols as dcerpc */
+ dcerpc_init_uuid (proto_pn_io, ett_pn_io, &uuid_pn_io_device, ver_pn_io_device, pn_io_dissectors, hf_pn_io_opnum);
+ dcerpc_init_uuid (proto_pn_io, ett_pn_io, &uuid_pn_io_controller, ver_pn_io_controller, pn_io_dissectors, hf_pn_io_opnum);
+ dcerpc_init_uuid (proto_pn_io, ett_pn_io, &uuid_pn_io_supervisor, ver_pn_io_supervisor, pn_io_dissectors, hf_pn_io_opnum);
+ dcerpc_init_uuid (proto_pn_io, ett_pn_io, &uuid_pn_io_parameterserver, ver_pn_io_parameterserver, pn_io_dissectors, hf_pn_io_opnum);
+
+ heur_dissector_add("pn_rt", dissect_PNIO_heur, proto_pn_io);
+}
diff --git a/plugins/profinet/profinet.c b/plugins/profinet/profinet.c
new file mode 100644
index 0000000000..4915936924
--- /dev/null
+++ b/plugins/profinet/profinet.c
@@ -0,0 +1,73 @@
+/* profinet-plugin.c
+ * Routines for the PROFINET plugin
+ *
+ * $Id: profinet-plugin.c 12115 2004-09-27 22:55:15Z guy $
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@ethereal.com>
+ * Copyright 1999 Gerald Combs
+ *
+ * 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/* Include files */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "moduleinfo.h"
+#include <gmodule.h>
+
+#include <glib.h>
+
+/* Define version if we are not building ethereal statically */
+
+#ifndef ENABLE_STATIC
+G_MODULE_EXPORT const gchar version[] = VERSION;
+#endif
+
+gboolean plugin_registered = FALSE;
+
+/* XXX */
+extern void proto_register_pn_io (void);
+extern void proto_reg_handoff_pn_io (void);
+
+
+
+/* Start the functions we need for the plugin stuff */
+
+#ifndef ENABLE_STATIC
+
+G_MODULE_EXPORT void
+plugin_register(void)
+{
+ /* register the new protocol, protocol fields, and subtrees */
+ if (plugin_registered == FALSE) { /* execute protocol initialization only once */
+ proto_register_pn_io();
+
+ plugin_registered = TRUE;
+ }
+}
+
+G_MODULE_EXPORT void
+plugin_reg_handoff(void){
+ proto_reg_handoff_pn_io();
+}
+
+#endif
+
+/* End the functions we need for plugin stuff */
+