diff --git a/plugins/ethercat/AUTHORS b/plugins/ethercat/AUTHORS new file mode 100644 index 0000000000..8e9f8dae72 --- /dev/null +++ b/plugins/ethercat/AUTHORS @@ -0,0 +1,5 @@ +Author : +Richard Kuemmel + +Updates and bugfixes: +Peter Johansson diff --git a/plugins/ethercat/COPYING b/plugins/ethercat/COPYING new file mode 100644 index 0000000000..2cc56d616c --- /dev/null +++ b/plugins/ethercat/COPYING @@ -0,0 +1,696 @@ + 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. + + + Copyright (C) + + 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. + + , 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. +Wireshark is distributed under the GNU GPL. There are no restrictions +on its use. There are significant restrictions on its distribution. + +Parts of Wireshark can be built and distributed as libraries. These +parts are still covered by the GPL, and NOT by the Lesser General Public +License or any other license. + +If you create a combined work using all or part of Wireshark, then your +combined work must be released under a license compatible with the GPL. + +...and don't get us started on trademarks. + +The full text of the GNU GPL follows. + +------------------------------------------------------------------------ + + 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. + + + Copyright (C) 19yy + + 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) 19yy 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. + + , 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/ethercat/Makefile.am b/plugins/ethercat/Makefile.am new file mode 100644 index 0000000000..dbcf5785f9 --- /dev/null +++ b/plugins/ethercat/Makefile.am @@ -0,0 +1,118 @@ +# Makefile.am +# Automake file for EtherCAT plugin +# +# $Id$ +# +# Wireshark - Network traffic analyzer +# By Gerald Combs +# 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) -I$(includedir) + +include Makefile.common + +plugindir = @plugindir@ + +plugin_LTLIBRARIES = ethercat.la +ethercat_la_SOURCES = \ + plugin.c \ + moduleinfo.h \ + $(DISSECTOR_SRC) \ + $(DISSECTOR_INCLUDES) +ethercat_la_LDFLAGS = -module -avoid-version +ethercat_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 = + +# +# Build plugin.c, which contains the plugin version[] string, a +# function plugin_register() that calls the register routines for all +# protocols, and a function plugin_reg_handoff() that calls the handoff +# registration routines for all protocolsagentx_la. +# +# We do this by scanning sources. If that turns out to be too slow, +# maybe we could just require every .o file to have an register routine +# of a given name (packet-aarp.o -> proto_register_aarp, etc.). +# +# Formatting conventions: The name of the proto_register_* routines an +# proto_reg_handoff_* routines must start in column zero, or must be +# preceded only by "void " starting in column zero, and must not be +# inside #if. +# +# DISSECTOR_SRC is assumed to have all the files that need to be scanned. +# +# For some unknown reason, having a big "for" loop in the Makefile +# to scan all the files doesn't work with some "make"s; they seem to +# pass only the first few names in the list to the shell, for some +# reason. +# +# Therefore, we have a script to generate the plugin.c file. +# The shell script runs slowly, as multiple greps and seds are run +# for each input file; this is especially slow on Windows. Therefore, +# if Python is present (as indicated by PYTHON being defined), we run +# a faster Python script to do that work instead. +# +# The first argument is the directory in which the source files live. +# The second argument is "plugin", to indicate that we should build +# a plugin.c file for a plugin. +# All subsequent arguments are the files to scan. +# +plugin.c: $(DISSECTOR_SRC) $(top_srcdir)/tools/make-dissector-reg \ + $(top_srcdir)/tools/make-dissector-reg.py + @if test -n $(PYTHON); then \ + echo Making plugin.c with python ; \ + $(PYTHON) $(top_srcdir)/tools/make-dissector-reg.py $(srcdir) \ + plugin $(DISSECTOR_SRC) ; \ + else \ + echo Making plugin.c with shell script ; \ + $(top_srcdir)/tools/make-dissector-reg $(srcdir) \ + $(plugin_src) plugin $(DISSECTOR_SRC) ; \ + fi + +# +# Currently plugin.c can be included in the distribution because +# we always build all protocol dissectors. We used to have to check +# whether or not to build the snmp dissector. If we again need to +# variably build something, making plugin.c non-portable, uncomment +# the dist-hook line below. +# +# Oh, yuk. We don't want to include "plugin.c" in the distribution, as +# its contents depend on the configuration, and therefore we want it +# to be built when the first "make" is done; however, Automake insists +# on putting *all* source into the distribution. +# +# We work around this by having a "dist-hook" rule that deletes +# "plugin.c", so that "dist" won't pick it up. +# +#dist-hook: +# @rm -f $(distdir)/plugin.c + +CLEANFILES = \ + ethercat \ + *~ + +MAINTAINERCLEANFILES = \ + Makefile.in \ + plugin.c + +EXTRA_DIST = \ + Makefile.common \ + Makefile.nmake diff --git a/plugins/ethercat/Makefile.common b/plugins/ethercat/Makefile.common new file mode 100644 index 0000000000..555fe2b557 --- /dev/null +++ b/plugins/ethercat/Makefile.common @@ -0,0 +1,296 @@ +# Makefile.common for EtherCAT plugin +# Contains the stuff from Makefile.am and Makefile.nmake that is +# a) common to both files and +# b) portable between both files +# +# $Id$ +# +# Wireshark - Network traffic analyzer +# By Gerald Combs +# 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 name of the plugin +PLUGIN_NAME = ethercat + +# the dissector sources (without any helpers) +DISSECTOR_SRC = \ + packet-ethercat-frame.c \ + packet-ioraw.c \ + packet-nv.c \ + packet-ams.c \ + packet-ecatmb.c \ + packet-ethercat-datagram.c + +# corresponding headers +DISSECTOR_INCLUDES = \ + packet-ams.h \ + packet-ethercat-frame.h \ + packet-ecatmb.h \ + packet-ethercat-datagram.h \ + packet-ioraw.h \ + packet-nv.h +# Makefile.common +# Contains the stuff from Makefile.am and Makefile.nmake that is +# a) common to both files and +# b) portable between both files +# +# $Id$ +# +# Wireshark - Network traffic analyzer +# By Gerald Combs +# 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. + +# "BUILT_SOURCES" are built before any "make all" or "make check" targets. +BUILT_HEADER_FILES = \ + svnversion.h + +BUILT_C_FILES = \ + ps.c + +BUILT_SOURCES = $(BUILT_C_FILES) $(BUILT_HEADER_FILES) + +# Header files generated from source files. +GENERATED_HEADER_FILES = \ + $(BUILT_HEADER_FILES) + +# C source files generated from source files. +GENERATED_C_FILES = \ + $(BUILT_C_FILES) \ + tshark-tap-register.c + +# All the generated files. +GENERATED_FILES = $(GENERATED_C_FILES) $(GENERATED_HEADER_FILES) + +# sources common for wireshark and tshark +WIRESHARK_COMMON_SRC = \ + $(PLATFORM_SRC) \ + capture_errs.c \ + capture-pcap-util.c \ + capture_ui_utils.c \ + cfile.c \ + clopts_common.c \ + disabled_protos.c \ + packet-range.c \ + print.c \ + ps.c \ + sync_pipe_write.c \ + timestats.c \ + util.c \ + version_info.c + +# corresponding headers +WIRESHARK_COMMON_INCLUDES = \ + svnversion.h \ + capture_errs.h \ + capture-pcap-util.h \ + capture-pcap-util-int.h \ + capture_ui_utils.h \ + cfile.h \ + clopts_common.h \ + cmdarg_err.h \ + color.h \ + disabled_protos.h \ + file.h \ + fileset.h \ + isprint.h \ + packet-range.h \ + print.h \ + ps.h \ + register.h \ + tempfile.h \ + timestats.h \ + util.h \ + version_info.h + +# sources for TShark taps +TSHARK_TAP_SRC = \ + tap-afpstat.c \ + tap-ansi_astat.c \ + tap-bootpstat.c \ + tap-camelcounter.c \ + tap-camelsrt.c \ + tap-dcerpcstat.c \ + tap-funnel.c \ + tap-gsm_astat.c \ + tap-h225counter.c \ + tap-h225rassrt.c \ + tap-httpstat.c \ + tap-iostat.c \ + tap-iousers.c \ + tap-mgcpstat.c \ + tap-protocolinfo.c \ + tap-protohierstat.c \ + tap-radiusstat.c \ + tap-rpcstat.c \ + tap-rpcprogs.c \ + tap-sctpchunkstat.c \ + tap-sipstat.c \ + tap-smbsids.c \ + tap-smbstat.c \ + tap-stats_tree.c \ + tap-wspstat.c + +# helpers already available on some platforms (and on others not) +EXTRA_wireshark_SOURCES = \ + getopt.c \ + inet_ntop.c \ + inet_pton.c \ + mkstemp.c \ + strerror.c \ + strcasecmp.c \ + strncasecmp.c \ + strptime.c + +# corresponding headers +EXTRA_wireshark_INCLUDES = \ + getopt.h \ + inet_v6defs.h \ + mkstemp.h \ + strerror.h \ + strptime.h + +# wireshark specifics +wireshark_SOURCES = \ + $(WIRESHARK_COMMON_SRC) \ + airpcap_loader.c \ + alert_box.c \ + capture.c \ + capture_info.c \ + capture_opts.c \ + capture_sync.c \ + color_filters.c \ + file.c \ + fileset.c \ + filters.c \ + g711.c \ + merge.c \ + proto_hier_stats.c \ + summary.c \ + tempfile.c + +# corresponding headers +wireshark_INCLUDES = \ + airpcap.h \ + airpcap_loader.h \ + alert_box.h \ + capture.h \ + capture_info.h \ + capture_opts.h \ + capture_sync.h \ + color_filters.h \ + filters.h \ + g711.h \ + globals.h \ + log.h \ + main_window.h \ + menu.h \ + merge.h \ + progress_dlg.h \ + proto_hier_stats.h \ + simple_dialog.h \ + stat_menu.h \ + statusbar.h \ + summary.h \ + sync_pipe.h \ + tap_dfilter_dlg.h \ + ui_util.h + +# tshark specifics +tshark_SOURCES = \ + $(WIRESHARK_COMMON_SRC) \ + $(TSHARK_TAP_SRC) \ + capture_opts.c \ + capture_sync.c \ + tempfile.c \ + tshark-tap-register.c \ + tshark.c + +# text2pcap specifics +text2pcap_SOURCES = \ + text2pcap.c \ + text2pcap-scanner.l + +# mergecap specifics +mergecap_SOURCES = \ + mergecap.c \ + merge.c \ + svnversion.h + +# editcap specifics +editcap_SOURCES = \ + editcap.c \ + epan/crypt/crypt-md5.c \ + $(WTAP_PLUGIN_SOURCES) + +capinfos_SOURCES = \ + capinfos.c \ + $(WTAP_PLUGIN_SOURCES) + +# dftest specifics +dftest_SOURCES = \ + dftest.c \ + util.c + +# randpkt specifics +randpkt_SOURCES = \ + randpkt.c + +# dumpcap specifics +dumpcap_SOURCES = \ + $(PLATFORM_SRC) \ + capture_opts.c \ + capture_loop.c \ + capture-pcap-util.c \ + capture_stop_conditions.c \ + clopts_common.c \ + conditions.c \ + dumpcap.c \ + pcapio.c \ + ringbuffer.c \ + sync_pipe_write.c \ + tempfile.c \ + version_info.c \ + epan/unicode-utils.c + +# corresponding headers +dumpcap_INCLUDES = \ + capture_loop.h \ + capture_stop_conditions.h \ + conditions.h \ + pcapio.h \ + ringbuffer.h + +# this target needed for distribution only +noinst_HEADERS = \ + $(WIRESHARK_COMMON_INCLUDES) \ + $(wireshark_INCLUDES) \ + $(EXTRA_wireshark_INCLUDES) \ + $(dumpcap_INCLUDES) diff --git a/plugins/ethercat/Makefile.nmake b/plugins/ethercat/Makefile.nmake new file mode 100644 index 0000000000..fabf526b95 --- /dev/null +++ b/plugins/ethercat/Makefile.nmake @@ -0,0 +1,99 @@ +# Makefile.nmake +# nmake file for Wireshark plugin +# +# $Id$ +# + +include ..\..\config.nmake +include moduleinfo.nmake + +include Makefile.common + +CFLAGS=/WX /DHAVE_CONFIG_H /I../.. /I../../wiretap $(GLIB_CFLAGS) \ + /I$(PCAP_DIR)\include -D_U_="" $(LOCAL_CFLAGS) + +.c.obj:: + $(CC) $(CFLAGS) -Fd.\ -c $< + +LDFLAGS = $(PLUGIN_LDFLAGS) + +!IFDEF ENABLE_LIBWIRESHARK +LINK_PLUGIN_WITH=..\..\epan\libwireshark.lib +CFLAGS=/DHAVE_WIN32_LIBWIRESHARK_LIB /D_NEED_VAR_IMPORT_ $(CFLAGS) + +DISSECTOR_OBJECTS = $(DISSECTOR_SRC:.c=.obj) + +DISSECTOR_SUPPORT_OBJECTS = $(DISSECTOR_SUPPORT_SRC:.c=.obj) + +OBJECTS = $(DISSECTOR_OBJECTS) $(DISSECTOR_SUPPORT_OBJECTS) plugin.obj + +RESOURCE=$(PLUGIN_NAME).res + +all: $(PLUGIN_NAME).dll + +$(PLUGIN_NAME).rc : moduleinfo.nmake + sed -e s/@PLUGIN_NAME@/$(PLUGIN_NAME)/ \ + -e s/@RC_MODULE_VERSION@/$(RC_MODULE_VERSION)/ \ + -e s/@RC_VERSION@/$(RC_VERSION)/ \ + -e s/@MODULE_VERSION@/$(MODULE_VERSION)/ \ + -e s/@PACKAGE@/$(PACKAGE)/ \ + -e s/@VERSION@/$(VERSION)/ \ + -e s/@MSVC_VARIANT@/$(MSVC_VARIANT)/ \ + < plugin.rc.in > $@ + +$(PLUGIN_NAME).dll $(PLUGIN_NAME).exp $(PLUGIN_NAME).lib : $(OBJECTS) $(LINK_PLUGIN_WITH) $(RESOURCE) $(DISSECTOR_INCLUDES) + link -dll /out:$(PLUGIN_NAME).dll $(LDFLAGS) $(OBJECTS) $(LINK_PLUGIN_WITH) \ + $(GLIB_LIBS) $(RESOURCE) + +# +# Build plugin.c, which contains the plugin version[] string, a +# function plugin_register() that calls the register routines for all +# protocols, and a function plugin_reg_handoff() that calls the handoff +# registration routines for all protocols. +# +# We do this by scanning sources. If that turns out to be too slow, +# maybe we could just require every .o file to have an register routine +# of a given name (packet-aarp.o -> proto_register_aarp, etc.). +# +# Formatting conventions: The name of the proto_register_* routines an +# proto_reg_handoff_* routines must start in column zero, or must be +# preceded only by "void " starting in column zero, and must not be +# inside #if. +# +# DISSECTOR_SRC is assumed to have all the files that need to be scanned. +# +# For some unknown reason, having a big "for" loop in the Makefile +# to scan all the files doesn't work with some "make"s; they seem to +# pass only the first few names in the list to the shell, for some +# reason. +# +# Therefore, we have a script to generate the plugin.c file. +# The shell script runs slowly, as multiple greps and seds are run +# for each input file; this is especially slow on Windows. Therefore, +# if Python is present (as indicated by PYTHON being defined), we run +# a faster Python script to do that work instead. +# +# The first argument is the directory in which the source files live. +# The second argument is "plugin", to indicate that we should build +# a plugin.c file for a plugin. +# All subsequent arguments are the files to scan. +# +plugin.c: $(DISSECTOR_SRC) ../../tools/make-dissector-reg.py ../../tools/make-dissector-reg +!IFDEF PYTHON + @echo Making plugin.c (using python) + @$(PYTHON) "../../tools/make-dissector-reg.py" . plugin $(DISSECTOR_SRC) +!ELSE + @echo Making plugin.c (using sh) + @$(SH) ../../tools/make-dissector-reg . plugin $(DISSECTOR_SRC) +!ENDIF + +!ENDIF + +clean: + rm -f $(OBJECTS) $(RESOURCE) plugin.c *.pdb \ + $(PLUGIN_NAME).dll $(PLUGIN_NAME).dll.manifest $(PLUGIN_NAME).lib \ + $(PLUGIN_NAME).exp $(PLUGIN_NAME).rc + +distclean: clean + +maintainer-clean: distclean diff --git a/plugins/ethercat/moduleinfo.h b/plugins/ethercat/moduleinfo.h new file mode 100644 index 0000000000..407867b2ff --- /dev/null +++ b/plugins/ethercat/moduleinfo.h @@ -0,0 +1,59 @@ +/* Copyright (c) 2007 by Beckhoff Automation GmbH + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * 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. + */ +/* Included *after* config.h, in order to re-define these macros */ + +#ifdef PACKAGE +#undef PACKAGE +#endif + +/* Name of package */ +#define PACKAGE "EtherCAT" + +#ifdef VERSION +#undef VERSION +#endif + +/* Version number of package */ +/*#define VERSION "0.0.6" /* firstversion */ +/*#define VERSION "0.0.7" /* new dissector for mailbox inserted*/ +/*#define VERSION "0.0.9" /* nv-protocol inserted*/ +/*#define VERSION "0.0.10" +/*#define VERSION "0.0.11" /* support of AoE protocol */ +/*#define VERSION "0.0.12" /* port to Wireshark */ +#define VERSION "0.1.0" /* First version integrated into the Wireshark sources*/ +/* Included *after* config.h, in order to re-define these macros */ + +#ifdef PACKAGE +#undef PACKAGE +#endif + +/* Name of package */ +#define PACKAGE "mikey" + + +#ifdef VERSION +#undef VERSION +#endif + +/* Version number of package */ +#define VERSION "0.0.1" + + diff --git a/plugins/ethercat/moduleinfo.nmake b/plugins/ethercat/moduleinfo.nmake new file mode 100644 index 0000000000..d11d9b8738 --- /dev/null +++ b/plugins/ethercat/moduleinfo.nmake @@ -0,0 +1,56 @@ +# +# $Id$ +# + +# The name +PACKAGE=ethercat + +# The version +MODULE_VERSION_MAJOR=0 +MODULE_VERSION_MINOR=1 +MODULE_VERSION_MICRO=0 +MODULE_VERSION_EXTRA=0 + +# +# The RC_VERSION should be comma-separated, not dot-separated, +# as per Graham Bloice's message in +# +# http://www.ethereal.com/lists/ethereal-dev/200303/msg00283.html +# +# "The RC_VERSION variable in config.nmake should be comma separated. +# This allows the resources to be built correctly and the version +# number to be correctly displayed in the explorer properties dialog +# for the executables, and XP's tooltip, rather than 0.0.0.0." +# + +MODULE_VERSION=$(MODULE_VERSION_MAJOR).$(MODULE_VERSION_MINOR).$(MODULE_VERSION_MICRO).$(MODULE_VERSION_EXTRA) +RC_MODULE_VERSION=$(MODULE_VERSION_MAJOR),$(MODULE_VERSION_MINOR),$(MODULE_VERSION_MICRO),$(MODULE_VERSION_EXTRA) + +# +# $Id$ +# + +# The name +PACKAGE=mikey + +# The version +MODULE_VERSION_MAJOR=0 +MODULE_VERSION_MINOR=0 +MODULE_VERSION_MICRO=1 +MODULE_VERSION_EXTRA=0 + +# +# The RC_VERSION should be comma-separated, not dot-separated, +# as per Graham Bloice's message in +# +# http://www.ethereal.com/lists/ethereal-dev/200303/msg00283.html +# +# "The RC_VERSION variable in config.nmake should be comma separated. +# This allows the resources to be built correctly and the version +# number to be correctly displayed in the explorer properties dialog +# for the executables, and XP's tooltip, rather than 0.0.0.0." +# + +MODULE_VERSION=$(MODULE_VERSION_MAJOR).$(MODULE_VERSION_MINOR).$(MODULE_VERSION_MICRO).$(MODULE_VERSION_EXTRA) +RC_MODULE_VERSION=$(MODULE_VERSION_MAJOR),$(MODULE_VERSION_MINOR),$(MODULE_VERSION_MICRO),$(MODULE_VERSION_EXTRA) + diff --git a/plugins/ethercat/packet-ams.c b/plugins/ethercat/packet-ams.c new file mode 100644 index 0000000000..725e68b93e --- /dev/null +++ b/plugins/ethercat/packet-ams.c @@ -0,0 +1,1254 @@ +/* packet-ams.c + * Routines for ethercat packet disassembly + * + * $Id$ + * + * Copyright (c) 2007 by Beckhoff Automation GmbH + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * 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. + */ + +/* Include files */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include "packet-ams.h" + +void proto_reg_handoff_ams(void); + +/* Define the ams proto */ +int proto_ams = -1; + +/* Define the tree for ams */ +static int ett_ams = -1; +static int ett_ams_sender = -1; +static int ett_ams_target = -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 ett_ams_adsdnresponse = -1; +static int ett_ams_noteblockstamp = -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 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 } +}; + +static void NetIdFormater(tvbuff_t *tvb, guint offset, char *szText, gint nMax) +{ + g_snprintf ( szText, nMax, "%d.%d.%d.%d.%d.%d", tvb_get_guint8(tvb, offset++), + tvb_get_guint8(tvb, offset++), + tvb_get_guint8(tvb, offset++), + tvb_get_guint8(tvb, offset++), + tvb_get_guint8(tvb, offset++), + tvb_get_guint8(tvb, offset) + ); +} + + + +/*ams*/ +static void dissect_ams(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + proto_item *ti, *aitem; + proto_tree *ams_tree = NULL, *ams_adstree, *ams_statetree; + gint offset = 0; + guint ams_length = tvb_reported_length(tvb); + guint16 stateflags = 0; + guint16 cmdId = 0; + + char szText[200]; + int nMax = sizeof(szText)-1; + + if (check_col(pinfo->cinfo, COL_PROTOCOL)) + col_set_str(pinfo->cinfo, COL_PROTOCOL, "AMS"); + + if (check_col(pinfo->cinfo, COL_INFO)) + col_clear(pinfo->cinfo, COL_INFO); + + if( pinfo->ethertype != 0x88a4 ) + { + if( sizeof(TcpAdsParserHDR) > ams_length ) + return; + ams_length -= sizeof(TcpAdsParserHDR); + + offset = sizeof(TcpAdsParserHDR); + } + + if( ams_length < sizeof(AmsHead) ) + return; + + if (tree) + { + ti = proto_tree_add_item(tree, proto_ams, tvb, 0, -1, TRUE); + 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, sizeof(AmsNetId), szText); + offset += sizeof(AmsNetId); + + proto_tree_add_item(ams_tree, hf_ams_targetport, tvb, offset, sizeof(guint16), TRUE); + offset += sizeof(guint16); + + NetIdFormater(tvb, offset, szText, nMax); + proto_tree_add_string(ams_tree, hf_ams_sendernetid, tvb, offset, sizeof(AmsNetId), szText); + offset += sizeof(AmsNetId); + + proto_tree_add_item(ams_tree, hf_ams_senderport, tvb, offset, sizeof(guint16), TRUE); + offset += sizeof(guint16); + + proto_tree_add_item(ams_tree, hf_ams_cmdid, tvb, offset, sizeof(guint16), TRUE); + cmdId = tvb_get_letohs(tvb, offset); + offset+=sizeof(guint16); + + aitem = proto_tree_add_item(ams_tree, hf_ams_stateflags, tvb, offset, sizeof(guint16), TRUE); + ams_statetree = proto_item_add_subtree(aitem, ett_ams_stateflags); + proto_tree_add_item(ams_statetree, hf_ams_stateresponse,tvb, offset, sizeof(guint16), TRUE); + proto_tree_add_item(ams_statetree, hf_ams_statenoreturn,tvb, offset, sizeof(guint16), TRUE); + proto_tree_add_item(ams_statetree, hf_ams_stateadscmd,tvb, offset, sizeof(guint16), TRUE); + proto_tree_add_item(ams_statetree, hf_ams_statesyscmd,tvb, offset, sizeof(guint16), TRUE); + proto_tree_add_item(ams_statetree, hf_ams_statehighprio,tvb, offset, sizeof(guint16), TRUE); + proto_tree_add_item(ams_statetree, hf_ams_statetimestampadded,tvb, offset, sizeof(guint16), TRUE); + proto_tree_add_item(ams_statetree, hf_ams_stateudp,tvb, offset, sizeof(guint16), TRUE); + proto_tree_add_item(ams_statetree, hf_ams_stateinitcmd,tvb, offset, sizeof(guint16), TRUE); + proto_tree_add_item(ams_statetree, hf_ams_statebroadcast,tvb, offset, sizeof(guint16), TRUE); + stateflags = tvb_get_letohs(tvb, offset); + offset+=sizeof(guint16); + + proto_tree_add_item(ams_tree, hf_ams_cbdata, tvb, offset, sizeof(guint32), TRUE); + offset+=sizeof(guint32); + + proto_tree_add_item(ams_tree, hf_ams_errorcode, tvb, offset, sizeof(guint32),TRUE); + offset+=sizeof(guint32); + + proto_tree_add_item(ams_tree, hf_ams_invokeid, tvb, offset, sizeof(guint32), TRUE); + offset+=sizeof(guint32); + } + else + { + offset+=sizeof(AmsHead); + } + + if ( (stateflags & AMSCMDSF_ADSCMD) != 0 ) + { + /* ADS */ + if ( (stateflags & AMSCMDSF_RESPONSE) == 0 ) + { + /* Request */ + switch ( cmdId ) + { + case ADSSRVID_READ: + { + if (check_col(pinfo->cinfo, COL_INFO)) + col_append_str(pinfo->cinfo, COL_INFO, "ADS Read Request"); + + if( tree ) + { + aitem = proto_tree_add_item(ams_tree, hf_ams_adsreadrequest, tvb, offset, ams_length-offset, TRUE); + if( ams_length-offset >= sizeof(TAdsReadReq) ) + { + ams_adstree = proto_item_add_subtree(aitem, ett_ams_adsreadrequest); + proto_tree_add_item(ams_adstree, hf_ams_adsindexgroup, tvb, offset, sizeof(guint32), TRUE); + offset+=sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adsindexoffset, tvb, offset, sizeof(guint32), TRUE); + offset+=sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adscblength, tvb, offset, sizeof(guint32), TRUE); + offset+=sizeof(guint32); + } + } + } + break; + case ADSSRVID_WRITE: + { + if (check_col(pinfo->cinfo, COL_INFO)) + col_append_str(pinfo->cinfo, COL_INFO, "ADS Write Request"); + + if( tree ) + { + aitem = proto_tree_add_item(ams_tree, hf_ams_adswriterequest, tvb, offset, ams_length-offset, TRUE); + if( ams_length-offset >= sizeof(TAdsWriteReq) - sizeof(guint16) ) + { + ams_adstree = proto_item_add_subtree(aitem, ett_ams_adswriterequest); + proto_tree_add_item(ams_adstree, hf_ams_adsindexgroup, tvb, offset, 4, TRUE); + offset+=sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adsindexoffset, tvb, offset, 4, TRUE); + offset+=sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adscblength, tvb, offset, 4, TRUE); + offset+=sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adsdata, tvb, offset, ams_length-offset, TRUE); + } + } + } + break; + case ADSSRVID_READWRITE: + { + if (check_col(pinfo->cinfo, COL_INFO)) + col_append_str(pinfo->cinfo, COL_INFO, "ADS Read Write Request"); + + if( tree ) + { + aitem = proto_tree_add_item(ams_tree, hf_ams_adsreadwriterequest, tvb, offset, ams_length-offset, TRUE); + if( ams_length-offset >= sizeof(TAdsReadWriteReq) - sizeof(guint16)) + { + ams_adstree = proto_item_add_subtree(aitem, ett_ams_adsreadwriterequest); + proto_tree_add_item(ams_adstree, hf_ams_adsindexgroup, tvb, offset, sizeof(guint32), TRUE); + offset+=sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adsindexoffset, tvb, offset, sizeof(guint32), TRUE); + offset+=sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adscbreadlength, tvb, offset, sizeof(guint32), TRUE); + offset+=sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adscbwritelength, tvb, offset, sizeof(guint32), TRUE); + offset+=sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adsdata, tvb, offset+16, ams_length-offset, TRUE); + } + } + } + break; + case ADSSRVID_READSTATE: + { + if (check_col(pinfo->cinfo, COL_INFO)) + col_append_str(pinfo->cinfo, COL_INFO, "ADS Read State Request"); + + if( tree ) + { + aitem = proto_tree_add_item(ams_tree, hf_ams_adsreadstaterequest, tvb, offset, ams_length-offset, TRUE); + if( ams_length-offset >= sizeof(TAdsReadStateReq) ) + { + ams_adstree = proto_item_add_subtree(aitem, ett_ams_adsreadstaterequest); + proto_tree_add_item(ams_adstree, hf_ams_adsinvokeid, tvb, offset, sizeof(guint32), TRUE); + } + } + } + break; + case ADSSRVID_WRITECTRL: + { + if (check_col(pinfo->cinfo, COL_INFO)) + col_append_str(pinfo->cinfo, COL_INFO, "ADS Write Control Request"); + + if( tree ) + { + aitem = proto_tree_add_item(ams_tree, hf_ams_adswritectrlrequest, tvb, offset, ams_length-offset, TRUE); + if( ams_length-offset >= sizeof(TAdsWriteControlReq) - sizeof(guint16) ) + { + ams_adstree = proto_item_add_subtree(aitem, ett_ams_adswritectrlrequest); + proto_tree_add_item(ams_adstree, hf_ams_adsstate, tvb, offset, 2, TRUE); + offset+=sizeof(guint16); + + proto_tree_add_item(ams_adstree, hf_ams_adsdevicestate, tvb, offset, 2, TRUE); + offset+=sizeof(guint16); + + proto_tree_add_item(ams_adstree, hf_ams_adscblength, tvb, offset, sizeof(guint32), TRUE); + offset+=sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adsdata, tvb, offset, ams_length-offset, TRUE); + } + } + } + break; + case ADSSRVID_READDEVICEINFO: + { + if (check_col(pinfo->cinfo, COL_INFO)) + col_append_str(pinfo->cinfo, COL_INFO, "ADS Read Device Info Request"); + + if( tree ) + { + aitem = proto_tree_add_item(ams_tree, hf_ams_adsreaddinforequest, tvb, offset, ams_length-offset, TRUE); + if( ams_length-offset >= sizeof(TAdsReadDeviceInfoReq) ) + { + ams_adstree = proto_item_add_subtree(aitem, ett_ams_adsreaddinforequest); + proto_tree_add_item(ams_adstree, hf_ams_adsresult, tvb, offset, sizeof(guint32), TRUE); + } + } + } + break; + case ADSSRVID_ADDDEVICENOTE: + { + if (check_col(pinfo->cinfo, COL_INFO)) + col_append_str(pinfo->cinfo, COL_INFO, "ADS Add Device Notification Request"); + + if( tree ) + { + aitem = proto_tree_add_item(ams_tree, hf_ams_adsadddnrequest, tvb, offset, ams_length-offset, TRUE); + if( ams_length-offset >= sizeof(TAdsAddDeviceNotificationReq) ) + { + ams_adstree = proto_item_add_subtree(aitem, ett_ams_adsadddnrequest); + proto_tree_add_item(ams_adstree, hf_ams_adsindexgroup, tvb, offset, sizeof(guint32), TRUE); + offset+=sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adsindexoffset, tvb, offset, sizeof(guint32), TRUE); + offset+=sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adscblength, tvb, offset, sizeof(guint32), TRUE); + offset+=sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adstransmode, tvb, offset, sizeof(guint32), TRUE); + offset+=sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adsmaxdelay, tvb, offset, sizeof(guint32), TRUE); + offset+=sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adscycletime, tvb, offset, sizeof(guint32), TRUE); + offset+=sizeof(guint32); + } + } + } + break; + case ADSSRVID_DELDEVICENOTE: + { + if (check_col(pinfo->cinfo, COL_INFO)) + col_append_str(pinfo->cinfo, COL_INFO, "ADS Delete Device Notification Request"); + + if( tree ) + { + aitem = proto_tree_add_item(ams_tree, hf_ams_adsdeldnrequest, tvb, offset, ams_length-offset, TRUE); + if( ams_length-offset >= sizeof(TAdsDelDeviceNotificationReq) ) + { + ams_adstree = proto_item_add_subtree(aitem, ett_ams_adsdeldnrequest); + proto_tree_add_item(ams_adstree, hf_ams_adsnotificationhandle, tvb, offset, sizeof(guint32), TRUE); + } + } + } + break; + case ADSSRVID_DEVICENOTE: + { + if (check_col(pinfo->cinfo, COL_INFO)) + col_append_str(pinfo->cinfo, COL_INFO, "ADS Device Notification Request"); + + if( tree ) + { + /*guint32 cbLength; + guint32 nStamps;*/ + + aitem = proto_tree_add_item(ams_tree, hf_ams_adsdnrequest, tvb, offset, ams_length-offset, TRUE); + if( ams_length-offset >= sizeof(TAdsDeviceNotificationReq) - sizeof(AdsNotificationSample) ) + { + ams_adstree = proto_item_add_subtree(aitem, ett_ams_adsdnrequest); + proto_tree_add_item(ams_adstree, hf_ams_adscblength, tvb, offset, sizeof(guint32), TRUE); + /*cbLength = tvb_get_letohs(tvb, offset);*/ + offset+=sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adsnoteblocksstamps, tvb, offset, sizeof(guint32), TRUE); + /*nStamps = tvb_get_letohs(tvb, offset);*/ + offset+=sizeof(guint32); + + /*ToDo: dissect noteblocks*/ + } + } + } + break; + } + } + else + { + /* Response */ + switch ( cmdId ) + { + case ADSSRVID_READ: + { + if (check_col(pinfo->cinfo, COL_INFO)) + col_append_str(pinfo->cinfo, COL_INFO, "ADS Read Response"); + + if( tree ) + { + aitem = proto_tree_add_item(ams_tree, hf_ams_adsreadresponse, tvb, offset, ams_length-offset, TRUE); + if( ams_length-offset >= sizeof(TAdsReadRes) - sizeof(guint16) ) + { + ams_adstree = proto_item_add_subtree(aitem, ett_ams_adsreadresponse); + proto_tree_add_item(ams_adstree, hf_ams_adsresult, tvb, offset, sizeof(guint32), TRUE); + offset+=sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adscblength, tvb, offset, sizeof(guint32), TRUE); + offset+=sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adsdata, tvb, offset, ams_length-offset, TRUE); + } + } + } + break; + case ADSSRVID_WRITE: + { + if (check_col(pinfo->cinfo, COL_INFO)) + col_append_str(pinfo->cinfo, COL_INFO, "ADS Write Response"); + + if( tree ) + { + aitem = proto_tree_add_item(ams_tree, hf_ams_adswriteresponse, tvb, offset, ams_length-offset, TRUE); + if( ams_length-offset >= sizeof(TAdsWriteRes) ) + { + ams_adstree = proto_item_add_subtree(aitem, ett_ams_adswriteresponse); + proto_tree_add_item(ams_adstree, hf_ams_adsresult, tvb, offset, sizeof(guint32), TRUE); + } + } + } + break; + case ADSSRVID_READWRITE: + { + if (check_col(pinfo->cinfo, COL_INFO)) + col_append_str(pinfo->cinfo, COL_INFO, "ADS Read Write Response"); + + if( tree ) + { + aitem = proto_tree_add_item(ams_tree, hf_ams_adsreadwriteresponse, tvb, offset, ams_length-offset, TRUE); + if( ams_length-offset >= sizeof(TAdsReadWriteRes) - sizeof(guint16) ) + { + ams_adstree = proto_item_add_subtree(aitem, ett_ams_adsreadwriteresponse); + proto_tree_add_item(ams_adstree, hf_ams_adsresult, tvb, offset, sizeof(guint32), TRUE); + offset+=sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adscblength, tvb, offset, sizeof(guint32), TRUE); + offset+=sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adsdata, tvb, offset, ams_length-offset, TRUE); + } + } + } + break; + case ADSSRVID_READSTATE: + { + if (check_col(pinfo->cinfo, COL_INFO)) + col_append_str(pinfo->cinfo, COL_INFO, "ADS Read State Response"); + + if( tree ) + { + aitem = proto_tree_add_item(ams_tree, hf_ams_adsreadstateresponse, tvb, offset, ams_length-offset, TRUE); + if( ams_length-offset >= sizeof(TAdsReadStateRes) ) + { + ams_adstree = proto_item_add_subtree(aitem, ett_ams_adsreadstateresponse); + proto_tree_add_item(ams_adstree, hf_ams_adsresult, tvb, offset, sizeof(guint32), TRUE); + offset+=sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adsstate, tvb, offset, sizeof(guint16), TRUE); + offset+=sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adsdevicestate, tvb, offset, sizeof(guint16), TRUE); + } + } + } + break; + case ADSSRVID_WRITECTRL: + { + if (check_col(pinfo->cinfo, COL_INFO)) + col_append_str(pinfo->cinfo, COL_INFO, "ADS Write Control Response"); + + if( tree ) + { + aitem = proto_tree_add_item(ams_tree, hf_ams_adswritectrlresponse, tvb, offset, ams_length-offset, TRUE); + if( ams_length-offset >= sizeof(TAdsWriteControlRes) ) + { + ams_adstree = proto_item_add_subtree(aitem, ett_ams_adswritectrlresponse); + proto_tree_add_item(ams_adstree, hf_ams_adsresult, tvb, offset, sizeof(guint32), TRUE); + } + } + } + break; + case ADSSRVID_READDEVICEINFO: + { + if (check_col(pinfo->cinfo, COL_INFO)) + col_append_str(pinfo->cinfo, COL_INFO, "ADS Read Device Info Response"); + + if( tree ) + { + aitem = proto_tree_add_item(ams_tree, hf_ams_adsreaddinforesponse, tvb, offset, ams_length-offset, TRUE); + if( ams_length-offset >= sizeof(TAdsReadDeviceInfoRes) ) + { + ams_adstree = proto_item_add_subtree(aitem, ett_ams_adsreaddinforesponse); + proto_tree_add_item(ams_adstree, hf_ams_adsresult, tvb, offset, sizeof(guint32), TRUE); + offset+=sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adsversionversion, tvb, offset++, sizeof(guint8), TRUE); + proto_tree_add_item(ams_adstree, hf_ams_adsversionrevision, tvb, offset++, sizeof(guint8), TRUE); + proto_tree_add_item(ams_adstree, hf_ams_adsversionbuild, tvb, offset, sizeof(guint16), TRUE); + offset+=sizeof(guint16); + + proto_tree_add_item(ams_adstree, hf_ams_adsdevicename, tvb, offset, ams_length-offset, TRUE); + } + } + } + break; + case ADSSRVID_ADDDEVICENOTE: + { + if (check_col(pinfo->cinfo, COL_INFO)) + col_append_str(pinfo->cinfo, COL_INFO, "ADS Device Notification Response"); + + if( tree ) + { + aitem = proto_tree_add_item(ams_tree, hf_ams_adsadddnresponse, tvb, offset, ams_length-offset, TRUE); + if( ams_length-offset >= sizeof(TAdsAddDeviceNotificationRes) ) + { + ams_adstree = proto_item_add_subtree(aitem, ett_ams_adsadddnresponse); + proto_tree_add_item(ams_adstree, hf_ams_adsresult, tvb, offset, sizeof(guint32), TRUE); + offset+=sizeof(guint32); + + proto_tree_add_item(ams_adstree, hf_ams_adsnotificationhandle, tvb, offset, sizeof(guint32), TRUE); + } + } + } + break; + case ADSSRVID_DELDEVICENOTE: + { + if (check_col(pinfo->cinfo, COL_INFO)) + col_append_str(pinfo->cinfo, COL_INFO, "ADS Delete Device Notification Response"); + + if( tree ) + { + aitem = proto_tree_add_item(ams_tree, hf_ams_adsdeldnresponse, tvb, offset, ams_length-offset, TRUE); + if( ams_length-offset >= sizeof(TAdsDelDeviceNotificationRes) ) + { + ams_adstree = proto_item_add_subtree(aitem, ett_ams_adsdeldnresponse); + proto_tree_add_item(ams_adstree, hf_ams_adsresult, tvb, offset, sizeof(guint32), TRUE); + } + } + } + break; + } + } + } + else + { + if (check_col(pinfo->cinfo, COL_INFO)) + { + 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, TRUE); + } + +} + + +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, + "", HFILL } + }, + { &hf_ams_senderport, + { "AMS Sender port", "ams.senderport", + FT_UINT16, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_targetnetid, + { "AMS Target Net Id", "ams.targetnetid", + FT_STRING, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_targetport, + { "AMS Target port", "ams.targetport", + FT_UINT16, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_cmdid, + { "CmdId", "ams.cmdid", + FT_UINT16, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_stateflags, + { "StateFlags", "ams.stateflags", + FT_UINT16, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_stateresponse, + { "RESPONSE", "ams.state_response", + FT_BOOLEAN, 16, TFS(&flags_set_truth), AMSCMDSF_RESPONSE, + "", HFILL } + }, + { &hf_ams_statenoreturn, + { "NO RETURN", "ams.state_noreturn", + FT_BOOLEAN, 16, TFS(&flags_set_truth), AMSCMDSF_NORETURN, + "", HFILL } + }, + { &hf_ams_stateadscmd, + { "ADS COMMAND", "ams.state_adscmd", + FT_BOOLEAN, 16, TFS(&flags_set_truth), AMSCMDSF_ADSCMD, + "", HFILL } + }, + { &hf_ams_statesyscmd, + { "SYSTEM COMMAND", "ams.state_syscmd", + FT_BOOLEAN, 16, TFS(&flags_set_truth), AMSCMDSF_SYSCMD, + "", HFILL } + }, + { &hf_ams_statehighprio, + { "HIGH PRIORITY COMMAND", "ams.state_highprio", + FT_BOOLEAN, 16, TFS(&flags_set_truth), AMSCMDSF_HIGHPRIO, + "", HFILL } + }, + { &hf_ams_statetimestampadded, + { "TIMESTAMP ADDED", "ams.state_timestampadded", + FT_BOOLEAN, 16, TFS(&flags_set_truth), AMSCMDSF_TIMESTAMPADDED, + "", HFILL } + }, + { &hf_ams_stateudp, + { "UDP COMMAND", "ams.state_udp", + FT_BOOLEAN, 16, TFS(&flags_set_truth), AMSCMDSF_UDP, + "", HFILL } + }, + { &hf_ams_stateinitcmd, + { "INIT COMMAND", "ams.state_initcmd", + FT_BOOLEAN, 16, TFS(&flags_set_truth), AMSCMDSF_INITCMD, + "", HFILL } + }, + { &hf_ams_statebroadcast, + { "BROADCAST", "ams.state_broadcast", + FT_BOOLEAN, 16, TFS(&flags_set_truth), AMSCMDSF_BROADCAST, + "", HFILL } + }, + { &hf_ams_cbdata, + { "cbData", "ams.cbdata", + FT_UINT32, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_errorcode, + { "ErrorCode", "ams.errorcode", + FT_UINT32, BASE_HEX, VALS(ErrorCode), 0x0, + "", HFILL } + }, + { &hf_ams_invokeid, + { "InvokeId", "ams.invokeid", + FT_UINT32, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_adsdata, + { "Data", "ams.ads_data", + FT_NONE, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_data, + { "Data", "ams.data", + FT_NONE, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_adsindexgroup, + { "IndexGroup", "ams.ads_indexgroup", + FT_UINT32, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_adsindexoffset, + { "IndexOffset", "ams.ads_indexoffset", + FT_UINT32, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_adscblength, + { "CbLength", "ams.ads_cblength", + FT_UINT32, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_adsreadrequest, + { "ADS Read Request", "ams.ads_read_req", + FT_NONE, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_adsreadresponse, + { "ADS Read Respone", "ams.ads_read_res", + FT_NONE, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_adsinvokeid, + { "InvokeId", "ams.ads_invokeid", + FT_UINT32, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_adsresult, + { "Result", "ams.adsresult", + FT_UINT32, BASE_HEX, VALS(AdsErrorMode), 0x0, + "", HFILL } + }, + { &hf_ams_adswriterequest, + { "ADS Write Request", "ams.ads_write_req", + FT_NONE, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_adswriteresponse, + { "ADS Write Response", "ams.ads_write_res", + FT_NONE, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_adsreadwriterequest, + { "ADS ReadWrite Request", "ams.ads_readwrite_req", + FT_NONE, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_adsreadwriteresponse, + { "ADS ReadWrite Response", "ams.ads_readwrite_res", + FT_NONE, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_adscbreadlength, + { "CBReadLength", "ams.ads_cbreadlength", + FT_UINT32, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_adscbwritelength, + { "CBWriteLength", "ams.ads_cbwritelength", + FT_UINT32, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_adsstate, + { "AdsState", "ams.ads_state", + FT_UINT16, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_adsdevicestate, + { "DeviceState", "ams.ads_devicestate", + FT_UINT16, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_adsnotificationhandle, + { "NotificationHandle", "ams.ads_notificationhandle", + FT_UINT32, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_adsreadstaterequest, + { "ADS Read State Request", "ams.ads_readstate_req", + FT_NONE, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_adsreadstateresponse, + { "ADS Read State Response", "ams.ads_readstate_res", + FT_NONE, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_adswritectrlrequest, + { "ADS Write Ctrl Request", "ams.ads_writectrl_req", + FT_NONE, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_adswritectrlresponse, + { "ADS Write Ctrl Response", "ams.ads_writectrl_res", + FT_NONE, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_adsreaddinforequest, + { "ADS Read Device Info Request", "ams.ads_readdinfo_req", + FT_NONE, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_adsreaddinforesponse, + { "ADS Read Device Info Response", "ams.ads_readdinfo_res", + FT_NONE, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_adsadddnrequest, + { "ADS Add Device Notification Request", "ams.ads_adddn_req", + FT_NONE, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_adsadddnresponse, + { "ADS Add Device Notification Response", "ams.ads_adddn_res", + FT_NONE, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_adsdeldnrequest, + { "ADS Delete Device Notification Request", "ams.ads_deldn_req", + FT_NONE, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_adsdeldnresponse, + { "ADS Delete Device Notification Response", "ams.ads_deldn_res", + FT_NONE, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_adsdnrequest, + { "ADS Device Notification Request", "ams.ads_dn_req", + FT_NONE, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_adsdnresponse, + { "ADS Device Notification Response", "ams.ads_dn_res", + FT_NONE, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_adsnoteattrib, + { "InvokeId", "ams.ads_noteattrib", + FT_NONE, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_adsnoteblocks, + { "InvokeId", "ams.ads_noteblocks", + FT_NONE, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_adsversion, + { "ADS Version", "ams.ads_version", + FT_UINT32, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_adsdevicename, + { "Device Name","ams.ads_devicename", + FT_STRING, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_adsversionversion, + { "ADS Major Version", "ams.ads_versionversion", + FT_UINT8, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_adsversionrevision, + { "ADS Minor Version", "ams.ads_versionrevision", + FT_UINT8, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_adsversionbuild, + { "ADS Version Build", "ams.ads_versionbuild", + FT_UINT16, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_adsnoteblocksstamps, + { "Count of Stamps", "ams.ads_noteblocksstamps", + FT_UINT32, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_adsnoteblocksstamp, + { "Notification Stamp", "ams.ads_noteblocksstamp", + FT_NONE, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_adstimestamp, + { "Time Stamp", "ams.ads_timestamp", + FT_UINT64, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_adssamplecnt, + { "Count of Stamps", "ams.ads_samplecnt", + FT_UINT32, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_adsnoteblockssample, + { "Notification Sample", "ams.ads_noteblockssample", + FT_NONE, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_adstransmode, + { "Trans Mode", "ams.ads_transmode", + FT_UINT32, BASE_DEC, VALS(TransMode), 0x0, + "", HFILL } + }, + { &hf_ams_adsmaxdelay, + { "Max Delay", "ams.ads_maxdelay", + FT_UINT32, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_adscycletime, + { "Cycle Time", "ams.ads_cycletime", + FT_UINT32, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_adscmpmax, + { "Cmp Mad", "ams.ads_cmpmax", + FT_NONE, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_ams_adscmpmin, + { "Cmp Min", "ams.ads_cmpmin", + FT_NONE, BASE_NONE, NULL, 0x0, + "", HFILL } + } + }; + + static gint *ett[] = + { + &ett_ams, + &ett_ams_sender, + &ett_ams_target, + &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, + &ett_ams_adsdnresponse, + &ett_ams_noteblockstamp + }; + + 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)); + + register_dissector("ams", dissect_ams, proto_ams); +} + +/* The registration hand-off routing */ + +void proto_reg_handoff_ams(void) +{ + static dissector_handle_t ams_handle; + + ams_handle = create_dissector_handle(dissect_ams,proto_ams); + dissector_add("tcp.port", 0xbf02, ams_handle); + dissector_add("ecatf.type", 2, ams_handle); +} diff --git a/plugins/ethercat/packet-ams.h b/plugins/ethercat/packet-ams.h new file mode 100644 index 0000000000..77bc184e7d --- /dev/null +++ b/plugins/ethercat/packet-ams.h @@ -0,0 +1,1208 @@ +/* Copyright (c) 2007 by Beckhoff Automation GmbH + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * 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. + */ +/* Ams.h*/ + +#ifndef __PACKET_AMS_H__ +#define __PACKET_AMS_H__ + +/* FIXED PORTS */ + +#define AMSPORT_ROUTER 1 +#define AMSPORT_DEBUGGER 2 + +#define AMSPORT_LOGGER 100 +#define AMSPORT_EVENTLOG 110 +#define AMSPORT_R0_RTIME 200 +#define AMSPORT_R0_TRACE (AMSPORT_R0_RTIME+90) +#define AMSPORT_R0_IO 300 +#define AMSPORT_R0_SPS 400 +#define AMSPORT_R0_NC 500 +#define AMSPORT_R0_NCSAF 501 +#define AMSPORT_R0_NCSVB 511 +#define AMSPORT_R0_ISG 550 +#define AMSPORT_R0_CNC 600 +#define AMSPORT_R0_LINE 700 +#define AMSPORT_R0_PLC 800 +#define AMSPORT_R0_CAM 900 +#define AMSPORT_R0_CAMTOOL 950 + +#define AMSPORT_R0_IOPORTBEGIN 1000 +#define AMSPORT_R0_IOPORTEND 1199 + +#define AMSPORT_R0_USER 2000 + +#define AMSPORT_R3_SYSSERV 10000 +#define AMSPORT_R3_CTRLPROG 10000 +#define AMSPORT_R3_SYSCTRL 10001 +#define AMSPORT_R3_SYSSAMPLER 10100 +#define AMSPORT_R3_TCPRAWCONN 10200 +#define AMSPORT_R3_TCPIPSERVER 10201 +#define AMSPORT_R3_SYSMANAGER 10300 +#define AMSPORT_R3_SMSSERVER 10400 +#define AMSPORT_R3_MODBUSSERVER 10500 +#define AMSPORT_R3_PLCCONTROL 10800 +#define AMSPORT_R3_NCCTRL 11000 +#define AMSPORT_R3_NCINTERPRETER 11500 +#define AMSPORT_R3_STRECKECTRL 12000 +#define AMSPORT_R3_CAMCTRL 13000 +#define AMSPORT_R3_SCOPE 14000 +#define AMSPORT_R3_SINECH1 15000 +#define AMSPORT_R3_CONTROLNET 16000 +#define AMSPORT_R3_OPCSERVER 17000 +#define AMSPORT_R3_OPCCLIENT 17500 + +#define AMSPORT_R3_CUSTOMER_FIRST 25000 +#define AMSPORT_R3_CUSTOMER_LAST 25999 + +#define AMSPORT_FIRST 1 +#define AMSPORT_LAST 0xFFFE + +#define AMSPORT_UNFIXEDPORT 0 +#define AMSPORT_USEDEFAULT 0xFFFF + +#define AMSPORT_IOBOXBEGIN_USB 0x6E00 +#define AMSPORT_IOBOXEND_USB 0x6EFF +#define AMSPORT_IODEVBEGIN 0x7000 +#define AMSPORT_IODEVEND 0x70FF +#define AMSPORT_IOBOXBEGIN 0x7100 +#define AMSPORT_IOBOXEND 0x7FFF + +#define AMSPORT_FREEBEGIN 0x8000 +#define AMSPORT_FREEEND 0xBFFF + + +#define AMSPORT_NAMESIZE 31 + +/* Port types */ +typedef enum +{ + PORTTYPE_INVALID = -1, + PORTTYPE_ROUTER = 0x00, + PORTTYPE_R3PORT = 0x01, + PORTTYPE_R0CTRLPORT = 0x02, + PORTTYPE_R0TASKPORT = 0x03, + PORTTYPE_R0IOPORT = 0x04, + PORTTYPE_TPPORT = 0x05, + PORTTYPE_MAXVAL = 0xFF +}AMSPORT_TYPE; + +/* Command IDs */ + +#define AMSCMD_LOGMESSAGE 0x0001 +#define AMSCMD_ROUTERSHUTDOWN 0x0002 +#define AMSCMD_ROUTERACTIVATED 0x0003 +#define AMSCMD_SYSTEMREMOVED 0x0004 +#define AMSCMD_CLOSECONNECTION 0x0005 +#define AMSCMD_SIGNALSTART 0x00FB +#define AMSCMD_SIGNALSTOP 0x00FC +#define AMSCMD_HANDLERETAINDATA 0x00FD +#define AMSCMD_DEVICECONFIGID 0x00FE +#define AMSCMD_DOWNLOADSYMBOLS 0x00FF + +#define AMS_ERRLOGCMDS 0x100 + +#define AMS_TASKCMDS 0x500 +#define AMS_CTRLCMDS 0x600 + +#define AMS_ROUTERCMDS 0x900 +#define AMS_RTIMECMDS 0x1000 +#define AMS_TRACECMDS (AMS_RTIMECMDS+0x900) +#define AMS_IOCMDS 0x2000 +#define AMS_C1220CMDS (AMS_IOCMDS+0x100) +#define AMS_FCxxxxCMDS (AMS_IOCMDS+0x200) +#define AMS_SPSCMDS 0x3000 +#define AMS_NCCMDS 0x4000 +#define AMS_PLCCMDS 0x5000 +#define AMS_LINECMDS 0x6000 +#define AMS_CAMCMDS 0x7000 + +#define AMS_CMDSPECIFIC 0x8000 + + +#define AMSERRCODEISWARNING 0x80000000 + +/* Error Arrays */ + +#define ERR_ROUTERERRS 0x0500 +#define ERR_TASKERRS 0x0600 +#define ERR_ADSERRS 0x0700 +#define ERR_SYSSMPLERRS 0x0800 +#define ERR_RTIMEERRS 0x1000 +#define ERR_TRACEERRS (ERR_RTIMEERRS+0x900) +#define ERR_IOERRS 0x2000 +#define ERR_DPSLAVE (ERR_IOERRS+0x900) +#define ERR_CP5412A2 (ERR_IOERRS+0xA00) +#define ERR_ASP (ERR_IOERRS+0xB00) +#define ERR_CANSLAVE (ERR_IOERRS+0xC00) +#define ERR_CIF30 (ERR_IOERRS+0xD00) +#define ERR_IBSSLAVE (ERR_IOERRS+0xE00) +#define ERR_SPSERRS 0x3000 +#define ERR_NCERRS 0x4000 +#define ERR_PLCERRS 0x6000 +#define ERR_STRKERRS 0x7000 + +#define ERR_PRJSPECIFIC 0x7800 + +#define ERR_DRIVEERRS_C3D 0xD000 +#define ERR_DRIVEERRS_C2D 0xE000 +#define ERR_DRIVEERRS_C1D 0xF000 + + +/* Global Error codes */ +#define ERR_NOERROR 0 +#define ERR_INTERNAL 1 +#define ERR_NORTIME 2 +#define ERR_ALLOCLOCKEDMEM 3 +#define ERR_INSERTMAILBOX 4 +#define ERR_WRONGRECEIVEHMSG 5 +#define ERR_TARGETPORTNOTFOUND 6 +#define ERR_TARGETMACHINENOTFOUND 7 +#define ERR_UNKNOWNCMDID 8 +#define ERR_BADTASKID 9 +#define ERR_NOIO 10 +#define ERR_UNKNOWNAMSCMD 11 +#define ERR_WIN32ERROR 12 +#define ERR_PORTNOTCONNECTED 13 +#define ERR_INVALIDAMSLENGTH 14 +#define ERR_INVALIDAMSNETID 15 +#define ERR_LOWINSTLEVEL 16 +#define ERR_NODEBUGINTAVAILABLE 17 +#define ERR_PORTDISABLED 18 +#define ERR_PORTALREADYCONNECTED 19 +#define ERR_AMSSYNC_W32ERROR 20 +#define ERR_AMSSYNC_TIMEOUT 21 +#define ERR_AMSSYNC_AMSERROR 22 +#define ERR_AMSSYNC_NOINDEXINMAP 23 +#define ERR_INVALIDAMSPORT 24 +#define ERR_NOMEMORY 25 +#define ERR_TCPSEND 26 +#define ERR_HOSTUNREACHABLE 27 +#define ERR_INVALIDAMSFRAGMENT 28 + + +/* ROUTER */ +#define ROUTERERR_NOLOCKEDMEMORY 0 + ERR_ROUTERERRS +#define ROUTERERR_RESIZEMEMORY 1 + ERR_ROUTERERRS +#define ROUTERERR_MAILBOXFULL 2 + ERR_ROUTERERRS +#define ROUTERERR_DEBUGBOXFULL 3 + ERR_ROUTERERRS +#define ROUTERERR_UNKNOWNPORTTYPE 4 + ERR_ROUTERERRS +#define ROUTERERR_NOTINITIALIZED 5 + ERR_ROUTERERRS +#define ROUTERERR_PORTALREADYINUSE 6 + ERR_ROUTERERRS +#define ROUTERERR_NOTREGISTERED 7 + ERR_ROUTERERRS +#define ROUTERERR_NOMOREQUEUES 8 + ERR_ROUTERERRS +#define ROUTERERR_INVALIDPORT 9 + ERR_ROUTERERRS +#define ROUTERERR_NOTACTIVATED 10 + ERR_ROUTERERRS +#define ROUTERERR_FRAGMENTBOXFULL 11 + ERR_ROUTERERRS +#define ROUTERERR_FRAGMENTTIMEOUT 12 + ERR_ROUTERERRS +#define ROUTERERR_TOBEREMOVED 13 + ERR_ROUTERERRS + +#define TASKERR_UNKNOWNTASKTYPE 0 + ERR_TASKERRS +#define TASKERR_TASKTERMINATED 1 + ERR_TASKERRS +#define TASKERR_EVENTTIMEOUT 2 + ERR_TASKERRS + + +/* System Sampler */ +#define SMPLERR_INTERNAL 0 + ERR_SYSSMPLERRS +#define SMPLERR_INVALIDTYPE 1 + ERR_SYSSMPLERRS + + +/* RTIME */ +#define RTERR_INTERNAL 0 + ERR_RTIMEERRS +#define RTERR_BADTIMERPERIODS 1 + ERR_RTIMEERRS +#define RTERR_INVALIDTASKPTR 2 + ERR_RTIMEERRS +#define RTERR_INVALIDSTACKPTR 3 + ERR_RTIMEERRS +#define RTERR_PRIOEXISTS 4 + ERR_RTIMEERRS +#define RTERR_NOMORETCB 5 + ERR_RTIMEERRS +#define RTERR_NOMORESEMAS 6 + ERR_RTIMEERRS +#define RTERR_NOMOREQUEUES 7 + ERR_RTIMEERRS +#define RTERR_SHUTDOWNTIMEOUT 8 + ERR_RTIMEERRS +#define RTERR_CHECKHOSTOSNOPCR 9 + ERR_RTIMEERRS +#define RTERR_CHECKHOSTOSNOIDT 10 + ERR_RTIMEERRS +#define RTERR_CHECKHOSTOSNOPHYSMEM 11 + ERR_RTIMEERRS +#define RTERR_CHECKHOSTOSMAPERR 12 + ERR_RTIMEERRS +#define RTERR_EXTIRQALREADYDEF 13 + ERR_RTIMEERRS +#define RTERR_EXTIRQNOTDEF 14 + ERR_RTIMEERRS +#define RTERR_EXTIRQINSTALLFAILED 15 + ERR_RTIMEERRS +#define RTERR_IRQLNOTLESSOREQUAL 16 + ERR_RTIMEERRS +#define RTERR_SYSCLOCKFAILURE 17 + ERR_RTIMEERRS + + +/* TRACE */ +#define TRACEERR_REGISTRY 0 + ERR_TRACEERRS +#define TRACEERR_MEMMAP 1 + ERR_TRACEERRS +#define TRACEERR_NOTAVAIL 2 + ERR_TRACEERRS + + +/* IO */ +#define IOERR_INTERNAL (0 + ERR_IOERRS) +#define IOERR_BADCARDNO (1 + ERR_IOERRS) +#define IOERR_INVALIDCARDADDR (2 + ERR_IOERRS) +#define IOERR_CDLLISTFULL (3 + ERR_IOERRS) +#define IOERR_BADCDLPARAM (4 + ERR_IOERRS) +#define IOERR_OPENIOFAILED (5 + ERR_IOERRS) +#define IOERR_RESETIOFAILED (6 + ERR_IOERRS) +#define IOERR_UNKNOWNDEVICE (7 + ERR_IOERRS) +#define IOERR_UNKNOWNDEVICEID (8 + ERR_IOERRS) +#define IOERR_UNKNOWNIMAGEID (9 + ERR_IOERRS) +#define IOERR_GETIOSTATE (10 + ERR_IOERRS) +#define IOERR_BADIMAGEID (11 + ERR_IOERRS) +#define IOERR_NOMORECLIENTSPACE (12 + ERR_IOERRS) +#define IOERR_CLIENTINFONOTFOUND (13 + ERR_IOERRS) +#define IOERR_CDLNOTINUSE (14 + ERR_IOERRS) +#define IOERR_TIMEOUTWITHDEVICE (15 + ERR_IOERRS) +#define IOERR_C1220FUNC_1 (16 + ERR_IOERRS) +#define IOERR_C1220FUNC_9 (17 + ERR_IOERRS) +#define IOERR_C1220FUNC_C (18 + ERR_IOERRS) +#define IOERR_C1220FUNC_10 (19 + ERR_IOERRS) +#define IOERR_C1220FUNC_1_MAXSEND (20 + ERR_IOERRS) +#define IOERR_C1220FUNC_1_ADDRSET (21 + ERR_IOERRS) +#define IOERR_C1220FUNC_1_BREAK (22 + ERR_IOERRS) +#define IOERR_C1220FUNC_1_BREAK0 (23 + ERR_IOERRS) +#define IOERR_C1220FUNC_1_BREAK1 (24 + ERR_IOERRS) +#define IOERR_C1220FUNC_1_BREAK2 (25 + ERR_IOERRS) +#define IOERR_C1220FUNC_1_BREAK3 (26 + ERR_IOERRS) +#define IOERR_C1220FUNC_1_BREAK4 (27 + ERR_IOERRS) +#define IOERR_C1220FUNC_1_BREAK5 (28 + ERR_IOERRS) +#define IOERR_C1220FUNC_1_BREAK6 (29 + ERR_IOERRS) +#define IOERR_C1220FUNC_1_BREAK7 (30 + ERR_IOERRS) +#define IOERR_C1220FUNC_1_BREAK8 (31 + ERR_IOERRS) +#define IOERR_C1220FUNC_1_BREAK9 (32 + ERR_IOERRS) +#define IOERR_C1220FUNC_1_BREAK10 (33 + ERR_IOERRS) +#define IOERR_C1220FUNC_1_BREAK11 (34 + ERR_IOERRS) +#define IOERR_C1220FUNC_1_BREAK12 (35 + ERR_IOERRS) +#define IOERR_C1220FUNC_1_BREAK13 (36 + ERR_IOERRS) +#define IOERR_C1220FUNC_1_BREAK14 (37 + ERR_IOERRS) +#define IOERR_C1220FUNC_1_BREAK15 (38 + ERR_IOERRS) +#define IOERR_C1220FUNC_1_BREAK16 (39 + ERR_IOERRS) +#define IOERR_SPC3DEVINITDP (40 + ERR_IOERRS) +#define IOERR_SPC3UPDATEOUTPUT (41 + ERR_IOERRS) +#define IOERR_CIF30READDIAG (42 + ERR_IOERRS) +#define IOERR_CIF30COMMNOTSTARTED (43 + ERR_IOERRS) +#define IOERR_CIF30SLAVEPARASIZE (44 + ERR_IOERRS) +#define IOERR_CIF30NOPARAS (45 + ERR_IOERRS) +#define IOERR_CIF30SLAVEERROR (46 + ERR_IOERRS) +#define IOERR_CIF30WATCHDOGEXPIRED (47 + ERR_IOERRS) +#define IOERR_UNKNOWNDEVICECMD (48 + ERR_IOERRS) +#define IOERR_CIF40MESSAGEHANDLING (49 + ERR_IOERRS) +#define IOERR_CIF40PARAERROR (50 + ERR_IOERRS) +#define IOERR_CIF40WATCHDOGEXPIRED (51 + ERR_IOERRS) +#define IOERR_CIF40FLAGERROR (52 + ERR_IOERRS) +#define IOERR_CIF40COMMNOTSTARTED (53 + ERR_IOERRS) +#define IOERR_CIF40READDIAG (54 + ERR_IOERRS) +#define IOERR_CIF40SLAVEERROR (55 + ERR_IOERRS) +#define IOERR_CIF40GLOBALERROR (56 + ERR_IOERRS) +#define IOERR_CIF40CONFIGLIST (57 + ERR_IOERRS) +#define IOERR_CP5412A2SLAVEPARASIZE (58 + ERR_IOERRS) +#define IOERR_CP5412A2NOPARAS (59 + ERR_IOERRS) +#define IOERR_CP5412A2SLAVEERROR (60 + ERR_IOERRS) +#define IOERR_CP5412A2FATAL (61 + ERR_IOERRS) +#define IOERR_CP5412A2MAILBOXUSED (62 + ERR_IOERRS) +#define IOERR_BEGINCONFIGWHILETICKER (63 + ERR_IOERRS) +#define IOERR_UNEXPECTEDBOXCOUNT (64 + ERR_IOERRS) +#define IOERR_C1200CHECKADDR (65 + ERR_IOERRS) +#define IOERR_C1200INTENSITYTEST (66 + ERR_IOERRS) +#define IOERR_NOIMAGE (67 + ERR_IOERRS) +#define IOERR_INVALIDIMAGEOFFSSIZE (68 + ERR_IOERRS) +#define IOERR_FORCESCOUNTEXCEEDEDMAXIMUM (69 + ERR_IOERRS) +#define IOERR_SERCOSLIFECOUNTERERR (70 + ERR_IOERRS) +#define IOERR_C1220NOTFOUND (71 + ERR_IOERRS) +#define IOERR_AMSDEVICENOAMSINTF (72 + ERR_IOERRS) +#define IOERR_AMSDEVICEAMSCMDIDNOTSUPP (73 + ERR_IOERRS) +#define IOERR_AMSDEVICEAMSSERVICERUNNING (74 + ERR_IOERRS) +#define IOERR_PLCINTERFACE_BUSY (75 + ERR_IOERRS) +#define IOERR_PLCINTERFACE_FAULT (76 + ERR_IOERRS) +#define IOERR_PLCINTERFACE_TIMEOUT (77 + ERR_IOERRS) +#define IOERR_PLCINTERFACE_RESETTIMEOUT (78 + ERR_IOERRS) +#define IOERR_PLCINTERFACE_NODATAEXCH (79 + ERR_IOERRS) +#define IOERR_PLCINTERFACE_RESET (80 + ERR_IOERRS) +#define IOERR_CP5412A2INVALIDADDR (81 + ERR_IOERRS) +#define IOERR_CP5412A2INVALIDPORT (82 + ERR_IOERRS) +#define IOERR_AMSDEVICEBADBOXNO (83 + ERR_IOERRS) +#define IOERR_AMSDEVICEBADTYPE (84 + ERR_IOERRS) +#define IOERR_AMSDEVICEILLEGALADDRESS (85 + ERR_IOERRS) +#define IOERR_CP5412A2INVALIDBOX (86 + ERR_IOERRS) +#define IOERR_AMSDEVICEFIFOOVERFLOW (87 + ERR_IOERRS) +#define IOERR_AMSDEVICEAMSSEQUENCEERROR (88 + ERR_IOERRS) +#define IOERR_CP5412A2DPV1SYNTAXERROR (89 + ERR_IOERRS) +#define IOERR_CP5412A2DEVICENOTRUNNING (90 + ERR_IOERRS) +#define IOERR_AMSDEVICENOTRUNNING (91 + ERR_IOERRS) +#define IOERR_AMSDEVICEBOXNOTDEFINED (92 + ERR_IOERRS) +#define IOERR_CP5412A2BADSERVICEPARA (93 + ERR_IOERRS) +#define IOERR_CP5412A2FIFOOVERFLOW (94 + ERR_IOERRS) +#define IOERR_COMPORTOPENFAILED (95 + ERR_IOERRS) +#define IOERR_CIF30BADMESSAGERESPONSE (96 + ERR_IOERRS) +#define IOERR_CIF30DELETEDATABASE (97 + ERR_IOERRS) +#define IOERR_CIF30STARTSEQFAILED (98 + ERR_IOERRS) +#define IOERR_CIF30DOWNLOADFAILED (99 + ERR_IOERRS) +#define IOERR_CIF30ENDSEQFAILED (100 + ERR_IOERRS) +#define IOERR_CIF30BUSLOADFAILED (101 + ERR_IOERRS) +#define IOERR_PLCINTERFACE_RESETREQ (102 + ERR_IOERRS) +#define IOERR_CP5412A2INVALIDCYCLETICKS (103 + ERR_IOERRS) +#define IOERR_CP5412A2DPBUSFAULT (104 + ERR_IOERRS) +#define IOERR_INVALIDTERMCONFIG (105 + ERR_IOERRS) +#define IOERR_SERCANSBREAK (106 + ERR_IOERRS) +#define IOERR_SERCANSPHASE0 (107 + ERR_IOERRS) +#define IOERR_SERCANSPHASE1 (108 + ERR_IOERRS) +#define IOERR_SERCANSPHASE2 (109 + ERR_IOERRS) +#define IOERR_SERCANSPHASE3 (110 + ERR_IOERRS) +#define IOERR_SERCANSPHASE4 (111 + ERR_IOERRS) +#define IOERR_SERCANSNCSERVICECHNFAILED (112 + ERR_IOERRS) +#define IOERR_RESOURCECONFICT (113 + ERR_IOERRS) +#define IOERR_C1220INITSTRINGCOMM (114 + ERR_IOERRS) +#define IOERR_C1220REGSTRINGSLAVE (115 + ERR_IOERRS) +#define IOERR_C1220STRREGFAULT (116 + ERR_IOERRS) +#define IOERR_IOSTATEBUSY (117 + ERR_IOERRS) +#define IOERR_IBSSCITWATCHDOGEXPIRED (118 + ERR_IOERRS) +#define IOERR_IBSSCITSYNCMAILBOXERROR (119 + ERR_IOERRS) +#define IOERR_IBSSCITCONFIRMDIAGERROR (120 + ERR_IOERRS) +#define IOERR_IBSSCITCREATECFGERROR (121 + ERR_IOERRS) +#define IOERR_IBSSCITCOMPLETEREADCFGERROR (122 + ERR_IOERRS) +#define IOERR_IBSSCITSTARTDATATRANSFERERROR (123 + ERR_IOERRS) +#define IOERR_IBSSCITSETFAULTINDICATION (124 + ERR_IOERRS) +#define IOERR_IBSSCITSETDEVICESTATEINDICATION (125 + ERR_IOERRS) +#define IOERR_IBSSCITSETBUSERRORINDICATION (126 + ERR_IOERRS) +#define IOERR_IBSSCITSTOPDATATRANSFERERROR (127 + ERR_IOERRS) +#define IOERR_IBSSCITSETVALUEINDICATION (128 + ERR_IOERRS) +#define IOERR_IBSSCITINITIATEREQ (129 + ERR_IOERRS) +#define IOERR_IBSSCITACTIVATECFGERROR (130 + ERR_IOERRS) +#define IOERR_IBSSCITCOMPACTLOADPDRLERROR (131 + ERR_IOERRS) +#define IOERR_IBSSCITCONTROLPARAMERROR (132 + ERR_IOERRS) +#define IOERR_IBSSCITDEACTIVATECFGERROR (133 + ERR_IOERRS) +#define IOERR_IBSSCITINVALIDPORT (134 + ERR_IOERRS) +#define IOERR_C1220FUNC_7_ADDRESSTEST (135 + ERR_IOERRS) +#define IOERR_FCXXXXMAILBOXUSED (136 + ERR_IOERRS) +#define IOERR_FCXXXXDPRAMTOOSMALL (137 + ERR_IOERRS) +#define IOERR_COMUPS_PORTINUSE (138 + ERR_IOERRS) +#define IOERR_COMUPS_NOUPSORNOPOWER (139 + ERR_IOERRS) +#define IOERR_COMUPS_LOWBATTERY (140 + ERR_IOERRS) +#define IOERR_UPS_ALREADY_EXISTS (141 + ERR_IOERRS) +#define IOERR_FCXXXXSTARTUPFAILED (142 + ERR_IOERRS) +#define IOERR_C1220GETSTRINGCOMMTXSTATEFAILED (143 + ERR_IOERRS) +#define IOERR_C1220SENDSTRINGTOSLAVEFAILED (144 + ERR_IOERRS) +#define IOERR_CP5613FIRMWARELOADFAILED (145 + ERR_IOERRS) +#define IOERR_CP5613DPOPENFAILED (146 + ERR_IOERRS) +#define IOERR_CP5613FATALERROR (147 + ERR_IOERRS) +#define IOERR_CP5613DPUSEROPENFAILED (148 + ERR_IOERRS) +#define IOERR_CP5613DPSETMODESTOPFAILED (149 + ERR_IOERRS) +#define IOERR_CP5613DPSETMODECLEARFAILED (150 + ERR_IOERRS) +#define IOERR_CP5613DPSETMODEOPERATEFAILED (151 + ERR_IOERRS) +#define IOERR_CP5613NODATAAVAILABLE (152 + ERR_IOERRS) +#define IOERR_CP5613DPSERVICEFAILED (153 + ERR_IOERRS) +#define IOERR_CP5613DPSETMODEOFFLINEFAILED (154 + ERR_IOERRS) +#define IOERR_CP5613DPUSERCLOSEFAILED (155 + ERR_IOERRS) +#define IOERR_CP5613DPCLOSEFAILED (156 + ERR_IOERRS) +#define IOERR_CP5613OTHERSERVICERETURNED (157 + ERR_IOERRS) +#define IOERR_CP5613DPOKASYNC (158 + ERR_IOERRS) +#define IOERR_CP5613DPERROREVENT (159 + ERR_IOERRS) +#define IOERR_CP5613DPERROREVENTNET (160 + ERR_IOERRS) +#define IOERR_CP5613DPERRORREQPAR (161 + ERR_IOERRS) +#define IOERR_CP5613DPERRORCI (162 + ERR_IOERRS) +#define IOERR_CP5613DPERRORRES (163 + ERR_IOERRS) +#define IOERR_CP5613DPERRORUSRABORT (164 + ERR_IOERRS) +#define IOERR_PKWSYNTAXERROR (165 + ERR_IOERRS) +#define IOERR_CP5412A2CDLCFGFAULT (166 + ERR_IOERRS) +#define IOERR_IBSSCITINITLOADCFGERROR (168 + ERR_IOERRS) +#define IOERR_IBSSCITLOADCFGERROR (169 + ERR_IOERRS) +#define IOERR_IBSSCITTERMLOADCFGERROR (170 + ERR_IOERRS) +#define IOERR_IBSSCITINITLOADPDRLERROR (171 + ERR_IOERRS) +#define IOERR_IBSSCITLOADPDRLERROR (172 + ERR_IOERRS) +#define IOERR_IBSSCITTERMLOADPDRLERROR (173 + ERR_IOERRS) +#define IOERR_IBSSCITDELETEOBJECTERROR (174 + ERR_IOERRS) +#define IOERR_IBSSCITCONTROLACTIVECFGGERROR (175 + ERR_IOERRS) +#define IOERR_IBSSCITINITLOADPDDLERROR (176 + ERR_IOERRS) +#define IOERR_IBSSCITLOADPDDLERROR (177 + ERR_IOERRS) +#define IOERR_IBSSCITTERMLOADPDDLERROR (178 + ERR_IOERRS) +#define IOERR_NOMOREMAPSINIMAGE (179 + ERR_IOERRS) +#define IOERR_IBSSCITSETSLAVEINFOERROR (180 + ERR_IOERRS) +#define IOERR_CIF40NOTREADY (190 + ERR_IOERRS) +#define IOERR_C1220SETAMSNETIDFAILED (191 + ERR_IOERRS) +#define IOERR_AMSDEVICEIORESETACTIVE (192 + ERR_IOERRS) +#define IOERR_C1220INITPROGRAMMABLECDL (193 + ERR_IOERRS) +#define IOERR_FCXXXXINVALIDBOXNODOWNLOADED (194 + ERR_IOERRS) + + +#define IOERR_CP5412A2_RESET (4 + ERR_CP5412A2) +#define IOERR_CP5412A2_LOADBUSPARA (5 + ERR_CP5412A2) +#define IOERR_CP5412A2_LOADSLAVE (6 + ERR_CP5412A2) +#define IOERR_CP5412A2_LOADPRMDATA (7 + ERR_CP5412A2) +#define IOERR_CP5412A2_LOADCFGDATA (8 + ERR_CP5412A2) +#define IOERR_CP5412A2_LOADSLAVECDL (9 + ERR_CP5412A2) +#define IOERR_CP5412A2_ACTIVATESLAVE (10 + ERR_CP5412A2) +#define IOERR_CP5412A2_ADDSLAVE (11 + ERR_CP5412A2) +#define IOERR_CP5412A2_DELETESLAVE (12 + ERR_CP5412A2) +#define IOERR_CP5412A2_STARTDATAEXCH (13 + ERR_CP5412A2) +#define IOERR_CP5412A2_STOPDATAEXCH (14 + ERR_CP5412A2) +#define IOERR_CP5412A2_DEBUGDPM (15 + ERR_CP5412A2) + + +/* FC Box - stamndadisiert */ + +#define FCERR_FMNOERROR 0 +#define FCERR_FMDEACTIVATED 1 +#define FCERR_FMNOANSWER 2 +#define FCERR_FMMASTERLOCK 3 +#define FCERR_FMINVALIDRESPONSE 4 +#define FCERR_FMPRMFAULT 5 +#define FCERR_FMFEATURENOTSUPPORTED 6 +#define FCERR_FMCFGFAULT 7 +#define FCERR_FMSTATIONNOTREADY 8 +#define FCERR_FMSTATDIAG 9 +#define FCERR_FMDIAGOVERFLOW 10 +#define FCERR_FMPHYSICALFAULT 11 +#define FCERR_FMDATATRANSFERLEFT 12 +#define FCERR_FMSYNIFAULT 13 +#define FCERR_FMTELEGRAMFAULT 14 +#define FCERR_FMNORESSOURCES 15 +#define FCERR_FMSERVICENOTACTIVATED 16 +#define FCERR_FMUNEXPECTEDTELEGRAM 17 +#define FCERR_FMSTATIONREADY 18 +#define FCERR_FMADSSTARTUP 19 +#define FCERR_FMINVALIDINDICATION 20 +#define FCERR_FMSTATIONINFAULT 21 +#define FCERR_FMINDICATIONMISSED 22 +#define FCERR_FMWAITFORINDICATIONS 23 + +#define FCERR_FMFBUSSPECIFIC_1 40 +#define FCERR_FMFBUSSPECIFIC_2 41 +#define FCERR_FMFBUSSPECIFIC_3 42 +#define FCERR_FMFBUSSPECIFIC_4 43 +#define FCERR_FMFBUSSPECIFIC_5 44 +#define FCERR_FMFBUSSPECIFIC_6 45 +#define FCERR_FMFBUSSPECIFIC_7 46 +#define FCERR_FMFBUSSPECIFIC_8 47 +#define FCERR_FMFBUSSPECIFIC_9 48 + + +/* FC520x */ + +#define FCERR_FMFC520XHEARTBEATFAULT 40 +#define FCERR_FMFC520XSHUTDOWNRECEIVED 41 +#define FCERR_FMFC520XEKEYERROR_VENDOR 42 +#define FCERR_FMFC520XEKEYERROR_DEVTYPE 43 +#define FCERR_FMFC520XEKEYERROR_PRODCODE 44 +#define FCERR_FMFC520XEKEYERROR_REVISION 45 +#define FCERR_FMFC520XSTARTUPATTR 46 +#define FCERR_FMFC520XIOLENGTH_PROD 47 +#define FCERR_FMFC520XIOLENGTH_CONS 48 + +#define FCERR_FMFC520XDEVICEOPERATE_RUN 0 +#define FCERR_FMFC520XDEVICEOPERATE_IDLE 1 +#define FCERR_FMFC520XDEVICEDUPMAC 2 +#define FCERR_FMFC520XDEVICESELFTEST 3 +#define FCERR_FMFC520XDEVICESTANDBY 4 +#define FCERR_FMFC520XDEVICEMAJORFAULT 5 +#define FCERR_FMFC520XDEVICEMINORFAULT 6 +#define FCERR_FMFC520XDEVICEBUSSENSEFAIL 7 + +#define FCERR_FMFC520XCANBUSON 0x01 +#define FCERR_FMFC520XCANBUSOFF 0x02 +#define FCERR_FMFC520XCANWARNINGLIMIT 0x04 +#define FCERR_FMFC520XCANOVERRUN 0x08 + + +/* DP-Slave-Errors */ + +#define DPSLAVEERROR_NOERROR (FCERR_FMNOERROR + ERR_DPSLAVE) +#define DPSLAVEERROR_STATIONDEACTIVATED (FCERR_FMDEACTIVATED + ERR_DPSLAVE) +#define DPSLAVEERROR_STATIONNONEXISTENT (FCERR_FMNOANSWER + ERR_DPSLAVE) +#define DPSLAVEERROR_MASTERLOCK (FCERR_FMMASTERLOCK + ERR_DPSLAVE) +#define DPSLAVEERROR_INVALIDSLAVERESPONSE (FCERR_FMINVALIDRESPONSE + ERR_DPSLAVE) +#define DPSLAVEERROR_PRMFAULT (FCERR_FMPRMFAULT + ERR_DPSLAVE) +#define DPSLAVEERROR_NOTSUPPORTED (FCERR_FMFEATURENOTSUPPORTED + ERR_DPSLAVE) +#define DPSLAVEERROR_CFGFAULT (FCERR_FMCFGFAULT + ERR_DPSLAVE) +#define DPSLAVEERROR_STATIONNOTREADY (FCERR_FMSTATIONNOTREADY + ERR_DPSLAVE) +#define DPSLAVEERROR_STATDIAG (FCERR_FMSTATDIAG + ERR_DPSLAVE) +#define DPSLAVEERROR_DIAGOVERFLOW (FCERR_FMDIAGOVERFLOW + ERR_DPSLAVE) +#define DPSLAVEERROR_PHYSICALFAULT (FCERR_FMPHYSICALFAULT + ERR_DPSLAVE) +#define DPSLAVEERROR_TELEGRAMFAULT (FCERR_FMTELEGRAMFAULT + ERR_DPSLAVE) +#define DPSLAVEERROR_NORESSOURCES (FCERR_FMNORESSOURCES + ERR_DPSLAVE) +#define DPSLAVEERROR_SERVICENOTACTIVATED (FCERR_FMSERVICENOTACTIVATED + ERR_DPSLAVE) +#define DPSLAVEERROR_UNEXPECTEDTELEGRAM (FCERR_FMUNEXPECTEDTELEGRAM + ERR_DPSLAVE) +#define DPSLAVEERROR_STATIONREADY (FCERR_FMSTATIONREADY + ERR_DPSLAVE) +#define DPSLAVEERROR_ADSSTARTUP (FCERR_FMADSSTARTUP + ERR_DPSLAVE) + + +/* CAN-Node-Errors */ + +#define CANNODEERROR_NOERROR (0 + ERR_CANSLAVE) +#define CANNODEERROR_STATIONNONEXISTENT (1 + ERR_CANSLAVE) +#define CANNODEERROR_PRMFAULT (4 + ERR_CANSLAVE) +#define CANNODEERROR_CFGFAULT (6 + ERR_CANSLAVE) +#define CANNODEERROR_DEACTIVATED (8 + ERR_CANSLAVE) +#define CANNODEERROR_PREOPERATIONAL (12 + ERR_CANSLAVE) +#define CANNODEERROR_NOT_OPERATIONAL (13 + ERR_CANSLAVE) + + +/* IBS-Device-Errors */ + +#define IBSDEVICEERROR_NOERROR (0 + ERR_IBSSLAVE) +#define IBSDEVICEERROR_STATIONDEACTIVATED (1 + ERR_IBSSLAVE) +#define IBSDEVICEERROR_STATIONNONEXISTENT (2 + ERR_IBSSLAVE) +#define IBSDEVICEERROR_CFGFAULT (6 + ERR_IBSSLAVE) +#define IBSDEVICEERROR_DIAGOVERFLOW (10 + ERR_IBSSLAVE) +#define IBSDEVICEERROR_PHYSICALFAULT (11 + ERR_IBSSLAVE) + + +/* PLC */ +#define PLCWRN_LOADINGBOOTPRJ ((0 + ERR_PLCERRS) | AMSERRCODEISWARNING) +#define PLCWRN_LOADINGRETAINDATA ((1 + ERR_PLCERRS) | AMSERRCODEISWARNING) + + +/* NC */ +#define ERR_NCR0MANERRS (ERR_NCERRS+0x0000) +#define ERR_NCCHNERRS (ERR_NCERRS+0x0100) + + +/* NC: R0-Manager Error Codes */ +#define NCERR_INTERNAL (0x0000 + ERR_NCR0MANERRS) +#define NCERR_NOMEMORY (0x0001 + ERR_NCR0MANERRS) + +#define NCERR_UNKNOWNCHANNELID (0x0010 + ERR_NCR0MANERRS) +#define NCERR_UNKNOWNGROUPID (0x0011 + ERR_NCR0MANERRS) +#define NCERR_UNKNOWNAXISID (0x0012 + ERR_NCR0MANERRS) +#define NCERR_UNKNOWNENCODERID (0x0013 + ERR_NCR0MANERRS) +#define NCERR_UNKNOWNCONTROLLERID (0x0014 + ERR_NCR0MANERRS) +#define NCERR_UNKNOWNDRIVEID (0x0015 + ERR_NCR0MANERRS) +#define NCERR_UNKNOWNTABULARID (0x0016 + ERR_NCR0MANERRS) + +#define NCERR_UNKNOWNPLCTONCADDR (0x0020 + ERR_NCR0MANERRS) +#define NCERR_UNKNOWNNCTOPLCADDR (0x0021 + ERR_NCR0MANERRS) +#define NCERR_UNKNOWNENCINADDR (0x0022 + ERR_NCR0MANERRS) +#define NCERR_UNKNOWNENCOUTADDR (0x0023 + ERR_NCR0MANERRS) +#define NCERR_UNKNOWNDRIVEINADDR (0x0024 + ERR_NCR0MANERRS) +#define NCERR_UNKNOWNDRIVEOUTADDR (0x0025 + ERR_NCR0MANERRS) + +#define NCERR_UNKNOWNDSLAVETYPE (0x0030 + ERR_NCR0MANERRS) +#define NCERR_UNKNOWNAXISTYPE (0x0031 + ERR_NCR0MANERRS) +#define NCERR_UNKNOWNCHNTYPE (0x0032 + ERR_NCR0MANERRS) + +#define NCERR_AXISINCOMPATIBLE (0x0040 + ERR_NCR0MANERRS) + +#define NCERR_CHANNELINCOMPLETE (0x0050 + ERR_NCR0MANERRS) +#define NCERR_GROUPINCOMPLETE (0x0051 + ERR_NCR0MANERRS) +#define NCERR_AXISINCOMPLETE (0x0052 + ERR_NCR0MANERRS) + +#define NCERR_CHANNELEXISTS (0x0060 + ERR_NCR0MANERRS) +#define NCERR_GROUPEXISTS (0x0061 + ERR_NCR0MANERRS) +#define NCERR_AXISEXISTS (0x0062 + ERR_NCR0MANERRS) +#define NCERR_TABULAREXISTS (0x0063 + ERR_NCR0MANERRS) + +#define NCERR_WRONGCHANNELINDEX (0x0070 + ERR_NCR0MANERRS) +#define NCERR_WRONGGROUPINDEX (0x0071 + ERR_NCR0MANERRS) + + +/* Channel Error Codes */ +#define NCCHNERR_GROUPINDEX (0x0001 + ERR_NCCHNERRS) +#define NCCHNERR_ADDR_GROUP (0x0002 + ERR_NCCHNERRS) +#define NCCHNERR_NO_PLCINTERFACE (0x0003 + ERR_NCCHNERRS) +#define NCCHNERR_ILLEGALMFUNCNR (0x0004 + ERR_NCCHNERRS) +#define NCCHNERR_NOMEMORY (0x0005 + ERR_NCCHNERRS) +#define NCCHNERR_ISBUSY (0x0006 + ERR_NCCHNERRS) +#define NCCHNERR_NOTSUPPORTED (0x0007 + ERR_NCCHNERRS) +#define NCCHNERR_ILLEGALSETTING (0x0008 + ERR_NCCHNERRS) + +#define NCCHNERR_NOFILE (0x0010 + ERR_NCCHNERRS) +#define NCCHNERR_ITPSYNTAXLT (0x0011 + ERR_NCCHNERRS) +#define NCCHNERR_ITPSYNTAXRT (0x0012 + ERR_NCCHNERRS) +#define NCCHNERR_SUBNOTFOUND (0x0013 + ERR_NCCHNERRS) +#define NCCHNERR_LOADBUFFERFULL (0x0014 + ERR_NCCHNERRS) +#define NCCHNERR_INVALIDIDENTIFIER (0x0015 + ERR_NCCHNERRS) +#define NCCHNERR_UNKNOWNIDENTIFIER (0x0016 + ERR_NCCHNERRS) +#define NCCHNERR_SUBINCOMPLETE (0x0017 + ERR_NCCHNERRS) + +#define NCCHNERR_ZERODIVIDE (0x0020 + ERR_NCCHNERRS) +#define NCCHNERR_BADCIRCLE (0x0021 + ERR_NCCHNERRS) +#define NCCHNERR_INVALIDOPERATION (0x0022 + ERR_NCCHNERRS) + +#define NCCHNERR_CALLSTACKOVR (0x0030 + ERR_NCCHNERRS) +#define NCCHNERR_CALLSTACKUDR (0x0031 + ERR_NCCHNERRS) +#define NCCHNERR_CALCSTACKOVR (0x0032 + ERR_NCCHNERRS) +#define NCCHNERR_CALCSTACKUDR (0x0033 + ERR_NCCHNERRS) + +#define NCCHNERR_REGINDEX (0x0040 + ERR_NCCHNERRS) +#define NCCHNERR_GFUNCINDEX (0x0041 + ERR_NCCHNERRS) +#define NCCHNERR_MFUNCINDEX (0x0042 + ERR_NCCHNERRS) +#define NCCHNERR_EXTENDEDADDR (0x0043 + ERR_NCCHNERRS) +#define NCCHNERR_INTERNALINDEXH (0x0044 + ERR_NCCHNERRS) +#define NCCHNERR_MDBACCESSINDEX (0x0045 + ERR_NCCHNERRS) + +#define NCTRAFOERR_CANNOTCHANGE (0x0050 + ERR_NCCHNERRS) +#define NCTRAFOERR_CANNOTCORRECT (0x0051 + ERR_NCCHNERRS) +#define NCTRAFOERR_PLANE (0x0052 + ERR_NCCHNERRS) +#define NCTRAFOERR_DPARAMINVALID (0x0053 + ERR_NCCHNERRS) +#define NCTRAFOERR_TOOLRADIUSINV (0x0054 + ERR_NCCHNERRS) +#define NCTRAFOERR_CHANGETOOLRAD (0x0055 + ERR_NCCHNERRS) +#define NCTRAFOERR_CDOVERFLOW (0x0056 + ERR_NCCHNERRS) +#define NCTRAFOERR_CDON (0x0057 + ERR_NCCHNERRS) +#define NCTRAFOERR_CDCHECK (0x0058 + ERR_NCCHNERRS) +#define NCTRAFOERR_CDUNEXPECTED (0x0059 + ERR_NCCHNERRS) +#define NCTRAFOERR_CDNEGRADIUS (0x005A + ERR_NCCHNERRS) +#define NCTRAFOERR_CDOCCURED (0x005B + ERR_NCCHNERRS) +#define NCTRAFOERR_COOKEDTBLFULL (0x005C + ERR_NCCHNERRS) +#define NCTRAFOERR_TFTBLFULL (0x005D + ERR_NCCHNERRS) +#define NCTRAFOERR_EXECTFTBLFULL (0x005E + ERR_NCCHNERRS) +#define NCTRAFOERR_EXECTFT (0x005F + ERR_NCCHNERRS) + +#define NCBACKUPERR_WRITEDATA (0x0060 + ERR_NCCHNERRS) +#define NCBACKUPERR_TARGETENTRY (0x0061 + ERR_NCCHNERRS) + + +#define MACHINEIDENTRYDONTCARE 0xFF +#define AMS_NETIDLEN 23 + +/* Ensure the same data layout for all platforms */ +#pragma pack(push, 1) + +typedef struct AmsNetId_ +{ + guint8 b[6]; +} AmsNetId, *PAmsNetId; + + +typedef struct AmsAddr_ +{ + AmsNetId netId; + guint16 port; +} AmsAddr, *PAmsAddr; + +typedef union ErrCodeUnion +{ + gint32 errCode; + gint32 hRcv; +} ErrCodeUnion; + +typedef union tUserUnion +{ + gint32 hUser; + struct + { + guint16 fragmentNo; + guint16 packetNo; + }; +} UserUnion; + +typedef struct +{ + AmsAddr target; + AmsAddr sender; + guint16 cmdId; + guint16 stateFlags; + guint32 cbData; + + ErrCodeUnion anErrCodeUnion; + UserUnion aUserUnion; +} AmsHead, *PAmsHead; + + +/* State flags */ + +#define AMSCMDSF_RESPONSE 0x0001 +#define AMSCMDSF_NORETURN 0x0002 +#define AMSCMDSF_ADSCMD 0x0004 +#define AMSCMDSF_SYSCMD 0x0008 +#define AMSCMDSF_HIGHPRIO 0x0010 +#define AMSCMDSF_TIMESTAMPADDED 0x0020 +#define AMSCMDSF_UDP 0x0040 +#define AMSCMDSF_INITCMD 0x0080 +#define AMSCMDSF_BROADCAST 0x8000 + + +/* AmsCmd */ + +typedef struct +{ + AmsHead head; +} AmsCmd, *PAmsCmd; + +#define SIZEOF_AmsCmd(p) (sizeof(AmsHead) + ((PAmsCmd)p)->head.cbData) + +#pragma pack(pop) + +/* ADS */ + +#define ADS_FIXEDNAMESIZE 16 + + +/* ADS Service Ids */ +#define ADSSRVID_INVALID 0x00 +#define ADSSRVID_READDEVICEINFO 0x01 +#define ADSSRVID_READ 0x02 +#define ADSSRVID_WRITE 0x03 +#define ADSSRVID_READSTATE 0x04 +#define ADSSRVID_WRITECTRL 0x05 +#define ADSSRVID_ADDDEVICENOTE 0x06 +#define ADSSRVID_DELDEVICENOTE 0x07 +#define ADSSRVID_DEVICENOTE 0x08 +#define ADSSRVID_READWRITE 0x09 + +/* ADS reserved index groups */ +#define ADSIGRP_SYMTAB 0xF000 +#define ADSIGRP_SYMNAME 0xF001 +#define ADSIGRP_SYMVAL 0xF002 + +#define ADSIGRP_SYM_HNDBYNAME 0xF003 +#define ADSIGRP_SYM_VALBYNAME 0xF004 +#define ADSIGRP_SYM_VALBYHND 0xF005 +#define ADSIGRP_SYM_RELEASEHND 0xF006 +#define ADSIGRP_SYM_INFOBYNAME 0xF007 +#define ADSIGRP_SYM_VERSION 0xF008 +#define ADSIGRP_SYM_INFOBYNAMEEX 0xF009 + +#define ADSIGRP_SYM_DOWNLOAD 0xF00A +#define ADSIGRP_SYM_UPLOAD 0xF00B +#define ADSIGRP_SYM_UPLOADINFO 0xF00C +#define ADSIGRP_SYM_DOWNLOAD2 0xF00D +#define ADSIGRP_SYM_DT_UPLOAD 0xF00E +#define ADSIGRP_SYM_UPLOADINFO2 0xF00F + +#define ADSIGRP_SYMNOTE 0xF010 + +#define ADSIGRP_SYM_DT_INFOBYNAMEEX 0xF011 +#define ADSIGRP_SYM_ADDRBYHND 0xF012 + + +#define ADSIGRP_IOIMAGE_RWIB 0xF020 +#define ADSIGRP_IOIMAGE_RWIX 0xF021 +#define ADSIGRP_IOIMAGE_RISIZE 0xF025 + +#define ADSIGRP_IOIMAGE_RWOB 0xF030 +#define ADSIGRP_IOIMAGE_RWOX 0xF031 +#define ADSIGRP_IOIMAGE_ROSIZE 0xF035 +#define ADSIGRP_IOIMAGE_CLEARI 0xF040 +#define ADSIGRP_IOIMAGE_CLEARO 0xF050 + +#define ADSIGRP_IOIMAGE_RWIOB 0xF060 + +#define ADSIGRP_IOIMAGE_CREATE 0xF068 + +#define ADSIGRP_SUMUP_READ 0xF080 + +#define ADSIGRP_SUMUP_WRITE 0xF081 +#define ADS_SUMUP_IGRP(p, i) (((guint32*)p)[(i)*3+0]) +#define ADS_SUMUP_IOFFS(p, i) (((guint32*)p)[(i)*3+1]) +#define ADS_SUMUP_LENGTH(p, i) (((guint32*)p)[(i)*3+2]) + +#define ADSIGRP_DEVICE_DATA 0xF100 + #define ADSIOFFS_DEVDATA_ADSSTATE 0x0000 + #define ADSIOFFS_DEVDATA_DEVSTATE 0x0002 + #define ADSIOFFS_DEVDATA_CONFIGID 0x0004 + #define ADSIOFFS_DEVDATA_ADSVERSIONCHECK 0x0005 + +#define ADSIGRP_TASK_DATA 0xF200 +/* ADSIGRP_TASK_DATA reserved until 0xF2FF*/ + +#define ADSIGRP_CANOPEN_BEGIN 0xF300 +#define ADSIGRP_CANOPEN_SDO 0xF302 +#define ADSIGRP_CANOPEN_SDO_INFO_LIST 0xF3FC +#define ADSIGRP_CANOPEN_SDO_INFO_OBJ 0xF3FD +#define ADSIGRP_CANOPEN_SDO_INFO_ENTRY 0xF3FE +#define ADSIGRP_CANOPEN_END 0xF3FF + +#define ADSIGRP_ECAT_FOE_BEGIN 0xF400 +#define ADSIGRP_ECAT_FOE_FOPENREAD 0xF401 +#define ADSIGRP_ECAT_FOE_FOPENWRITE 0xF402 +#define ADSIGRP_ECAT_FOE_FCLOSE 0xF403 +#define ADSIGRP_ECAT_FOE_FREAD 0xF404 +#define ADSIGRP_ECAT_FOE_FWRITE 0xF405 +#define ADSIGRP_ECAT_FOE_PROGRESSINFO 0xF406 +#define ADSIGRP_ECAT_FOE_END 0xF41F + +#define ADSIGRP_ECAT_SOE 0xF420 + #define ADSIOFFS_ECAT_SOE_ELEMENT_MASK 0x00FF0000 + #define ADSIOFFS_ECAT_SOE_DATASTATE 0x00010000 + #define ADSIOFFS_ECAT_SOE_NAME 0x00020000 + #define ADSIOFFS_ECAT_SOE_ATTRIBUTE 0x00040000 + #define ADSIOFFS_ECAT_SOE_UNIT 0x00080000 + #define ADSIOFFS_ECAT_SOE_MIN 0x00100000 + #define ADSIOFFS_ECAT_SOE_MAX 0x00200000 + #define ADSIOFFS_ECAT_SOE_VALUE 0x00400000 + #define ADSIOFFS_ECAT_SOE_DEFAULT 0x00800000 + #define ADSIOFFS_ECAT_SOE_DRIVENO_MASK 0x07000000 + #define ADSIOFFS_ECAT_SOE_COMMAND 0x08000000 + +#define ADSIGRP_ECAT_VOE 0xF430 + + +#define ADS_NOTIFICATIONBLOCKSIZE (sizeof(AdsNotificationBlock)-1) + +typedef enum nAdsState +{ + ADSSTATE_INVALID =0, + ADSSTATE_IDLE =1, + ADSSTATE_RESET =2, + ADSSTATE_INIT =3, + ADSSTATE_START =4, + ADSSTATE_RUN =5, + ADSSTATE_STOP =6, + ADSSTATE_SAVECFG =7, + ADSSTATE_LOADCFG =8, + ADSSTATE_POWERFAILURE =9, + ADSSTATE_POWERGOOD =10, + ADSSTATE_ERROR =11, + ADSSTATE_SHUTDOWN =12, + ADSSTATE_SUSPEND =13, + ADSSTATE_RESUME =14, + ADSSTATE_CONFIG =15, + ADSSTATE_RECONFIG =16, + ADSSTATE_MAXSTATES +} ADSSTATE; + +typedef enum nAdsTransMode +{ + ADSTRANS_NOTRANS =0, + ADSTRANS_CLIENTCYCLE =1, + ADSTRANS_CLIENTONCHA =2, + ADSTRANS_SERVERCYCLE =3, + ADSTRANS_SERVERONCHA =4, + ADSTRANS_CLIENT1REQ =10, + ADSTRANS_MAXMODES +}ADSTRANSMODE; + + +/* ADS error codes */ +#define ADSERR_NOERR 0x00 + +#define ADSERR_DEVICE_ERROR (0x700) +#define ADSERR_DEVICE_SRVNOTSUPP (0x701) +#define ADSERR_DEVICE_INVALIDGRP (0x702) +#define ADSERR_DEVICE_INVALIDOFFSET (0x703) +#define ADSERR_DEVICE_INVALIDACCESS (0x704) +#define ADSERR_DEVICE_INVALIDSIZE (0x705) +#define ADSERR_DEVICE_INVALIDDATA (0x706) +#define ADSERR_DEVICE_NOTREADY (0x707) +#define ADSERR_DEVICE_BUSY (0x708) +#define ADSERR_DEVICE_INVALIDCONTEXT (0x709) +#define ADSERR_DEVICE_NOMEMORY (0x70A) +#define ADSERR_DEVICE_INVALIDPARM (0x70B) +#define ADSERR_DEVICE_NOTFOUND (0x70C) +#define ADSERR_DEVICE_SYNTAX (0x70D) +#define ADSERR_DEVICE_INCOMPATIBLE (0x70E) +#define ADSERR_DEVICE_EXISTS (0x70F) +#define ADSERR_DEVICE_SYMBOLNOTFOUND (0x710) +#define ADSERR_DEVICE_SYMBOLVERSIONINVALID (0x711) +#define ADSERR_DEVICE_INVALIDSTATE (0x712) +#define ADSERR_DEVICE_TRANSMODENOTSUPP (0x713) +#define ADSERR_DEVICE_NOTIFYHNDINVALID (0x714) +#define ADSERR_DEVICE_CLIENTUNKNOWN (0x715) +#define ADSERR_DEVICE_NOMOREHDLS (0x716) +#define ADSERR_DEVICE_INVALIDWATCHSIZE (0x717) +#define ADSERR_DEVICE_NOTINIT (0x718) +#define ADSERR_DEVICE_TIMEOUT (0x719) +#define ADSERR_DEVICE_NOINTERFACE (0x71A) +#define ADSERR_DEVICE_INVALIDINTERFACE (0x71B) +#define ADSERR_DEVICE_INVALIDCLSID (0x71C) +#define ADSERR_DEVICE_INVALIDOBJID (0x71D) +#define ADSERR_DEVICE_PENDING (0x71E) +#define ADSERR_DEVICE_ABORTED (0x71F) +#define ADSERR_DEVICE_WARNING (0x720) +#define ADSERR_DEVICE_INVALIDARRAYIDX (0x721) +#define ADSERR_DEVICE_SYMBOLNOTACTIVE (0x722) +#define ADSERR_DEVICE_ACCESSDENIED (0x723) + +#define ADSERR_CLIENT_ERROR (0x740) +#define ADSERR_CLIENT_INVALIDPARM (0x741) +#define ADSERR_CLIENT_LISTEMPTY (0x742) +#define ADSERR_CLIENT_VARUSED (0x743) +#define ADSERR_CLIENT_DUPLINVOKEID (0x744) +#define ADSERR_CLIENT_SYNCTIMEOUT (0x745) +#define ADSERR_CLIENT_W32ERROR (0x746) +#define ADSERR_CLIENT_TIMEOUTINVALID (0x747) +#define ADSERR_CLIENT_PORTNOTOPEN (0x748) +#define ADSERR_CLIENT_NOAMSADDR (0x749) +#define ADSERR_CLIENT_SYNCINTERNAL (0x750) +#define ADSERR_CLIENT_ADDHASH (0x751) +#define ADSERR_CLIENT_REMOVEHASH (0x752) +#define ADSERR_CLIENT_NOMORESYM (0x753) +#define ADSERR_CLIENT_SYNCRESINVALID (0x754) +#define ADSERR_CLIENT_SYNCPORTLOCKED (0x755) + + +#define FACILITY_TC_ADS 0x1811 +#define FACILITY_TC_CNC 0x1821 +#define FACILITY_TC_IO 0x1831 + + +#define ADS_E_ERROR (0x98110000L + ADSERR_DEVICE_ERROR) +#define ADS_E_SRVNOTSUPP (0x98110000L + ADSERR_DEVICE_SRVNOTSUPP) +#define ADS_E_INVALIDGRP (0x98110000L + ADSERR_DEVICE_INVALIDGRP) +#define ADS_E_INVALIDOFFSET (0x98110000L + ADSERR_DEVICE_INVALIDOFFSET) +#define ADS_E_INVALIDACCESS (0x98110000L + ADSERR_DEVICE_INVALIDACCESS) +#define ADS_E_INVALIDSIZE (0x98110000L + ADSERR_DEVICE_INVALIDSIZE) +#define ADS_E_INVALIDDATA (0x98110000L + ADSERR_DEVICE_INVALIDDATA) +#define ADS_E_NOTREADY (0x98110000L + ADSERR_DEVICE_NOTREADY) +#define ADS_E_BUSY (0x98110000L + ADSERR_DEVICE_BUSY) +#define ADS_E_INVALIDCONTEXT (0x98110000L + ADSERR_DEVICE_INVALIDCONTEXT) +#define ADS_E_NOMEMORY (0x98110000L + ADSERR_DEVICE_NOMEMORY) +#define ADS_E_INVALIDPARM (0x98110000L + ADSERR_DEVICE_INVALIDPARM) +#define ADS_E_NOTFOUND (0x98110000L + ADSERR_DEVICE_NOTFOUND) +#define ADS_E_SYNTAX (0x98110000L + ADSERR_DEVICE_SYNTAX) +#define ADS_E_INCOMPATIBLE (0x98110000L + ADSERR_DEVICE_INCOMPATIBLE) +#define ADS_E_EXISTS (0x98110000L + ADSERR_DEVICE_EXISTS) +#define ADS_E_SYMBOLNOTFOUND (0x98110000L + ADSERR_DEVICE_SYMBOLNOTFOUND) +#define ADS_E_SYMBOLVERSIONINVALID (0x98110000L + ADSERR_DEVICE_SYMBOLVERSIONINVALID) +#define ADS_E_INVALIDSTATE (0x98110000L + ADSERR_DEVICE_INVALIDSTATE) +#define ADS_E_TRANSMODENOTSUPP (0x98110000L + ADSERR_DEVICE_TRANSMODENOTSUPP) +#define ADS_E_NOTIFYHNDINVALID (0x98110000L + ADSERR_DEVICE_NOTIFYHNDINVALID) +#define ADS_E_CLIENTUNKNOWN (0x98110000L + ADSERR_DEVICE_CLIENTUNKNOWN) +#define ADS_E_NOMOREHDLS (0x98110000L + ADSERR_DEVICE_NOMOREHDLS) +#define ADS_E_INVALIDWATCHSIZE (0x98110000L + ADSERR_DEVICE_INVALIDWATCHSIZE) +#define ADS_E_NOTINIT (0x98110000L + ADSERR_DEVICE_NOTINIT) +#define ADS_E_TIMEOUT (0x98110000L + ADSERR_DEVICE_TIMEOUT) +#define ADS_E_NOINTERFACE (0x98110000L + ADSERR_DEVICE_NOINTERFACE) +#define ADS_E_INVALIDINTERFACE (0x98110000L + ADSERR_DEVICE_INVALIDINTERFACE) +#define ADS_E_INVALIDCLSID (0x98110000L + ADSERR_DEVICE_INVALIDCLSID) +#define ADS_E_INVALIDOBJID (0x98110000L + ADSERR_DEVICE_INVALIDOBJID) +#define ADS_E_PENDING (0x98110000L + ADSERR_DEVICE_PENDING) +#define ADS_E_ABORTED (0x98110000L + ADSERR_DEVICE_ABORTED) +#define ADS_E_WARNING (0x98110000L + ADSERR_DEVICE_WARNING) +#define ADS_E_INVALIDARRAYIDX (0x98110000L + ADSERR_DEVICE_INVALIDARRAYIDX) +#define ADS_E_SYMBOLNOTACTIVE (0x98110000L + ADSERR_DEVICE_SYMBOLNOTACTIVE) +#define ADS_E_ACCESSDENIED (0x98110000L + ADSERR_DEVICE_ACCESSDENIED) + + +#ifndef ANYSIZE_ARRAY + #define ANYSIZE_ARRAY 1 +#endif + +#ifndef UNALIGNED + #define UNALIGNED +#endif + +/* ADS AMS command */ +/* Ensure the same data layout for all platforms */ +#pragma pack(push, 1) + +typedef struct +{ + AmsHead head; + guint16 firstDataWord; +} AdsAmsCmd, *PAdsAmsCmd; + +typedef struct +{ + guint8 version; + guint8 revision; + guint16 build; +} AdsVersion, *PAdsVersion; + +typedef struct +{ + guint32 hNotification; + guint32 cbSampleSize; + guint8 data[ANYSIZE_ARRAY]; +} AdsNotificationSample, *PAdsNotificationSample; + +typedef struct +{ + gint64 nTimeStamp; + guint32 nSamples; + AdsNotificationSample tSample[ANYSIZE_ARRAY]; +} AdsStampHeader, *PAdsStampHeader; + + +typedef struct +{ + guint32 nStamps; + AdsStampHeader tStamp[ANYSIZE_ARRAY]; +} AdsNotificationStream, *PAdsNotificationStream; + + +typedef struct +{ + guint32 hNotification; + gint64 nTimeStamp; + guint32 cbSampleSize; + guint8 data[ANYSIZE_ARRAY]; +} AdsNotificationHeader, *PAdsNotificationHeader; + +typedef struct +{ + guint32 cbLength; + ADSTRANSMODE nTransMode; + guint32 nMaxDelay; + guint32 nCycleTime; + guint8 nCmpMax[sizeof(double)]; + guint8 nCmpMin[sizeof(double)]; +} AdsNotificationAttrib, *PAdsNotificationAttrib; + +typedef struct +{ + guint32 invokeId; +} TAdsReadDeviceInfoReq, *PTAdsReadDeviceInfoReq, TAdsReadDeviceInfoInd, *PTAdsReadDeviceInfoInd; + +typedef struct +{ + guint16 adsState; + guint16 deviceState; + guint32 cbLength; + guint16 firstDataWord; +} TAdsWriteControlReq, *PTAdsWriteControlReq, TAdsWriteControlInd, *PTAdsWriteControlInd; + +typedef struct +{ + guint32 invokeId; +} TAdsReadStateReq, *PTAdsReadStateReq, TAdsReadStateInd, *PTAdsReadStateInd; + +typedef struct +{ + guint32 indexGroup; + guint32 indexOffset; + guint32 cbLength; +} TAdsReadReq, *PTAdsReadReq, TAdsReadInd, *PTAdsReadInd; + +typedef struct +{ + guint32 indexGroup; + guint32 indexOffset; + guint32 cbLength; + guint16 firstDataWord; +} TAdsWriteReq, *PTAdsWriteReq, TAdsWriteInd, *PTAdsWriteInd; + +typedef struct +{ + guint32 indexGroup; + guint32 indexOffset; + guint32 cbReadLength; + guint32 cbWriteLength; + guint16 firstDataWord; +} TAdsReadWriteReq, *PTAdsReadWriteReq, TAdsReadWriteInd, *PTAdsReadWriteInd; + +typedef struct +{ + guint32 indexGroup; + guint32 indexOffset; + AdsNotificationAttrib noteAttrib; +} TAdsAddDeviceNotificationReq, *PTAdsAddDeviceNotificationReq, + TAdsAddDeviceNotificationInd, *PTAdsAddDeviceNotificationInd; + +typedef struct +{ + guint32 hNotification; +} TAdsDelDeviceNotificationReq, *PTAdsDelDeviceNotificationReq, + TAdsDelDeviceNotificationInd, *PTAdsDelDeviceNotificationInd; + +typedef struct +{ + guint32 cbLength; + AdsNotificationStream noteBlocks; +} TAdsDeviceNotificationReq, *PTAdsDeviceNotificationReq, + TAdsDeviceNotificationInd, *PTAdsDeviceNotificationInd; + + +typedef struct +{ + guint32 result; +} TAdsCon, *PTAdsCon, TAdsRes, *PTAdsRes; + +typedef struct +{ + guint32 result; + AdsVersion version; + char sName[ADS_FIXEDNAMESIZE]; +} TAdsReadDeviceInfoRes, *PTAdsReadDeviceInfoRes, TAdsReadDeviceInfoCon, *PTAdsReadDeviceInfoCon; + +typedef struct +{ + guint32 result; +} TAdsWriteControlRes, *PTAdsWriteControlRes, TAdsWriteControlCon, *PTAdsWriteControlCon; + +typedef struct +{ + guint32 result; + guint16 adsState; + guint16 deviceState; +} TAdsReadStateRes, *PTAdsReadStateRes, TAdsReadStateCon, *PTAdsReadStateCon; + +typedef struct +{ + guint32 result; + guint32 cbLength; + guint16 firstDataWord; +} TAdsReadRes, *PTAdsReadRes, TAdsReadCon, *PTAdsReadCon; + +typedef struct +{ + guint32 result; + guint32 cbLength; + guint16 firstDataWord; +} TAdsReadWriteRes, *PTAdsReadWriteRes, TAdsReadWriteCon, *PTAdsReadWriteCon; + +typedef struct +{ + guint32 result; +} TAdsWriteRes, *PTAdsWriteRes, TAdsWriteCon, *PTAdsWriteCon; + +typedef struct +{ + guint32 result; + guint32 handle; +} TAdsAddDeviceNotificationRes, *PTAdsAddDeviceNotificationRes, + TAdsAddDeviceNotificationCon, *PTAdsAddDeviceNotificationCon; + +typedef struct +{ + guint32 result; +} TAdsDelDeviceNotificationRes, *PTAdsDelDeviceNotificationRes, + TAdsDelDeviceNotificationCon, *PTAdsDelDeviceNotificationCon; + + +/* structure for decoding the header -----------------------------------------*/ +typedef struct +{ + guint16 reserved; + guint16 cbLength[2]; +} TcpAdsParserHDR; +typedef TcpAdsParserHDR UNALIGNED *PTcpAdsParserHDR; + +typedef union tAdsUnion +{ + TAdsReadReq readReq; + TAdsReadRes readRes; + TAdsWriteReq writeReq; + TAdsWriteRes writeRes; + TAdsReadWriteReq rwReq; + TAdsReadWriteRes rwRes; + TAdsReadDeviceInfoReq infoReq; + TAdsReadDeviceInfoRes infoRes; + TAdsWriteControlReq writeCtrlReq; + TAdsWriteControlRes writeCtrlRes; + TAdsReadStateReq readStateReq; + TAdsReadStateRes readStateRes; + TAdsAddDeviceNotificationReq addDnReq; + TAdsAddDeviceNotificationRes addDnRes; + TAdsDelDeviceNotificationReq delDnReq; + TAdsDelDeviceNotificationRes delDnRes; + TAdsDeviceNotificationReq dnReq; + TAdsReadDeviceInfoReq readDInfoReq; + TAdsReadDeviceInfoRes readDInfoRes; +} AdsUnion; + +typedef struct _AdsParser +{ + AmsHead ams; + + AdsUnion anAdsUnion; +} AdsParserHDR; +typedef AdsParserHDR UNALIGNED *PAdsParserHDR; + +#pragma pack(pop) + +#endif diff --git a/plugins/ethercat/packet-ecatmb.c b/plugins/ethercat/packet-ecatmb.c new file mode 100644 index 0000000000..0fcff32224 --- /dev/null +++ b/plugins/ethercat/packet-ecatmb.c @@ -0,0 +1,2084 @@ +/* packet-ecatmb.c + * Routines for ethercat packet disassembly + * + * $Id$ + * + * Copyright (c) 2007 by Beckhoff Automation GmbH + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * 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. + */ + +/* Include files */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include "packet-ecatmb.h" + +void proto_reg_handoff_ecat_mailbox(void); + + +#define BIT2BYTE(x) ((x+7)/8) +#define ENDOF(p) ((p)+1) /* pointer to end of *p */ + +static dissector_handle_t eth_handle; +static dissector_handle_t ams_handle; + +/* Define the EtherCAT mailbox proto */ +int proto_ecat_mailbox = -1; + +static int ett_ecat_mailbox = -1; +static int ett_ecat_mailbox_eoe = -1; +static int ett_ecat_mailbox_eoe_init = -1; +static int ett_ecat_mailbox_eoe_macfilter = -1; +static int ett_ecat_mailbox_eoe_macfilter_filter = -1; +static int ett_ecat_mailbox_eoe_macfilter_filtermask = -1; +static int ett_ecat_mailbox_coe = -1; +static int ett_ecat_mailbox_sdo = -1; +static int ett_ecat_mailbox_coe_sdoccs = -1; +static int ett_ecat_mailbox_coe_sdoscs = -1; +static int ett_ecat_mailbox_foe = -1; +static int ett_ecat_mailbox_foe_efw = -1; +static int ett_ecat_mailbox_soeopmode = -1; +static int ett_ecat_mailbox_soeflag = -1; +static int ett_ecat_mailbox_soe = -1; +static int ett_ecat_mailbox_fraghead = -1; + +static int hf_ecat_mailbox = -1; +static int hf_ecat_mailboxlength = -1; +static int hf_ecat_mailboxaddress = -1; +static int hf_ecat_mailboxtype = -1; +static int hf_ecat_mailboxcounter = -1; +static int hf_ecat_mailbox_eoe = -1; +static int hf_ecat_mailbox_eoe_fraghead = -1; +static int hf_ecat_mailbox_eoe_type = -1; +static int hf_ecat_mailbox_eoe_fragno = -1; +static int hf_ecat_mailbox_eoe_offset = -1; +static int hf_ecat_mailbox_eoe_frame = -1; +static int hf_ecat_mailbox_eoe_last = -1; +static int hf_ecat_mailbox_eoe_timestampreq = -1; +static int hf_ecat_mailbox_eoe_timestampapp = -1; +static int hf_ecat_mailbox_eoe_fragment = -1; +static int hf_ecat_mailbox_eoe_init = -1; +static int hf_ecat_mailbox_eoe_init_contains_macaddr = -1; +static int hf_ecat_mailbox_eoe_init_contains_ipaddr = -1; +static int hf_ecat_mailbox_eoe_init_contains_subnetmask = -1; +static int hf_ecat_mailbox_eoe_init_contains_defaultgateway = -1; +static int hf_ecat_mailbox_eoe_init_contains_dnsserver = -1; +static int hf_ecat_mailbox_eoe_init_contains_dnsname = -1; +static int hf_ecat_mailbox_eoe_init_append_timestamp = -1; +static int hf_ecat_mailbox_eoe_init_macaddr = -1; +static int hf_ecat_mailbox_eoe_init_ipaddr = -1; +static int hf_ecat_mailbox_eoe_init_subnetmask = -1; +static int hf_ecat_mailbox_eoe_init_defaultgateway = -1; +static int hf_ecat_mailbox_eoe_init_dnsserver = -1; +static int hf_ecat_mailbox_eoe_init_dnsname = -1; +static int hf_ecat_mailbox_eoe_macfilter = -1; +static int hf_ecat_mailbox_eoe_macfilter_macfiltercount = -1; +static int hf_ecat_mailbox_eoe_macfilter_maskcount = -1; +static int hf_ecat_mailbox_eoe_macfilter_nobroadcasts = -1; +static int hf_ecat_mailbox_eoe_macfilter_filter; +static int hf_ecat_mailbox_eoe_macfilter_filters[16] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}; +static int hf_ecat_mailbox_eoe_macfilter_filtermask = -1; +static int hf_ecat_mailbox_eoe_macfilter_filtermasks[4] = {-1,-1,-1,-1}; +static int hf_ecat_mailbox_eoe_timestamp = -1; +static int hf_ecat_mailbox_coe = -1; +static int hf_ecat_mailbox_coe_number = -1; +static int hf_ecat_mailbox_coe_type = -1; +static int hf_ecat_mailbox_coe_sdoreq = -1; +static int hf_ecat_mailbox_coe_sdoccsid = -1; +static int hf_ecat_mailbox_coe_sdoccsid_sizeind = -1; +static int hf_ecat_mailbox_coe_sdoccsid_expedited = -1; +static int hf_ecat_mailbox_coe_sdoccsid_size0= -1; +static int hf_ecat_mailbox_coe_sdoccsid_size1= -1; +static int hf_ecat_mailbox_coe_sdoccsid_complete = -1; +static int hf_ecat_mailbox_coe_sdoccsds = -1; +static int hf_ecat_mailbox_coe_sdoccsds_lastseg = -1; +static int hf_ecat_mailbox_coe_sdoccsds_size = -1; +static int hf_ecat_mailbox_coe_sdoccsds_toggle = -1; +static int hf_ecat_mailbox_coe_sdoccsus = -1; +static int hf_ecat_mailbox_coe_sdoccsus_toggle = -1; +static int hf_ecat_mailbox_coe_sdoccsiu = -1; +static int hf_ecat_mailbox_coe_sdoccsiu_complete = -1; +static int hf_ecat_mailbox_coe_sdoidx = -1; +static int hf_ecat_mailbox_coe_sdosub = -1; +static int hf_ecat_mailbox_coe_sdodata = -1; +static int hf_ecat_mailbox_coe_sdodata1 = -1; +static int hf_ecat_mailbox_coe_sdodata2 = -1; +static int hf_ecat_mailbox_coe_sdoldata = -1; +static int hf_ecat_mailbox_coe_sdolength = -1; +static int hf_ecat_mailbox_coe_sdoerror = -1; +static int hf_ecat_mailbox_coe_sdores = -1; +static int hf_ecat_mailbox_coe_sdoscsds = -1; +static int hf_ecat_mailbox_coe_sdoscsds_toggle = -1; +static int hf_ecat_mailbox_coe_sdoscsiu = -1; +static int hf_ecat_mailbox_coe_sdoscsiu_sizeind = -1; +static int hf_ecat_mailbox_coe_sdoscsiu_expedited = -1; +static int hf_ecat_mailbox_coe_sdoscsiu_size0 = -1; +static int hf_ecat_mailbox_coe_sdoscsiu_size1 = -1; +static int hf_ecat_mailbox_coe_sdoscsiu_complete = -1; +static int hf_ecat_mailbox_coe_sdoscsus = -1; +static int hf_ecat_mailbox_coe_sdoscsus_lastseg = -1; +static int hf_ecat_mailbox_coe_sdoscsus_bytes = -1; +static int hf_ecat_mailbox_coe_sdoscsus_toggle = -1; +static int hf_ecat_mailbox_coe_sdoinfoopcode = -1; +static int hf_ecat_mailbox_coe_sdoinfofrag = -1; +static int hf_ecat_mailbox_coe_sdoinfolisttype = -1; +static int hf_ecat_mailbox_coe_sdoinfolist = -1; +static int hf_ecat_mailbox_coe_sdoinfoindex = -1; +static int hf_ecat_mailbox_coe_sdoinfosubindex = -1; +static int hf_ecat_mailbox_coe_sdoinfovalueinfo = -1; +static int hf_ecat_mailbox_coe_sdoinfoerrorcode = -1; +static int hf_ecat_mailbox_coe_sdoinfodatatype = -1; +static int hf_ecat_mailbox_coe_sdoinfomaxsub = -1; +static int hf_ecat_mailbox_coe_sdoinfoobjcode = -1; +static int hf_ecat_mailbox_coe_sdoinfoname = -1; +static int hf_ecat_mailbox_coe_sdoinfobitlen = -1; +static int hf_ecat_mailbox_coe_sdoinfoobjaccess = -1; +static int hf_ecat_mailbox_coe_sdoinfounittype = -1; +static int hf_ecat_mailbox_coe_sdoinfodefaultvalue = -1; +static int hf_ecat_mailbox_coe_sdoinfominvalue = -1; +static int hf_ecat_mailbox_coe_sdoinfomaxvalue = -1; +static int hf_ecat_mailboxdata = -1; +static int hf_ecat_mailbox_foe = -1; +static int hf_ecat_mailbox_foe_opmode = -1; +static int hf_ecat_mailbox_foe_filelength = -1; +static int hf_ecat_mailbox_foe_filename = -1; +static int hf_ecat_mailbox_foe_packetno = -1; +static int hf_ecat_mailbox_foe_errcode = -1; +static int hf_ecat_mailbox_foe_errtext = -1; +static int hf_ecat_mailbox_foe_busydone = -1; +static int hf_ecat_mailbox_foe_busyentire = -1; +static int hf_ecat_mailbox_foe_data = -1; +static int hf_ecat_mailbox_foe_efw = -1; +static int hf_ecat_mailbox_foe_efw_cmd = -1; +static int hf_ecat_mailbox_foe_efw_size = -1; +static int hf_ecat_mailbox_foe_efw_addresslw = -1; +static int hf_ecat_mailbox_foe_efw_addresshw = -1; +static int hf_ecat_mailbox_foe_efw_data = -1; +static int hf_ecat_mailbox_soe = -1; +static int hf_ecat_mailbox_soe_header = -1; + +static int hf_ecat_mailbox_soe_header_opcode = -1; +static int hf_ecat_mailbox_soe_header_incomplete = -1; +static int hf_ecat_mailbox_soe_header_error = -1; +static int hf_ecat_mailbox_soe_header_driveno = -1; +static int hf_ecat_mailbox_soe_header_datastate = -1; +static int hf_ecat_mailbox_soe_header_name = -1; +static int hf_ecat_mailbox_soe_header_attribute = -1; +static int hf_ecat_mailbox_soe_header_unit = -1; +static int hf_ecat_mailbox_soe_header_min = -1; +static int hf_ecat_mailbox_soe_header_max = -1; +static int hf_ecat_mailbox_soe_header_value = -1; +static int hf_ecat_mailbox_soe_header_reserved = -1; +static int hf_ecat_mailbox_soe_idn = -1; +static int hf_ecat_mailbox_soe_data = -1; +static int hf_ecat_mailbox_soe_frag = -1; +static int hf_ecat_mailbox_soe_error = -1; + +static const value_string EcMBoxType[] = +{ + { 0, "Invalid", }, + { 1, "AoE", }, + { 2, "EoE", }, + { 3, "CoE", }, + { 4, "FoE", }, + { 5, "SoE", }, + { 0x80+1, "AoE - Err", }, + { 0x80+2, "EoE - Err", }, + { 0x80+3, "CoE - Err", }, + { 0x80+4, "FoE - Err", }, + { 0x80+5, "SoE - Err", }, + { 0, NULL } +}; + +static const value_string FoEOpMode[] = +{ + { 1, "RRQ", }, + { 2, "WRQ", }, + { 3, "DATA", }, + { 4, "ACK", }, + { 5, "ERROR", }, + { 6, "BUSY", }, + { 0, NULL } +}; + +static const value_string FoEEfwCmd[] = +{ + { 1, "Memory Transfer", }, + { 2, "Write Code", }, + { 3, "Check device id", }, + { 4, "Checksum", }, + { 5, "Write code checksum", }, + { 6, "Set device id", }, + { 8, "Set code id", }, + { 9, "NOP", }, + { 10, "Checksum checksum", }, + { 11, "boot checksum", }, + { 0, NULL } +}; + +static const value_string SoeOpcode[] = +{ + { 0, "unused" }, + { 1, "readReq" }, + { 2, "readRes"}, + { 3, "writeReq"}, + { 4, "writeRes" }, + { 5, "notification" }, + { 6, "emergency"}, + { 0, NULL } +}; + +static const true_false_string tfs_complete = +{ + "Complete", "Legacy" +}; + +void init_mbx_header(PETHERCAT_MBOX_HEADER pMbox, tvbuff_t *tvb, gint offset) +{ + pMbox->Length = tvb_get_letohs(tvb, offset); offset+=sizeof(guint16); + pMbox->Address = tvb_get_letohs(tvb, offset); offset+=sizeof(guint16); + pMbox->aControlUnion.Control = tvb_get_letohs(tvb, offset); +} + +void init_eoe_header(PETHERCAT_EOE_HEADER pEoE, tvbuff_t *tvb, gint offset) +{ + pEoE->anEoeHeaderInfoUnion.Info = tvb_get_letohs(tvb, offset); offset+=sizeof(guint16); + pEoE->anEoeHeaderDataUnion.Result = tvb_get_letohs(tvb, offset); +} + +void init_foe_header(PETHERCAT_FOE_HEADER pFoE, tvbuff_t *tvb, gint offset) +{ + pFoE->OpMode = tvb_get_guint8(tvb, offset++); + pFoE->Reserved1 = tvb_get_guint8(tvb, offset++); + pFoE->aFoeHeaderDataUnion.FileLength = tvb_get_letohl(tvb, offset); +} + +void init_soe_header(PETHERCAT_SOE_HEADER pSoE, tvbuff_t *tvb, gint offset) +{ + pSoE->anSoeHeaderControlUnion.Control = tvb_get_guint8(tvb, offset++); + pSoE->anSoeHeaderControlUnion.Element = tvb_get_guint8(tvb, offset++); + pSoE->anSoeHeaderDataUnion.FragmentsLeft = tvb_get_letohs(tvb, offset); +} + +void init_coe_header(PETHERCAT_COE_HEADER pCoE, tvbuff_t *tvb, gint offset) +{ + pCoE->header = tvb_get_letohs(tvb, offset); +} + +void init_sdo_header(PETHERCAT_SDO_HEADER pSdo, tvbuff_t *tvb, gint offset) +{ + pSdo->anSdoHeaderUnion.CS = tvb_get_guint8(tvb, offset++); + pSdo->Index = tvb_get_letohs(tvb, offset);offset+=sizeof(guint16); + pSdo->SubIndex = tvb_get_guint8(tvb, offset++); + pSdo->Data = tvb_get_letohl(tvb, offset); +} + +void init_sdo_info_header(PETHERCAT_SDO_INFO_HEADER pInfo, tvbuff_t *tvb, gint offset) +{ + pInfo->anSdoControlUnion.Control = tvb_get_guint8(tvb, offset++); + pInfo->Reserved = tvb_get_guint8(tvb, offset++); + pInfo->FragmentsLeft = sizeof(guint16); +} + + +static void MailboxTypeFormater(PETHERCAT_MBOX_HEADER pMbx, char *szText, gint nMax) +{ + guint32 i; + + for(i = 0; iaControlUnion.Type ) + { + g_snprintf(szText, nMax, "Type : %s (0x%x)", EcMBoxType[i].strptr, pMbx->aControlUnion.Type); + return; + } + } + g_snprintf ( szText, nMax,"Type : %d", pMbx->aControlUnion.Type); +} + +static void EoETypeFormater(PETHERCAT_EOE_HEADER pEoE, char *szText, gint nMax) +{ + switch (pEoE->anEoeHeaderInfoUnion.Type) + { + case EOE_TYPE_FRAME_FRAG: + g_snprintf ( szText, nMax, "Type(%d) : Fragment", pEoE->anEoeHeaderInfoUnion.Type); + break; + case EOE_TYPE_TIMESTAMP_RES: + g_snprintf ( szText, nMax, "Type(%d) : TimeStamp", pEoE->anEoeHeaderInfoUnion.Type); + break; + case EOE_TYPE_INIT_REQ: + g_snprintf ( szText, nMax, "Type(%d) : Init Req", pEoE->anEoeHeaderInfoUnion.Type); + break; + case EOE_TYPE_INIT_RES: + g_snprintf ( szText, nMax, "Type(%d) : Init Res", pEoE->anEoeHeaderInfoUnion.Type); + break; + case EOE_TYPE_MACFILTER_REQ: + g_snprintf ( szText, nMax, "Type(%d) : MAC Req", pEoE->anEoeHeaderInfoUnion.Type); + break; + case EOE_TYPE_MACFILTER_RES: + g_snprintf ( szText, nMax, "Type(%d) : MAC Res", pEoE->anEoeHeaderInfoUnion.Type); + break; + default: + g_snprintf ( szText, nMax, "Type(%d) : Unknown", pEoE->anEoeHeaderInfoUnion.Type); + break; + } +} + +static void EoEFragNoFormater(PETHERCAT_EOE_HEADER pEoE, char *szText, gint nMax) +{ + g_snprintf ( szText, nMax, "FragNo : %d", pEoE->anEoeHeaderDataUnion.Fragment); +} + +static void EoEOffsetFormater(PETHERCAT_EOE_HEADER pEoE, char *szText, gint nMax) +{ + if ( pEoE->anEoeHeaderDataUnion.Fragment == 0 ) + g_snprintf ( szText, nMax, "BufferSize : %d", 32*pEoE->anEoeHeaderDataUnion.OffsetBuffer); + else + g_snprintf ( szText, nMax, "Offset : %d", 32*pEoE->anEoeHeaderDataUnion.OffsetBuffer); +} + +static void EoEFrameFormater(PETHERCAT_EOE_HEADER pEoE, char *szText, gint nMax) +{ + g_snprintf ( szText, nMax, "FrameNo : %d", pEoE->anEoeHeaderDataUnion.FrameNo); +} + +static void EoELastFormater(PETHERCAT_EOE_HEADER pEoE, char *szText, gint nMax) +{ + if ( pEoE->anEoeHeaderInfoUnion.LastFragment != 0 ) + g_snprintf ( szText, nMax, "Last Frag"); + else + g_snprintf ( szText, nMax, "More Frags..."); +} + +static void CANopenNumberFormater(PETHERCAT_COE_HEADER pCoE, char *szText, gint nMax) +{ + g_snprintf( szText, nMax, "Number : %d", pCoE->Number); +} + +static void CANopenTypeFormater(PETHERCAT_COE_HEADER pCoE, char *szText, gint nMax) +{ + switch ( pCoE->Type) + { + case ETHERCAT_COE_TYPE_EMERGENCY: + g_snprintf ( szText, nMax, "Type : EMERGENCY(%d)", pCoE->Type); + break; + case ETHERCAT_COE_TYPE_SDOREQ: + g_snprintf ( szText, nMax, "Type : SDO Req(%d)", pCoE->Type); + break; + case ETHERCAT_COE_TYPE_SDORES: + g_snprintf ( szText, nMax, "Type : SDO Res(%d)", pCoE->Type); + break; + case ETHERCAT_COE_TYPE_TXPDO: + g_snprintf ( szText, nMax, "Type : TxPDO(%d)", pCoE->Type); + break; + case ETHERCAT_COE_TYPE_RXPDO: + g_snprintf ( szText, nMax, "Type : RxPDO(%d)", pCoE->Type); + break; + case ETHERCAT_COE_TYPE_TXPDO_RTR: + g_snprintf ( szText, nMax, "Type : TxPDO_RTR(%d)", pCoE->Type); + break; + case ETHERCAT_COE_TYPE_RXPDO_RTR: + g_snprintf ( szText, nMax, "Type : RxPDO_RTR(%d)", pCoE->Type); + break; + default: + g_snprintf ( szText, nMax, "Type :%d", pCoE->Type); + } +} + +static void CANopenSdoReqFormater(PETHERCAT_SDO_HEADER pSdo, char *szText, gint nMax) +{ + switch ( pSdo->anSdoHeaderUnion.Idq.Ccs ) + { + case SDO_CCS_INITIATE_DOWNLOAD: + g_snprintf ( szText, nMax, "SDO Req : 'Initiate Download' (%d) Idx=0x%x Sub=%d", pSdo->anSdoHeaderUnion.Idq.Ccs, pSdo->Index, pSdo->SubIndex); + break; + case SDO_CCS_INITIATE_UPLOAD: + g_snprintf ( szText, nMax, "SDO Req : 'Initiate Upload' (%d) Idx=0x%x Sub=%d", pSdo->anSdoHeaderUnion.Idq.Ccs, pSdo->Index, pSdo->SubIndex); + break; + case SDO_CCS_DOWNLOAD_SEGMENT: + g_snprintf ( szText, nMax, "SDO Req : 'Download Segment' (%d)", pSdo->anSdoHeaderUnion.Idq.Ccs); + break; + case SDO_CCS_UPLOAD_SEGMENT: + g_snprintf ( szText, nMax, "SDO Req : 'Upload Segment' (%d)", pSdo->anSdoHeaderUnion.Idq.Ccs); + break; + case SDO_CCS_ABORT_TRANSFER: + g_snprintf ( szText, nMax, "SDO Req : 'Abort Transfer' (%d)", pSdo->anSdoHeaderUnion.Idq.Ccs); + break; + default: + g_snprintf ( szText, nMax, "SDO Req : Ccs %d", pSdo->anSdoHeaderUnion.Idq.Ccs); + } +} + +static void CANopenSdoResFormater(PETHERCAT_SDO_HEADER pSdo, char *szText, gint nMax) +{ + g_snprintf ( szText, nMax, "SDO Res : Scs %d", pSdo->anSdoHeaderUnion.Ids.Scs); +} + +static void CANopenSdoInfoFormater(PETHERCAT_SDO_INFO_HEADER pHead, char *szText, gint nMax) +{ + guint8 opCode = pHead->anSdoControlUnion.OpCode&0x7F; + char* txt2 = ""; + if ( (pHead->anSdoControlUnion.OpCode&0x80) != 0 ) + txt2 = " - More Follows"; + switch (opCode) + { + case ECAT_COE_INFO_OPCODE_LIST_Q: + g_snprintf ( szText, nMax, "CoE SDO Info, OpCode: 'List Req' %s", txt2); + break; + case ECAT_COE_INFO_OPCODE_LIST_S: + g_snprintf ( szText, nMax, "CoE SDO Info, OpCode: 'List Res' %s", txt2); + break; + case ECAT_COE_INFO_OPCODE_OBJ_Q: + g_snprintf ( szText, nMax, "CoE SDO Info, OpCode: 'Obj Req' %s", txt2); + break; + case ECAT_COE_INFO_OPCODE_OBJ_S: + g_snprintf ( szText, nMax, "CoE SDO Info, OpCode: 'Obj Res' %s", txt2); + break; + case ECAT_COE_INFO_OPCODE_ENTRY_Q: + g_snprintf ( szText, nMax, "CoE SDO Info, OpCode: 'Entry Req' %s", txt2); + break; + case ECAT_COE_INFO_OPCODE_ENTRY_S: + g_snprintf ( szText, nMax, "CoE SDO Info, OpCode: 'Entry Res' %s", txt2); + break; + case ECAT_COE_INFO_OPCODE_ERROR_S: + g_snprintf ( szText, nMax, "CoE SDO Info, OpCode: 'Error Res' %s", txt2); + break; + default: + g_snprintf ( szText, nMax, "CoE SDO Info, OpCode: %d %s", opCode, txt2); + } +} + +static void FoeFormater(tvbuff_t *tvb, gint offset, char *szText, gint nMax, guint foe_length) +{ + ETHERCAT_FOE_HEADER foe; + char tmp[50]; + memset(tmp, 0, sizeof(tmp)); + + init_foe_header(&foe, tvb, offset); + + switch ( foe.OpMode ) + { + case ECAT_FOE_OPMODE_RRQ: + case ECAT_FOE_OPMODE_WRQ: + case ECAT_FOE_OPMODE_ERR: + if ( foe_length > ETHERCAT_FOE_HEADER_LEN ) + tvb_memcpy(tvb, tmp, offset+ETHERCAT_FOE_HEADER_LEN, MIN(foe_length-ETHERCAT_FOE_HEADER_LEN, sizeof(tmp)-1)); + break; + } + + switch ( foe.OpMode ) + { + case ECAT_FOE_OPMODE_RRQ: + g_snprintf ( szText, nMax, "FoE RRQ (%d) : '%s'", foe.aFoeHeaderDataUnion.FileLength, tmp); + break; + case ECAT_FOE_OPMODE_WRQ: + g_snprintf ( szText, nMax, "FoE WRQ (%d) : '%s'", foe.aFoeHeaderDataUnion.FileLength, tmp); + break; + case ECAT_FOE_OPMODE_DATA: + g_snprintf ( szText, nMax, "FoE DATA (%d) : %d Bytes", foe.aFoeHeaderDataUnion.PacketNo, foe_length-ETHERCAT_FOE_HEADER_LEN); + break; + case ECAT_FOE_OPMODE_ACK: + g_snprintf ( szText, nMax, "FoE ACK (%d)", foe.aFoeHeaderDataUnion.PacketNo); + break; + case ECAT_FOE_OPMODE_ERR: + g_snprintf ( szText, nMax, "FoE ERR (%d) : '%s'", foe.aFoeHeaderDataUnion.ErrorCode, tmp); + break; + case ECAT_FOE_OPMODE_BUSY: + if ( foe.aFoeHeaderDataUnion.Entire > 0 ) + g_snprintf ( szText, nMax, "FoE BUSY (%d%%)", ((guint32)foe.aFoeHeaderDataUnion.Done*100)/foe.aFoeHeaderDataUnion.Entire); + else + g_snprintf ( szText, nMax, "FoE BUSY (%d/%d)", foe.aFoeHeaderDataUnion.Done, foe.aFoeHeaderDataUnion.Entire); + break; + } +} + +static void SoEIdToString( char* txt, guint16 id, int nMax) +{ + if ( id & 0x8000 ) + g_snprintf(txt, nMax, "P-%d-%04d", (id>>12) & 0x0007, id & 0x0FFF ); + else + g_snprintf(txt, nMax, "S-%d-%04d", id>>12, id & 0x0FFF ); +} + +static void SoeFormater(tvbuff_t *tvb, gint offset, char *szText, gint nMax, guint soe_length) +{ + ETHERCAT_SOE_HEADER soe; + char tmp[50]; + char elm[50]; + memset(tmp, 0, sizeof(tmp)); + + init_soe_header(&soe, tvb, offset); + offset+=ETHERCAT_SOE_HEADER_LEN; + + if ( !soe.anSoeHeaderControlUnion.Error ) + { + if ( !soe.anSoeHeaderControlUnion.InComplete ) + { + SoEIdToString(tmp, soe.anSoeHeaderDataUnion.IDN, sizeof(tmp)-1); + elm[0] = 0; + if ( soe.anSoeHeaderControlUnion.DataState ) + strcat(elm, "D"); + if ( soe.anSoeHeaderControlUnion.Name ) + strcat(elm, "N"); + if ( soe.anSoeHeaderControlUnion.Attribute ) + strcat(elm, "A"); + if ( soe.anSoeHeaderControlUnion.Unit ) + strcat(elm, "U"); + if ( soe.anSoeHeaderControlUnion.Min ) + strcat(elm, "I"); + if ( soe.anSoeHeaderControlUnion.Max ) + strcat(elm, "X"); + if ( soe.anSoeHeaderControlUnion.Value ) + strcat(elm, "V"); + switch ( soe.anSoeHeaderControlUnion.OpCode ) + { + case ECAT_SOE_OPCODE_RRQ: + g_snprintf ( szText, nMax, "SoE: RRQ (%s, '%s')", tmp, elm); + break; + case ECAT_SOE_OPCODE_RRS: + g_snprintf ( szText, nMax, "SoE: RRS (%s, '%s') : %d Bytes", tmp, elm, soe_length-ETHERCAT_SOE_HEADER_LEN); + break; + case ECAT_SOE_OPCODE_WRS: + g_snprintf ( szText, nMax, "SoE: WRS (%s, '%s')", tmp, elm); + break; + case ECAT_SOE_OPCODE_WRQ: + g_snprintf ( szText, nMax, "SoE: WRQ (%s, '%s') : %d Bytes", tmp, elm, soe_length-ETHERCAT_SOE_HEADER_LEN); + break; + case ECAT_SOE_OPCODE_NFC: + g_snprintf ( szText, nMax, "SoE: NFC (%s, '%s') : %d Bytes", tmp, elm, soe_length-ETHERCAT_SOE_HEADER_LEN); + break; + case 6: + g_snprintf ( szText, nMax, "SoE: EMGCY"); + default: + g_snprintf ( szText, nMax, "SoE:"); + } + } + else + g_snprintf ( szText, nMax, "SoE: FragmentsLeft %d", soe.anSoeHeaderDataUnion.FragmentsLeft); + } + else + g_snprintf ( szText, nMax, "SoE: Error %04x", tvb_get_letohs(tvb, offset)); +} + + +/*ethercat mailbox*/ +static void dissect_ecat_coe(tvbuff_t *tvb, gint offset, packet_info *pinfo, proto_tree *tree) +{ + proto_tree *ecat_coe_tree = NULL, *ecat_sdo_tree, *ecat_coe_sdoccs_tree, *ecat_coe_sdoscs_tree; + + proto_item *aitem = NULL, *aparent = NULL; + char szText[200]; + int nMax = sizeof(szText)-1; + + guint coe_length = tvb_reported_length(tvb)-offset; + guint16 len; + + if( tree ) + { + aitem = proto_tree_add_item(tree, hf_ecat_mailbox_coe, tvb, offset, coe_length, TRUE); + proto_item_set_text(aitem,"CoE"); + aparent = proto_item_get_parent(aitem); + proto_item_append_text(aparent,":CoE "); + } + + if (check_col(pinfo->cinfo, COL_INFO)) + col_append_str(pinfo->cinfo, COL_INFO, "CoE "); + + if( coe_length >= ETHERCAT_COE_HEADER_LEN ) + { + ETHERCAT_COE_HEADER coe; + init_coe_header(&coe, tvb, offset); + if( tree ) + { + ecat_coe_tree = proto_item_add_subtree(aitem, ett_ecat_mailbox_coe); + + CANopenNumberFormater(&coe, szText, nMax); + aitem = proto_tree_add_uint(ecat_coe_tree, hf_ecat_mailbox_coe_number, tvb, offset, ETHERCAT_COE_HEADER_LEN, coe.Number); + proto_item_set_text(aitem, szText); + + CANopenTypeFormater(&coe, szText, nMax); + aitem = proto_tree_add_uint(ecat_coe_tree, hf_ecat_mailbox_coe_type, tvb, offset, ETHERCAT_COE_HEADER_LEN, coe.Type); + proto_item_set_text(aitem, szText); + } + + offset += ETHERCAT_COE_HEADER_LEN; + + switch (coe.Type) + { + case ETHERCAT_COE_TYPE_SDOREQ: + { + ETHERCAT_SDO_HEADER sdo; + + if( coe_length < ETHERCAT_COE_HEADER_LEN + ETHERCAT_SDO_HEADER_LEN ) + { + if (check_col(pinfo->cinfo, COL_INFO)) + col_append_str(pinfo->cinfo, COL_INFO, "Sdo Req - invalid length"); + break; + } + + init_sdo_header(&sdo, tvb, offset); + + CANopenSdoReqFormater(&sdo, szText, nMax); + if (check_col(pinfo->cinfo, COL_INFO)) + col_append_str(pinfo->cinfo, COL_INFO, szText); + + if( tree ) + { + proto_item_append_text(aparent, szText); + + aitem = proto_tree_add_uint(ecat_coe_tree, hf_ecat_mailbox_coe_sdoreq, tvb, offset, 1, sdo.anSdoHeaderUnion.Idq.Ccs); + proto_item_set_text(aitem, szText); + ecat_sdo_tree = proto_item_add_subtree(aitem, ett_ecat_mailbox_sdo); + + switch ( sdo.anSdoHeaderUnion.Idq.Ccs ) + { + case SDO_CCS_INITIATE_DOWNLOAD: + aitem = proto_tree_add_item(ecat_sdo_tree, hf_ecat_mailbox_coe_sdoccsid, tvb, offset, 1, TRUE); + ecat_coe_sdoccs_tree = proto_item_add_subtree(aitem, ett_ecat_mailbox_coe_sdoccs); + aitem = proto_tree_add_item(ecat_coe_sdoccs_tree, hf_ecat_mailbox_coe_sdoccsid_sizeind, tvb, offset, 1, TRUE); + aitem = proto_tree_add_item(ecat_coe_sdoccs_tree, hf_ecat_mailbox_coe_sdoccsid_expedited, tvb, offset, 1, TRUE); + aitem = proto_tree_add_item(ecat_coe_sdoccs_tree, hf_ecat_mailbox_coe_sdoccsid_size0, tvb, offset, 1, TRUE); + aitem = proto_tree_add_item(ecat_coe_sdoccs_tree, hf_ecat_mailbox_coe_sdoccsid_size1, tvb, offset, 1, TRUE); + aitem = proto_tree_add_item(ecat_coe_sdoccs_tree, hf_ecat_mailbox_coe_sdoccsid_complete, tvb, offset, 1, TRUE); + + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoidx, tvb, offset+1, 2, TRUE); + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdosub, tvb, offset+3, 1, TRUE); + if ( sdo.anSdoHeaderUnion.Idq.SizeInd && !sdo.anSdoHeaderUnion.Idq.Expedited ) + { + len = coe_length - ETHERCAT_COE_HEADER_LEN - ETHERCAT_SDO_HEADER_LEN; + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdolength, tvb, offset+4, 4, TRUE); + offset+=ETHERCAT_SDO_HEADER_LEN; + if ( len > 0 ) + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoldata, tvb, offset, len, TRUE); + } + else + { + if ( sdo.anSdoHeaderUnion.Idq.Size == 3 ) + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdodata1, tvb, offset+4, 1, TRUE); + else if ( sdo.anSdoHeaderUnion.Idq.Size == 2 ) + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdodata2, tvb, offset+4, 2, TRUE); + else + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdodata, tvb, offset+4, 4, TRUE); + } + break; + case SDO_CCS_INITIATE_UPLOAD: + aitem = proto_tree_add_item(ecat_sdo_tree, hf_ecat_mailbox_coe_sdoccsiu, tvb, offset, 1, TRUE); + ecat_coe_sdoccs_tree = proto_item_add_subtree(aitem, ett_ecat_mailbox_coe_sdoccs); + aitem = proto_tree_add_item(ecat_coe_sdoccs_tree, hf_ecat_mailbox_coe_sdoccsid_complete, tvb, offset, 1, TRUE); + + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoidx, tvb, offset+1, 2, TRUE); + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdosub, tvb, offset+3, 1, TRUE); + + break; + case SDO_CCS_DOWNLOAD_SEGMENT: + aitem = proto_tree_add_item(ecat_sdo_tree, hf_ecat_mailbox_coe_sdoccsds, tvb, offset, 1, TRUE); + ecat_coe_sdoccs_tree = proto_item_add_subtree(aitem, ett_ecat_mailbox_coe_sdoccs); + aitem = proto_tree_add_item(ecat_coe_sdoccs_tree, hf_ecat_mailbox_coe_sdoccsds_lastseg, tvb, offset, 1, TRUE); + aitem = proto_tree_add_item(ecat_coe_sdoccs_tree, hf_ecat_mailbox_coe_sdoccsds_size, tvb, offset, 1, TRUE); + aitem = proto_tree_add_item(ecat_coe_sdoccs_tree, hf_ecat_mailbox_coe_sdoccsds_toggle, tvb, offset, 1, TRUE); + offset+=1; + + if ( coe_length-offset > 0 ) + { + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoldata, tvb, offset, coe_length-offset, TRUE); + proto_item_append_text(aitem, "(len = %d)", coe_length-offset); + } + break; + case SDO_CCS_UPLOAD_SEGMENT: + aitem = proto_tree_add_item(ecat_sdo_tree, hf_ecat_mailbox_coe_sdoccsus, tvb, offset, 1, TRUE); + ecat_coe_sdoccs_tree = proto_item_add_subtree(aitem, ett_ecat_mailbox_coe_sdoccs); + aitem = proto_tree_add_item(ecat_coe_sdoccs_tree, hf_ecat_mailbox_coe_sdoccsus_toggle, tvb, offset, 1, TRUE); + break; + case SDO_CCS_ABORT_TRANSFER: + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoidx, tvb, offset+4, 4, TRUE); + break; + } + } + } + break; + + case ETHERCAT_COE_TYPE_SDORES: + { + ETHERCAT_SDO_HEADER sdo; + if( coe_length < ETHERCAT_COE_HEADER_LEN + ETHERCAT_SDO_HEADER_LEN ) + { + if (check_col(pinfo->cinfo, COL_INFO)) + col_append_str(pinfo->cinfo, COL_INFO, "Sdo Res - invalid length"); + break; + } + + init_sdo_header(&sdo, tvb, offset); + + CANopenSdoResFormater(&sdo, szText, nMax); + if (check_col(pinfo->cinfo, COL_INFO)) + col_append_str(pinfo->cinfo, COL_INFO, szText); + + if( tree ) + { + aitem = proto_tree_add_uint(ecat_coe_tree, hf_ecat_mailbox_coe_sdores, tvb, offset, 1, sdo.anSdoHeaderUnion.Ids.Scs); + proto_item_set_text(aitem, szText); + ecat_sdo_tree = proto_item_add_subtree(aitem, ett_ecat_mailbox_sdo); + + switch ( sdo.anSdoHeaderUnion.Ids.Scs ) + { + case SDO_SCS_INITIATE_DOWNLOAD: + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoidx, tvb, offset+1, 2, TRUE); + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdosub, tvb, offset+3, 1, TRUE); + break; + case SDO_SCS_INITIATE_UPLOAD: + aitem = proto_tree_add_item(ecat_sdo_tree, hf_ecat_mailbox_coe_sdoscsiu, tvb, offset, 1, TRUE); + ecat_coe_sdoscs_tree = proto_item_add_subtree(aitem, ett_ecat_mailbox_coe_sdoscs); + aitem = proto_tree_add_item(ecat_coe_sdoscs_tree, hf_ecat_mailbox_coe_sdoscsiu_sizeind, tvb, offset, 1, TRUE); + aitem = proto_tree_add_item(ecat_coe_sdoscs_tree, hf_ecat_mailbox_coe_sdoscsiu_expedited, tvb, offset, 1, TRUE); + aitem = proto_tree_add_item(ecat_coe_sdoscs_tree, hf_ecat_mailbox_coe_sdoscsiu_size0, tvb, offset, 1, TRUE); + aitem = proto_tree_add_item(ecat_coe_sdoscs_tree, hf_ecat_mailbox_coe_sdoscsiu_size1, tvb, offset, 1, TRUE); + aitem = proto_tree_add_item(ecat_coe_sdoscs_tree, hf_ecat_mailbox_coe_sdoscsiu_complete, tvb, offset, 1, TRUE); + + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoidx, tvb, offset+1, 2, TRUE); + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdosub, tvb, offset+3, 1, TRUE); + if ( sdo.anSdoHeaderUnion.Ius.SizeInd && !sdo.anSdoHeaderUnion.Ius.Expedited ) + { + len = coe_length - ETHERCAT_COE_HEADER_LEN - ETHERCAT_SDO_HEADER_LEN; + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdolength, tvb, offset+4, 4, TRUE); + offset+=ETHERCAT_SDO_HEADER_LEN; + if ( len > 0 ) + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoldata, tvb, offset, len, TRUE); + } + else if ( sdo.anSdoHeaderUnion.Ius.SizeInd && sdo.anSdoHeaderUnion.Ius.Expedited && sdo.anSdoHeaderUnion.Ius.Size == 3 ) + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdodata1, tvb, offset+4, 1, TRUE); + else if ( sdo.anSdoHeaderUnion.Ius.SizeInd && sdo.anSdoHeaderUnion.Ius.Expedited && sdo.anSdoHeaderUnion.Ius.Size == 2 ) + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdodata2, tvb, offset+4, 2, TRUE); + else + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdodata, tvb, offset+4, 4, TRUE); + break; + case SDO_SCS_DOWNLOAD_SEGMENT: + aitem = proto_tree_add_item(ecat_sdo_tree, hf_ecat_mailbox_coe_sdoscsds, tvb, offset, 1, TRUE); + ecat_coe_sdoscs_tree = proto_item_add_subtree(aitem, ett_ecat_mailbox_coe_sdoscs); + aitem = proto_tree_add_item(ecat_coe_sdoscs_tree, hf_ecat_mailbox_coe_sdoscsds_toggle, tvb, offset, 1, TRUE); + break; + case SDO_SCS_UPLOAD_SEGMENT: + aitem = proto_tree_add_item(ecat_sdo_tree, hf_ecat_mailbox_coe_sdoscsus, tvb, offset, 1, TRUE); + ecat_coe_sdoscs_tree = proto_item_add_subtree(aitem, ett_ecat_mailbox_coe_sdoscs); + aitem = proto_tree_add_item(ecat_coe_sdoscs_tree, hf_ecat_mailbox_coe_sdoscsus_lastseg, tvb, offset, 1, TRUE); + aitem = proto_tree_add_item(ecat_coe_sdoscs_tree, hf_ecat_mailbox_coe_sdoscsus_bytes, tvb, offset, 1, TRUE); + aitem = proto_tree_add_item(ecat_coe_sdoscs_tree, hf_ecat_mailbox_coe_sdoscsus_toggle, tvb, offset, 1, TRUE); + offset+=1; + + if ( coe_length-offset> 0 ) + { + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoldata, tvb, offset, coe_length-offset, TRUE); + proto_item_append_text(aitem, "(len = %d)", coe_length-offset); + } + break; + } + } + } + break; + + case ETHERCAT_COE_TYPE_SDOINFO: + { + ETHERCAT_SDO_INFO_HEADER info; + + if( coe_length < ETHERCAT_COE_HEADER_LEN + ETHERCAT_SDO_INFO_LISTREQ_LEN ) + { + if (check_col(pinfo->cinfo, COL_INFO)) + col_append_str(pinfo->cinfo, COL_INFO, "Sdo Info - invalid length"); + break; + } + + init_sdo_info_header(&info, tvb, offset); + + CANopenSdoInfoFormater(&info, szText, nMax); + if (check_col(pinfo->cinfo, COL_INFO)) + col_append_str(pinfo->cinfo, COL_INFO, szText); + + if( tree ) + { + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfoopcode, tvb, offset++, 1, TRUE); + offset++; /*Reserved*/ + + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfofrag, tvb, offset, 2, TRUE); + offset+=2; + + switch ( info.anSdoControlUnion.OpCode ) + { + case ECAT_COE_INFO_OPCODE_LIST_Q: + { + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfolisttype, tvb, offset, 2, TRUE); + } + break; + case ECAT_COE_INFO_OPCODE_LIST_S: + { + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfolisttype, tvb, offset, 2, TRUE); + offset+=2; + + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfolist, tvb, offset, coe_length-offset, TRUE); + } + break; + case ECAT_COE_INFO_OPCODE_OBJ_Q: + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfoindex, tvb, offset, 2, TRUE); + break; + case ECAT_COE_INFO_OPCODE_OBJ_S: + { + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfoindex, tvb, offset, 2, TRUE); + offset+=2; + + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfodatatype, tvb, offset, 2, TRUE); + offset+=2; + + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfomaxsub, tvb, offset++, 1, TRUE); + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfoobjcode, tvb, offset++, 1, TRUE); + + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfoname, tvb, offset, coe_length-offset, TRUE); + } + break; + case ECAT_COE_INFO_OPCODE_ENTRY_Q: + { + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfoindex, tvb, offset, 2, TRUE); + offset+=2; + + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfosubindex, tvb, offset++, 1, TRUE); + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfovalueinfo, tvb, offset, 1, TRUE); + } + break; + case ECAT_COE_INFO_OPCODE_ENTRY_S: + { + guint16 objlen; + + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfoindex, tvb, offset, 2, TRUE); + offset+=2; + + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfosubindex, tvb, offset++, 1, TRUE); + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfovalueinfo, tvb, offset++, 1, TRUE); + + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfodatatype, tvb, offset, 2, TRUE); + offset+=2; + + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfobitlen, tvb, offset, 2, TRUE); + offset+=2; + + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfoobjaccess, tvb, offset, 2, TRUE); + offset+=2; + + if ( (info.anSdoInfoUnion.Entry.ValueInfo & 0x08) != 0 ) + { + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfounittype, tvb, offset, 2, TRUE); + offset+=2; + } + if ( (info.anSdoInfoUnion.Entry.ValueInfo & 0x10) != 0 ) + { + objlen = BIT2BYTE(info.anSdoInfoUnion.Entry.Res.BitLen); + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfodefaultvalue, tvb, offset, objlen, TRUE); + offset+=objlen; + } + if ( (info.anSdoInfoUnion.Entry.ValueInfo & 0x20) != 0 ) + { + objlen = BIT2BYTE(info.anSdoInfoUnion.Entry.Res.BitLen); + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfominvalue, tvb, offset, objlen, TRUE); + offset+=objlen; + } + if ( (info.anSdoInfoUnion.Entry.ValueInfo & 0x40) != 0 ) + { + objlen = BIT2BYTE(info.anSdoInfoUnion.Entry.Res.BitLen); + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfomaxvalue, tvb, offset, objlen, TRUE); + offset+=objlen; + } + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfoname, tvb, offset, coe_length-offset, TRUE); + } + break; + case ECAT_COE_INFO_OPCODE_ERROR_S: + { + aitem = proto_tree_add_item(ecat_coe_tree, hf_ecat_mailbox_coe_sdoinfoerrorcode, tvb, offset, 4, TRUE); + } + break; + } + } + } + break; + } + } + else + { + if (check_col(pinfo->cinfo, COL_INFO)) + col_append_str(pinfo->cinfo, COL_INFO, "- invalid length"); + } +} + +static void dissect_ecat_soe(tvbuff_t *tvb, gint offset, packet_info *pinfo, proto_tree *tree) +{ + proto_tree *ecat_soeflag_tree, *ecat_soe_tree; + + proto_item *aitem = NULL ,*aparent = NULL; + char szText[200]; + int nMax = sizeof(szText)-1; + + guint soe_length = tvb_reported_length(tvb)-offset; + + if( tree ) + { + aitem = proto_tree_add_item(tree, hf_ecat_mailbox_soe, tvb, offset, soe_length, TRUE); + + aparent = proto_item_get_parent(aitem); + proto_item_append_text(aparent,":SoE "); + } + + if( soe_length >= ETHERCAT_SOE_HEADER_LEN ) + { + SoeFormater(tvb, offset, szText, nMax, soe_length); + if (check_col(pinfo->cinfo, COL_INFO)) + col_append_str(pinfo->cinfo, COL_INFO, szText); + + if( tree ) + { + ETHERCAT_SOE_HEADER soe; + init_soe_header(&soe, tvb, offset); + + proto_item_append_text(aparent, szText); + proto_item_set_text(aitem, szText); + + ecat_soe_tree = proto_item_add_subtree(aitem, ett_ecat_mailbox_soe); + aitem = proto_tree_add_item(ecat_soe_tree, hf_ecat_mailbox_soe_header, tvb, offset , 2, TRUE); + + ecat_soeflag_tree = proto_item_add_subtree(aitem, ett_ecat_mailbox_soeflag); + aitem = proto_tree_add_item(ecat_soeflag_tree, hf_ecat_mailbox_soe_header_opcode, tvb, offset, 2, TRUE); + aitem = proto_tree_add_item(ecat_soeflag_tree, hf_ecat_mailbox_soe_header_incomplete, tvb, offset, 2, TRUE); + aitem = proto_tree_add_item(ecat_soeflag_tree, hf_ecat_mailbox_soe_header_error, tvb, offset, 2, TRUE); + aitem = proto_tree_add_item(ecat_soeflag_tree, hf_ecat_mailbox_soe_header_driveno, tvb, offset, 2, TRUE); + aitem = proto_tree_add_item(ecat_soeflag_tree, hf_ecat_mailbox_soe_header_datastate, tvb, offset, 2, TRUE); + aitem = proto_tree_add_item(ecat_soeflag_tree, hf_ecat_mailbox_soe_header_name, tvb, offset, 2, TRUE); + aitem = proto_tree_add_item(ecat_soeflag_tree, hf_ecat_mailbox_soe_header_attribute, tvb, offset, 2, TRUE); + aitem = proto_tree_add_item(ecat_soeflag_tree, hf_ecat_mailbox_soe_header_unit, tvb, offset, 2, TRUE); + aitem = proto_tree_add_item(ecat_soeflag_tree, hf_ecat_mailbox_soe_header_min, tvb, offset, 2, TRUE); + aitem = proto_tree_add_item(ecat_soeflag_tree, hf_ecat_mailbox_soe_header_max, tvb, offset, 2, TRUE); + aitem = proto_tree_add_item(ecat_soeflag_tree, hf_ecat_mailbox_soe_header_value, tvb, offset, 2, TRUE); + aitem = proto_tree_add_item(ecat_soeflag_tree, hf_ecat_mailbox_soe_header_reserved, tvb, offset, 2, TRUE); + offset+=2; + + if ( !soe.anSoeHeaderControlUnion.Error ) + { + if ( !soe.anSoeHeaderControlUnion.InComplete ) + { + switch (soe.anSoeHeaderControlUnion.OpCode) + { + case ECAT_SOE_OPCODE_RRQ: + case ECAT_SOE_OPCODE_WRS: + aitem = proto_tree_add_item(ecat_soe_tree, hf_ecat_mailbox_soe_idn, tvb, offset, 2, TRUE); + break; + case ECAT_SOE_OPCODE_RRS: + case ECAT_SOE_OPCODE_WRQ: + case ECAT_SOE_OPCODE_NFC: + aitem = proto_tree_add_item(ecat_soe_tree, hf_ecat_mailbox_soe_idn, tvb, offset, 2, TRUE); + offset+=2; + aitem = proto_tree_add_item(tree, hf_ecat_mailbox_soe_data, tvb, offset, soe_length-offset, TRUE); + break; + } + } + else + { + aitem = proto_tree_add_item(ecat_soe_tree, hf_ecat_mailbox_soe_frag, tvb, offset, 2, TRUE); + offset+=2; + + aitem = proto_tree_add_item(tree, hf_ecat_mailbox_soe_data, tvb, offset, soe_length-offset, TRUE); + } + } + else + { + aitem = proto_tree_add_item(ecat_soe_tree, hf_ecat_mailbox_soe_idn, tvb, offset, 2, TRUE); + aitem = proto_tree_add_item(tree, hf_ecat_mailbox_soe_error, tvb, offset, 2, TRUE); + } + } + } + else + { + if (check_col(pinfo->cinfo, COL_INFO)) + col_append_str(pinfo->cinfo, COL_INFO, "SoE - invalid length"); + } +} + +static void dissect_ecat_eoe(tvbuff_t *tvb, gint offset, packet_info *pinfo, proto_tree *tree) +{ + proto_tree *ecat_eoe_tree = 0, *ecat_fraghead_tree, *ecat_eoe_init_tree, *ecat_eoe_macfilter_tree, + *ecat_eoe_macfilter_filter_tree, *ecat_eoe_macfilter_filtermask_tree; + tvbuff_t *next_tvb; + proto_item *aitem = NULL, *aparent = NULL; + char szText[200]; + int nMax = sizeof(szText)-1; + int nCnt; + + guint eoe_length = tvb_reported_length(tvb)-offset; + + if( tree ) + { + aitem = proto_tree_add_item(tree, hf_ecat_mailbox_eoe, tvb, offset, eoe_length, TRUE); + proto_item_set_text(aitem, "EoE Fragment"); + + aparent = proto_item_get_parent(aitem); + proto_item_append_text(aparent,":EoE "); + } + + if( eoe_length >= ETHERCAT_EOE_HEADER_LEN ) + { + ETHERCAT_EOE_HEADER eoe; + init_eoe_header(&eoe, tvb, offset); + if (check_col(pinfo->cinfo, COL_INFO)) + { + if ( eoe.anEoeHeaderInfoUnion.Type == EOE_TYPE_FRAME_FRAG ) + g_snprintf ( szText, nMax, "EoE-Frag %d", eoe.anEoeHeaderDataUnion.Fragment); + else + g_snprintf ( szText, nMax, "EoE"); + col_append_str(pinfo->cinfo, COL_INFO, szText); + } + + if( tree ) + { + ecat_eoe_tree = proto_item_add_subtree(aitem, ett_ecat_mailbox_eoe); + + aitem = proto_tree_add_item(ecat_eoe_tree, hf_ecat_mailbox_eoe_fraghead, tvb, offset, 4, TRUE); + proto_item_set_text(aitem, "Header"); + ecat_fraghead_tree = proto_item_add_subtree(aitem, ett_ecat_mailbox_fraghead); + + aitem = proto_tree_add_uint(ecat_fraghead_tree, hf_ecat_mailbox_eoe_type, tvb, offset, 4, eoe.anEoeHeaderInfoUnion.Type); + EoETypeFormater(&eoe, szText, nMax); + proto_item_set_text(aitem,szText); + + switch ( eoe.anEoeHeaderInfoUnion.Type ) + { + case EOE_TYPE_FRAME_FRAG: + aitem = proto_tree_add_uint(ecat_fraghead_tree, hf_ecat_mailbox_eoe_fragno, tvb, offset, 4, eoe.anEoeHeaderDataUnion.Fragment); + EoEFragNoFormater(&eoe, szText, nMax); + proto_item_set_text(aitem,szText); + + aitem = proto_tree_add_uint(ecat_fraghead_tree, hf_ecat_mailbox_eoe_offset, tvb, offset, 4, 32*eoe.anEoeHeaderDataUnion.OffsetBuffer); + EoEOffsetFormater(&eoe, szText, nMax); + proto_item_set_text(aitem,szText); + + aitem = proto_tree_add_uint(ecat_fraghead_tree, hf_ecat_mailbox_eoe_frame, tvb, offset, 4, eoe.anEoeHeaderDataUnion.FrameNo); + EoEFrameFormater(&eoe, szText, nMax); + proto_item_set_text(aitem,szText); + + aitem = proto_tree_add_uint(ecat_fraghead_tree, hf_ecat_mailbox_eoe_last, tvb, offset, 4, eoe.anEoeHeaderInfoUnion.LastFragment); + EoELastFormater(&eoe, szText, nMax); + proto_item_set_text(aitem,szText); + + if ( eoe.anEoeHeaderInfoUnion.TimeStampRequested ) + { + aitem = proto_tree_add_uint(ecat_fraghead_tree, hf_ecat_mailbox_eoe_timestampreq, tvb, offset, 4, eoe.anEoeHeaderInfoUnion.TimeStampRequested); + proto_item_set_text(aitem, "Time Stamp Requested"); + } + + if ( eoe.anEoeHeaderInfoUnion.TimeStampAppended ) + { + aitem = proto_tree_add_uint(ecat_fraghead_tree, hf_ecat_mailbox_eoe_timestampapp, tvb, offset, 4, eoe.anEoeHeaderInfoUnion.TimeStampAppended); + proto_item_set_text(aitem, "Time Stamp Appended"); + } + + offset+=ETHERCAT_EOE_HEADER_LEN; + aitem = proto_tree_add_item(ecat_eoe_tree, hf_ecat_mailbox_eoe_fragment, tvb, offset, eoe_length-offset, TRUE); + + if ( eoe.anEoeHeaderDataUnion.Fragment == 0 ) + { + next_tvb = tvb_new_subset(tvb, offset, eoe_length-offset, eoe_length-offset); + call_dissector( eth_handle, next_tvb, pinfo, ecat_eoe_tree); + } + + if ( eoe.anEoeHeaderInfoUnion.TimeStampAppended ) + { + aitem = proto_tree_add_item(ecat_eoe_tree, hf_ecat_mailbox_eoe_timestamp, tvb, eoe_length-ETHERCAT_EOE_TIMESTAMP_LEN, ETHERCAT_EOE_TIMESTAMP_LEN, TRUE); + } + break; + + case EOE_TYPE_TIMESTAMP_RES: + aitem = proto_tree_add_item(ecat_eoe_tree, hf_ecat_mailbox_eoe_timestamp, tvb, offset+ETHERCAT_EOE_HEADER_LEN, ETHERCAT_EOE_TIMESTAMP_LEN, TRUE); + break; + + case EOE_TYPE_INIT_REQ: + offset+=ETHERCAT_EOE_HEADER_LEN; + aitem = proto_tree_add_item(ecat_fraghead_tree, hf_ecat_mailbox_eoe_init, tvb, offset, MIN(eoe_length-offset,ETHERCAT_EOE_INIT_LEN), TRUE); + if( eoe_length-offset >= ETHERCAT_EOE_INIT_LEN ) + { + ecat_eoe_init_tree = proto_item_add_subtree(aitem, ett_ecat_mailbox_eoe_init); + + aitem = proto_tree_add_item(ecat_eoe_init_tree, hf_ecat_mailbox_eoe_init_contains_macaddr, tvb, offset, 4, TRUE); + aitem = proto_tree_add_item(ecat_eoe_init_tree, hf_ecat_mailbox_eoe_init_contains_ipaddr, tvb, offset, 4, TRUE); + aitem = proto_tree_add_item(ecat_eoe_init_tree, hf_ecat_mailbox_eoe_init_contains_subnetmask, tvb, offset, 4, TRUE); + aitem = proto_tree_add_item(ecat_eoe_init_tree, hf_ecat_mailbox_eoe_init_contains_defaultgateway, tvb, offset, 4, TRUE); + aitem = proto_tree_add_item(ecat_eoe_init_tree, hf_ecat_mailbox_eoe_init_contains_dnsserver, tvb, offset, 4, TRUE); + aitem = proto_tree_add_item(ecat_eoe_init_tree, hf_ecat_mailbox_eoe_init_contains_dnsname, tvb, offset, 4, TRUE); + aitem = proto_tree_add_item(ecat_eoe_init_tree, hf_ecat_mailbox_eoe_init_append_timestamp, tvb, offset, 4, TRUE); + offset+=4; + + aitem = proto_tree_add_item(ecat_eoe_init_tree, hf_ecat_mailbox_eoe_init_macaddr, tvb, offset, ETHERNET_ADDRESS_LEN, TRUE); + offset+=ETHERNET_ADDRESS_LEN; + + aitem = proto_tree_add_item(ecat_eoe_init_tree, hf_ecat_mailbox_eoe_init_ipaddr, tvb, offset, 4, TRUE); + offset+=4; + + aitem = proto_tree_add_item(ecat_eoe_init_tree, hf_ecat_mailbox_eoe_init_subnetmask, tvb, offset, 4, TRUE); + offset+=4; + + aitem = proto_tree_add_item(ecat_eoe_init_tree, hf_ecat_mailbox_eoe_init_defaultgateway, tvb, offset, 4, TRUE); + offset+=4; + + aitem = proto_tree_add_item(ecat_eoe_init_tree, hf_ecat_mailbox_eoe_init_dnsserver, tvb, offset, 4, TRUE); + offset+=4; + + aitem = proto_tree_add_item(ecat_eoe_init_tree, hf_ecat_mailbox_eoe_init_dnsname, tvb, offset, 32, TRUE); + } + else + proto_item_append_text(aitem, " - Invalid length!"); + break; + + case EOE_TYPE_MACFILTER_REQ: + { + EoeMacFilterOptionsUnion options; + offset+=ETHERCAT_EOE_HEADER_LEN; + aitem = proto_tree_add_item(ecat_fraghead_tree, hf_ecat_mailbox_eoe_macfilter, tvb, offset, MIN(eoe_length-offset, ETHERCAT_EOE_MACFILTER_LEN), TRUE); + if( eoe_length-offset >= ETHERCAT_EOE_MACFILTER_LEN ) + { + ecat_eoe_macfilter_tree = proto_item_add_subtree(aitem, ett_ecat_mailbox_eoe_macfilter); + aitem = proto_tree_add_item(ecat_eoe_macfilter_tree, hf_ecat_mailbox_eoe_macfilter_macfiltercount, tvb, offset, 4, TRUE); + aitem = proto_tree_add_item(ecat_eoe_macfilter_tree, hf_ecat_mailbox_eoe_macfilter_maskcount, tvb, offset, 4, TRUE); + aitem = proto_tree_add_item(ecat_eoe_macfilter_tree, hf_ecat_mailbox_eoe_macfilter_nobroadcasts, tvb, offset, 4, TRUE); + options.Options = tvb_get_letohs(tvb, offset); + offset+=4; + + aitem = proto_tree_add_item(ecat_eoe_macfilter_tree, hf_ecat_mailbox_eoe_macfilter_filter, tvb, offset, 16*ETHERNET_ADDRESS_LEN, TRUE); + ecat_eoe_macfilter_filter_tree = proto_item_add_subtree(aitem, ett_ecat_mailbox_eoe_macfilter_filter); + for( nCnt=0; nCntcinfo, COL_INFO)) + col_prepend_fstr(pinfo->cinfo, COL_INFO, "EoE("); + + if (check_col(pinfo->cinfo, COL_PROTOCOL)) + col_prepend_fstr(pinfo->cinfo, COL_PROTOCOL, "EoE-"); + } + else + { + if (check_col(pinfo->cinfo, COL_INFO)) + col_append_str(pinfo->cinfo, COL_INFO, "EoE - invalid length!"); + } +} + +static void dissect_ecat_foe(tvbuff_t *tvb, gint offset, packet_info *pinfo, proto_tree *tree) +{ + proto_tree *ecat_foe_tree,*ecat_foe_efw_tree; + + proto_item *aitem= NULL,*aparent = NULL; + char szText[200]; + int nMax = sizeof(szText)-1; + + guint foe_length = tvb_reported_length(tvb)-offset; + + if( tree ) + { + aitem = proto_tree_add_item(tree, hf_ecat_mailbox_foe, tvb, offset, foe_length, TRUE); + proto_item_set_text(aitem, ":Foe"); + + aparent = proto_item_get_parent(aitem); + proto_item_append_text(aparent,"FoE "); + } + + if( foe_length >= ETHERCAT_FOE_HEADER_LEN ) + { + FoeFormater(tvb, offset, szText, nMax, foe_length); + if (check_col(pinfo->cinfo, COL_INFO)) + col_append_str(pinfo->cinfo, COL_INFO, szText); + + if( tree ) + { + ETHERCAT_FOE_HEADER foe; + init_foe_header(&foe, tvb, offset); + + ecat_foe_tree = proto_item_add_subtree(aitem, ett_ecat_mailbox_foe); + aitem = proto_tree_add_item(ecat_foe_tree, hf_ecat_mailbox_foe_opmode, tvb, offset++, 1, TRUE); + offset++; /*Reserved1;*/ + + switch (foe.OpMode) + { + case ECAT_FOE_OPMODE_RRQ: + case ECAT_FOE_OPMODE_WRQ: + aitem = proto_tree_add_item(ecat_foe_tree, hf_ecat_mailbox_foe_filelength, tvb, offset, 4, TRUE); + offset+=4; + + aitem = proto_tree_add_item(ecat_foe_tree, hf_ecat_mailbox_foe_filename, tvb, offset, foe_length-offset, TRUE); + break; + + case ECAT_FOE_OPMODE_DATA: + { + aitem = proto_tree_add_item(ecat_foe_tree, hf_ecat_mailbox_foe_packetno, tvb, offset, 2, TRUE); + offset+=4; /*+2 for Reserved2*/ + + aitem = proto_tree_add_item(ecat_foe_tree, hf_ecat_mailbox_foe_data, tvb, offset, foe_length-offset, TRUE); + + if( foe_length-offset >= sizeof(TEFWUPDATE_HEADER) ) + { + aitem = proto_tree_add_item(ecat_foe_tree, hf_ecat_mailbox_foe_efw, tvb, offset, foe_length-offset, TRUE); + ecat_foe_efw_tree = proto_item_add_subtree(aitem, ett_ecat_mailbox_foe_efw); + aitem = proto_tree_add_item(ecat_foe_efw_tree, hf_ecat_mailbox_foe_efw_cmd, tvb, offset, 2, TRUE); + offset+=2; + + aitem = proto_tree_add_item(ecat_foe_efw_tree, hf_ecat_mailbox_foe_efw_size, tvb, offset, 2, TRUE); + offset+=2; + + aitem = proto_tree_add_item(ecat_foe_efw_tree, hf_ecat_mailbox_foe_efw_addresslw, tvb, offset, 2, TRUE); + offset+=2; + + aitem = proto_tree_add_item(ecat_foe_efw_tree, hf_ecat_mailbox_foe_efw_addresshw, tvb, offset, 2, TRUE); + offset+=2; + + aitem = proto_tree_add_item(ecat_foe_efw_tree, hf_ecat_mailbox_foe_efw_data, tvb, offset, foe_length-offset, TRUE); + } + } + break; + + case ECAT_FOE_OPMODE_ACK: + aitem = proto_tree_add_item(ecat_foe_tree, hf_ecat_mailbox_foe_packetno, tvb, offset, 2, TRUE); + break; + + case ECAT_FOE_OPMODE_ERR: + aitem = proto_tree_add_item(ecat_foe_tree, hf_ecat_mailbox_foe_errcode, tvb, offset, 4, TRUE); + offset+=4; + + aitem = proto_tree_add_item(ecat_foe_tree, hf_ecat_mailbox_foe_errtext, tvb, offset, foe_length-offset, TRUE); + break; + + case ECAT_FOE_OPMODE_BUSY: + aitem = proto_tree_add_item(ecat_foe_tree, hf_ecat_mailbox_foe_busydone, tvb, offset, 2, TRUE); + offset+=2; + + aitem = proto_tree_add_item(ecat_foe_tree, hf_ecat_mailbox_foe_busyentire, tvb, offset, 2, TRUE); + break; + } + } + } + else + { + if (check_col(pinfo->cinfo, COL_INFO)) + col_append_str(pinfo->cinfo, COL_INFO, "FoE - invalid length"); + } +} + +static void dissect_ecat_mailbox(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + proto_tree *ecat_mailbox_tree=NULL; + tvbuff_t *next_tvb; + proto_item *aitem; + gint offset = 0; + char szText[200]; + int nMax = sizeof(szText)-1; + + guint mailbox_length = tvb_reported_length(tvb); + + if( mailbox_length >= ETHERCAT_MBOX_HEADER_LEN ) + { + ETHERCAT_MBOX_HEADER hdr; + + init_mbx_header(&hdr, tvb, offset); + pinfo->private_data = &hdr; + + if( mailbox_length >= ETHERCAT_MBOX_HEADER_LEN + hdr.Length ) + { + if (check_col(pinfo->cinfo, COL_INFO)) + col_append_str(pinfo->cinfo, COL_INFO, " Mbx("); + + if( tree ) + { + aitem = proto_tree_add_item(tree, proto_ecat_mailbox, tvb, 0, ETHERCAT_MBOX_HEADER_LEN+hdr.Length, TRUE); + ecat_mailbox_tree = proto_item_add_subtree(aitem, ett_ecat_mailbox); + + aitem = proto_tree_add_item(ecat_mailbox_tree, hf_ecat_mailboxlength, tvb, offset, sizeof(hdr.Length), TRUE); + offset+=sizeof(hdr.Length); + + aitem = proto_tree_add_item(ecat_mailbox_tree, hf_ecat_mailboxaddress, tvb, offset, sizeof(hdr.Address), TRUE); + offset+=sizeof(hdr.Address)+sizeof(guint8); + + aitem = proto_tree_add_item(ecat_mailbox_tree, hf_ecat_mailboxtype, tvb, offset, 1, TRUE); + MailboxTypeFormater(&hdr, szText, nMax); + proto_item_set_text(aitem,szText); + + aitem = proto_tree_add_item(ecat_mailbox_tree, hf_ecat_mailboxcounter, tvb, offset, 1,TRUE); + proto_item_set_text(aitem,"Counter : %d",hdr.aControlUnion.Counter); + offset++; + } + else + offset+=ETHERCAT_MBOX_HEADER_LEN; + + next_tvb = tvb_new_subset (tvb, offset, hdr.Length, hdr.Length); + switch ( hdr.aControlUnion.Type ) + { + case ETHERCAT_MBOX_TYPE_ADS: + call_dissector(ams_handle, next_tvb, pinfo, ecat_mailbox_tree); + break; + + case ETHERCAT_MBOX_TYPE_EOE: + dissect_ecat_eoe(next_tvb, 0, pinfo, ecat_mailbox_tree); + break; + + case ETHERCAT_MBOX_TYPE_COE: + dissect_ecat_coe(next_tvb, 0, pinfo, ecat_mailbox_tree); + break; + + case ETHERCAT_MBOX_TYPE_FOE: + dissect_ecat_foe(next_tvb, 0, pinfo, ecat_mailbox_tree); + break; + + case ETHERCAT_MBOX_TYPE_SOE: + dissect_ecat_soe(next_tvb, 0, pinfo, ecat_mailbox_tree); + break; + + default: + aitem = proto_tree_add_item(ecat_mailbox_tree, hf_ecat_mailboxdata, tvb, offset, hdr.Length, TRUE); + } + + if (check_col(pinfo->cinfo, COL_INFO)) + col_append_str(pinfo->cinfo, COL_INFO, ")"); + } + } +} + +void proto_register_ecat_mailbox(void) +{ + static const true_false_string flags_set_truth = + { + "Set", + "Not set" + }; + + static hf_register_info hf[] = + { + { &hf_ecat_mailbox, + { "Mbx: ", "ecat_mailbox", + FT_BYTES, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_mailboxlength, + { "Length ", "ecat_mailbox.length", + FT_UINT16, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_mailboxaddress, + { "Address ", "ecat_mailbox.address", + FT_UINT16, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_mailboxtype, + { "Type ", "ecat_mailbox.type", + FT_UINT8, BASE_HEX, VALS(EcMBoxType), 0x0F, + "", 0x0F, 0, 0, 0, NULL, NULL } + }, + { &hf_ecat_mailboxcounter, + { "Counter ", "ecat_mailbox.counter", + FT_UINT8, BASE_HEX, NULL, 0x70, + "", 0x70, 0, 0, 0, NULL, NULL } + }, + { &hf_ecat_mailbox_eoe, + { "EoE Fragment", "ecat_mailbox.eoe", + FT_BYTES, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_mailbox_eoe_fraghead, + { "Eoe Frag Header", "ecat_mailbox.eoe.fraghead", + FT_BYTES, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_mailbox_eoe_type, + { "EoE"/*"Type*/, "ecat_mailbox.eoe.type", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_eoe_fragno, + { "EoE"/*"FragNo*/, "ecat_mailbox.eoe.fragno", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_eoe_offset, + { "EoE"/*"Offset"*/, "ecat_mailbox.eoe.offset", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL} + }, + { &hf_ecat_mailbox_eoe_frame, + { "EoE"/*"FrameNo"*/, "ecat_mailbox.eoe.frame", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_eoe_last, + { "Last Fragment"/*"Last Fragment"*/, "ecat_mailbox.eoe.last", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_eoe_timestampapp, + { "Last Fragment"/*"Last Fragment"*/, "ecat_mailbox.eoe.timestampapp", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_eoe_timestampreq, + { "Last Fragment"/*"Last Fragment"*/, "ecat_mailbox.eoe.timestampreq", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_eoe_fragment, + { "EoE Frag Data", "ecat_mailbox.eoe.fragment", + FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_eoe_init, + { "Init", "ecat_mailbox.eoe.init", + FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_eoe_init_contains_macaddr, + { "MacAddr", "ecat_mailbox.eoe.init.contains_macaddr", + FT_BOOLEAN, 32, TFS(&flags_set_truth), 0x00000001, "", HFILL } + }, + { &hf_ecat_mailbox_eoe_init_contains_ipaddr, + { "IpAddr", "ecat_mailbox.eoe.init.contains_ipaddr", + FT_BOOLEAN, 32, TFS(&flags_set_truth), 0x00000002, "", HFILL } + }, + { &hf_ecat_mailbox_eoe_init_contains_subnetmask, + { "SubnetMask", "ecat_mailbox.eoe.init.contains_subnetmask", + FT_BOOLEAN, 32, TFS(&flags_set_truth), 0x00000004, "", HFILL } + }, + { &hf_ecat_mailbox_eoe_init_contains_defaultgateway, + { "DefaultGateway", "ecat_mailbox.eoe.init.contains_defaultgateway", + FT_BOOLEAN, 32, TFS(&flags_set_truth), 0x00000008, "", HFILL } + }, + { &hf_ecat_mailbox_eoe_init_contains_dnsserver, + { "DnsServer", "ecat_mailbox.eoe.init.contains_dnsserver", + FT_BOOLEAN, 32, TFS(&flags_set_truth), 0x00000010, "", HFILL } + }, + { &hf_ecat_mailbox_eoe_init_contains_dnsname, + { "DnsName", "ecat_mailbox.eoe.init.contains_dnsname", + FT_BOOLEAN, 32, TFS(&flags_set_truth), 0x00000020, "", HFILL } + }, + { &hf_ecat_mailbox_eoe_init_append_timestamp, + { "AppendTimeStamp", "ecat_mailbox.eoe.init.append_timestamp", + FT_BOOLEAN, 32, TFS(&flags_set_truth), 0x00010000, "", HFILL } + }, + { &hf_ecat_mailbox_eoe_init_macaddr, + { "Mac Addr", "ecat_mailbox.eoe.init.macaddr", + FT_ETHER, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_eoe_init_ipaddr, + { "Ip Addr", "ecat_mailbox.eoe.init.ipaddr", + FT_IPv4, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_eoe_init_subnetmask, + { "Subnet Mask", "ecat_mailbox.eoe.init.subnetmask", + FT_IPv4, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_eoe_init_defaultgateway, + { "Default Gateway", "ecat_mailbox.eoe.init.defaultgateway", + FT_IPv4, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_eoe_init_dnsserver, + { "Dns Server", "ecat_mailbox.eoe.init.dnsserver", + FT_IPv4, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_eoe_init_dnsname, + { "Dns Name", "ecat_mailbox.eoe.init.dnsname", + FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter, + { "Mac Filter", "ecat_mailbox.eoe.macfilter", + FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter_macfiltercount, + { "Mac Filter Count", "ecat_mailbox.eoe.macfilter.macfiltercount", + FT_UINT8, 16, NULL, 0x0, "", 0x0000000F, 0, 0, 0, NULL, NULL } + }, + { &hf_ecat_mailbox_eoe_macfilter_maskcount, + { "Mac Filter Mask Count", "ecat_mailbox.eoe.macfilter.maskcount", + FT_UINT8, 16, NULL, 0x0, "", 0x00000030, 0, 0, 0, NULL, NULL } + }, + { &hf_ecat_mailbox_eoe_macfilter_nobroadcasts, + { "No Broadcasts", "ecat_mailbox.eoe.macfilter.nobroadcasts", + FT_BOOLEAN, 16, TFS(&flags_set_truth), 0x0, "", 0x00000080, 0, 0, 0, NULL, NULL } + }, + { &hf_ecat_mailbox_eoe_macfilter_filter, + { "Filter", "ecat_mailbox.eoe.macfilter.filter", + FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter_filters[0], + { "Filter 0", "ecat_mailbox.eoe.macfilter.filter0", + FT_ETHER, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter_filters[1], + { "Filter 1", "ecat_mailbox.eoe.macfilter.filter1", + FT_ETHER, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter_filters[2], + { "Filter 2", "ecat_mailbox.eoe.macfilter.filter2", + FT_ETHER, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter_filters[3], + { "Filter 3", "ecat_mailbox.eoe.macfilter.filter3", + FT_ETHER, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter_filters[4], + { "Filter 4", "ecat_mailbox.eoe.macfilter.filter4", + FT_ETHER, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter_filters[5], + { "Filter 5", "ecat_mailbox.eoe.macfilter.filter5", + FT_ETHER, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter_filters[6], + { "Filter 6", "ecat_mailbox.eoe.macfilter.filter6", + FT_ETHER, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter_filters[7], + { "Filter 7", "ecat_mailbox.eoe.macfilter.filter7", + FT_ETHER, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter_filters[8], + { "Filter 8", "ecat_mailbox.eoe.macfilter.filter8", + FT_ETHER, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter_filters[9], + { "Filter 9", "ecat_mailbox.eoe.macfilter.filter9", + FT_ETHER, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter_filters[10], + { "Filter 10", "ecat_mailbox.eoe.macfilter.filter10", + FT_ETHER, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter_filters[11], + { "Filter 11", "ecat_mailbox.eoe.macfilter.filter11", + FT_ETHER, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter_filters[12], + { "Filter 12", "ecat_mailbox.eoe.macfilter.filter12", + FT_ETHER, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter_filters[13], + { "Filter 13", "ecat_mailbox.eoe.macfilter.filter13", + FT_ETHER, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter_filters[14], + { "Filter 14", "ecat_mailbox.eoe.macfilter.filter14", + FT_ETHER, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter_filters[15], + { "Filter 15", "ecat_mailbox.eoe.macfilter.filter15", + FT_ETHER, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter_filtermask, + { "Filter Mask", "ecat_mailbox.eoe.macfilter.filtermask", + FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter_filtermasks[0], + { "Mask 0", "ecat_mailbox.eoe.macfilter.filtermask0", + FT_ETHER, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter_filtermasks[1], + { "Mask 1", "ecat_mailbox.eoe.macfilter.filtermask1", + FT_ETHER, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter_filtermasks[2], + { "Mask 2", "ecat_mailbox.eoe.macfilter.filtermask2", + FT_ETHER, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_eoe_macfilter_filtermasks[3], + { "Mask 3", "ecat_mailbox.eoe.macfilter.filtermask3", + FT_ETHER, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_eoe_timestamp, + { "Time Stamp", "ecat_mailbox.eoe.timestamp", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_coe, + { "CoE", "ecat_mailbox.coe", + FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_coe_number, + { "Number", "ecat_mailbox.coe.number", + FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_coe_type, + { "Type ", "ecat_mailbox.coe.type", + FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_coe_sdoreq, + { "SDO Req", "ecat_mailbox.coe.sdoreq", + FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_coe_sdoccsid, + { "Initiate Download", "ecat_mailbox.coe.sdoccsid", + FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_coe_sdoccsid_sizeind, + { "Size Ind.", "ecat_mailbox.coe.sdoccsid.sizeind", + FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x00000001, + "", HFILL } + }, + { &hf_ecat_mailbox_coe_sdoccsid_expedited, + { "Expedited", "ecat_mailbox.coe.sdoccsid.expedited", + FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x00000002, + "", HFILL } + }, + { &hf_ecat_mailbox_coe_sdoccsid_size0, + { "Bytes", "ecat_mailbox.coe.sdoccsid.size0", + FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x00000004, + "", HFILL } + }, + { &hf_ecat_mailbox_coe_sdoccsid_size1, + { "Bytes", "ecat_mailbox.coe.sdoccsid.size1", + FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x00000008, + "", HFILL } + }, + { &hf_ecat_mailbox_coe_sdoccsid_complete, + { "Access", "ecat_mailbox.coe.sdoccsid.complete", + FT_BOOLEAN, 8, TFS(&tfs_complete), 0x00000010, + "", HFILL } + }, + { &hf_ecat_mailbox_coe_sdoccsds, + { "Download Segment", "ecat_mailbox.coe.sdoccsds", + FT_UINT8, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_mailbox_coe_sdoccsds_lastseg, + { "Last Segment", "ecat_mailbox.coe.sdoccsds.lastseg", + FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x00000001, + "", HFILL } + }, + { &hf_ecat_mailbox_coe_sdoccsds_size, + { "Size", "ecat_mailbox.coe.sdoccsds.size", + FT_UINT8, BASE_DEC, NULL, 0x0000000E, + "", 0x0000000E, 0, 0, 0, NULL, NULL } + }, + { &hf_ecat_mailbox_coe_sdoccsds_toggle, + { "Toggle Bit", "ecat_mailbox.coe.sdoccsds.toggle", + FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x00000010, + "", HFILL } + }, + { &hf_ecat_mailbox_coe_sdoccsiu, + { "Init Upload", "ecat_mailbox.coe.sdoccsiu", + FT_UINT8, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_mailbox_coe_sdoccsiu_complete, + { "Toggle Bit", "ecat_mailbox.coe.sdoccsiu_complete", + FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x00000010, + "", HFILL } + }, + { &hf_ecat_mailbox_coe_sdoccsus, + { "Upload Segment", "ecat_mailbox.coe.sdoccsus", + FT_UINT8, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_mailbox_coe_sdoccsus_toggle, + { "Toggle Bit", "ecat_mailbox.coe.sdoccsus_toggle", + FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x00000010, + "", HFILL } + }, + + { &hf_ecat_mailbox_coe_sdoidx, + { "Index ", "ecat_mailbox.coe.sdoidx", + FT_UINT16, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_mailbox_coe_sdosub, + { "SubIndex", "ecat_mailbox.coe.sdosub", + FT_UINT8, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_mailbox_coe_sdodata, + { "Data ", "ecat_mailbox.coe.sdodata", + FT_UINT32, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_mailbox_coe_sdodata1, + { "Data ", "ecat_mailbox.coe.sdodata", + FT_UINT8, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_mailbox_coe_sdodata2, + { "Data ", "ecat_mailbox.coe.sdodata", + FT_UINT16, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_mailbox_coe_sdoldata, + { "Data ", "ecat_mailbox.coe.dsoldata", + FT_BYTES, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_mailbox_coe_sdolength, + { "Length ", "ecat_mailbox.coe.sdolength", + FT_UINT32, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_mailbox_coe_sdoerror, + { "SDO Error ", "ecat_mailbox.coe.sdoerror", + FT_UINT32, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_mailbox_coe_sdores, + { "SDO Res ", "ecat_mailbox.coe.sdores", + FT_UINT8, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_mailbox_coe_sdoscsiu, + { "Initiate Upload Response", "ecat_mailbox.coe.sdoscsiu", + FT_UINT8, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_mailbox_coe_sdoscsiu_sizeind, + { "Size Ind.", "ecat_mailbox.coe.sdoscsiu_sizeind", + FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x00000001, + "", HFILL } + }, + { &hf_ecat_mailbox_coe_sdoscsiu_expedited, + { "Expedited", "ecat_mailbox.coe.sdoscsiu_expedited", + FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x00000002, + "", HFILL } + }, + { &hf_ecat_mailbox_coe_sdoscsiu_size0, + { "Bytes", "ecat_mailbox.coe.sdoscsiu_size0", + FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x00000004, + "", HFILL } + }, + { &hf_ecat_mailbox_coe_sdoscsiu_size1, + { "Bytes", "ecat_mailbox.coe.sdoscsiu_size1", + FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x00000008, + "", HFILL } + }, + { &hf_ecat_mailbox_coe_sdoscsiu_complete, + { "Access", "ecat_mailbox.coe.sdoscsiu_complete", + FT_BOOLEAN, 8, TFS(&tfs_complete), 0x00000010, + "", HFILL } + }, + { &hf_ecat_mailbox_coe_sdoscsds, + { "Download Segment Response", "ecat_mailbox.coe.sdoscsds", + FT_UINT8, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_mailbox_coe_sdoscsds_toggle, + { "Toggle Bit", "ecat_mailbox.coe.sdoscsds_toggle", + FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x00000010, + "", HFILL } + }, + { &hf_ecat_mailbox_coe_sdoscsus, + { "Upload Segment", "ecat_mailbox.coe.sdoscsus", + FT_UINT8, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_mailbox_coe_sdoscsus_lastseg, + { "Last Segment", "ecat_mailbox.coe.sdoscsus_lastseg", + FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x00000001, + "", HFILL } + }, + { &hf_ecat_mailbox_coe_sdoscsus_bytes, + { "Bytes", "ecat_mailbox.coe.sdoscsus_bytes", + FT_UINT8, BASE_DEC, NULL, 0x0000000E, + "", 0x0000000E, 0, 0, 0, NULL, NULL } + }, + { &hf_ecat_mailbox_coe_sdoscsus_toggle, + { "Toggle Bit", "ecat_mailbox.coe.sdoscsus_toggle", + FT_BOOLEAN, 8, TFS(&flags_set_truth), 0x00000010, + "", HFILL } + }, + { &hf_ecat_mailbox_coe_sdoinfoopcode, + { "Info OpCode ", "ecat_mailbox.coe.sdoinfoopcode", + FT_UINT8, BASE_HEX, NULL, 0x0, + "", HFILL }, + }, + { &hf_ecat_mailbox_coe_sdoinfofrag, + { "Info Frag Left ", "ecat_mailbox.coe.sdoinfofrag", + FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }, + }, + { &hf_ecat_mailbox_coe_sdoinfolisttype, + { "Info List Type ", "ecat_mailbox.coe.sdoinfolisttype", + FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }, + }, + { &hf_ecat_mailbox_coe_sdoinfolist, + { "Info List ", "ecat_mailbox.coe.sdoinfolist", + FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }, + }, + { &hf_ecat_mailbox_coe_sdoinfoindex, + { "Info Obj Index ", "ecat_mailbox.coe.sdoinfoindex", + FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }, + }, + { &hf_ecat_mailbox_coe_sdoinfosubindex, + { "Info Obj SubIdx ", "ecat_mailbox.coe.sdoinfosubindex", + FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL }, + }, + { &hf_ecat_mailbox_coe_sdoinfovalueinfo, + { "Info Obj SubIdx ", "ecat_mailbox.coe.sdoinfovalueinfo", + FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL }, + }, + { &hf_ecat_mailbox_coe_sdoinfoerrorcode, + { "Info Error Code ", "ecat_mailbox.coe.sdoinfoerrorcode", + FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }, + }, + { &hf_ecat_mailbox_coe_sdoinfodatatype, + { "Info Data Type ", "ecat_mailbox.coe.sdoinfodatatype", + FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }, + }, + { &hf_ecat_mailbox_coe_sdoinfomaxsub, + { "Info Max SubIdx ", "ecat_mailbox.coe.sdoinfomaxsub", + FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL }, + }, + { &hf_ecat_mailbox_coe_sdoinfoobjcode, + { "Info Obj Code ", "ecat_mailbox.coe.sdoinfoobjcode", + FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL }, + }, + { &hf_ecat_mailbox_coe_sdoinfoname, + { "Info Name ", "ecat_mailbox.coe.sdoinfoname", + FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }, + }, + { &hf_ecat_mailbox_coe_sdoinfobitlen, + { "Info Bit Len ", "ecat_mailbox.coe.sdoinfobitlen", + FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }, + }, + { &hf_ecat_mailbox_coe_sdoinfoobjaccess, + { "Info Obj Access ", "ecat_mailbox.coe.sdoinfoobjaccess", + FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }, + }, + { &hf_ecat_mailbox_coe_sdoinfounittype, + { "Info Data Type ", "ecat_mailbox.coe.sdoinfounittype", + FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }, + }, + { &hf_ecat_mailbox_coe_sdoinfodefaultvalue, + { "Info Default Val", "ecat_mailbox.coe.sdoinfodefaultvalue", + FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }, + }, + { &hf_ecat_mailbox_coe_sdoinfominvalue, + { "Info Min Val ", "ecat_mailbox.coe.sdoinfominvalue", + FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }, + }, + { &hf_ecat_mailbox_coe_sdoinfomaxvalue, + { "Info Max Val ", "ecat_mailbox.coe.sdoinfomaxvalue", + FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }, + }, + { &hf_ecat_mailboxdata, + { "MB Data", "ecat_mailbox.data", + FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_foe, + { "Foe", "ecat_mailbox.foe", + FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_foe_opmode, + { "Foe OpMode ", "ecat_mailbox.foe_opmode", + FT_UINT8, BASE_HEX, VALS(FoEOpMode), 0x0, "Op modes", HFILL } + }, + { &hf_ecat_mailbox_foe_filelength, + { "Foe FileLength" , "ecat_mailbox.foe_filelength", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_foe_filename, + { "Foe FileName ", "ecat_mailbox.foe_filename", + FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_foe_packetno, + { "Foe PacketNo ", "ecat_mailbox.foe_packetno", + FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_foe_errcode, + { "Foe ErrorCode ", "ecat_mailbox.foe_errcode", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_foe_errtext, + { "Foe ErrorString", "ecat_mailbox.foe_errtext", + FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_foe_busydone, + { "Foe BusyDone ", "ecat_mailbox.foe_busydone", + FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_foe_busyentire, + { "Foe BusyEntire ", "ecat_mailbox.foe_busyentire", + FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_foe_data, + { "Foe Data ", "ecat_mailbox.foe_busydata", + FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_foe_efw, + { "Firmware", "ecat_mailbox.foe.efw", + FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_foe_efw_cmd, + { "Cmd ", "ecat_mailbox.foe.efw.cmd", + FT_UINT16, BASE_HEX, VALS(FoEEfwCmd), 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_foe_efw_size, + { "Size ", "ecat_mailbox.foe.efw.size", + FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_foe_efw_addresslw, + { "AddressLW", "ecat_mailbox.foe.efw.addresslw", + FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_foe_efw_addresshw, + { "AddressHW", "ecat_mailbox.foe.efw.addresshw", + FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_foe_efw_data, + { "Data ", "ecat_mailbox.foe.efw.data", + FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_soe, + { "Soe", "ecat_mailbox.soe", + FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_soe_header, + { "Soe Header ", "ecat_mailbox.soe_header", + FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_soe_header_opcode, + { "SoE OpCode", "ecat_mailbox.soe_opcode", + FT_UINT16, BASE_DEC, VALS(SoeOpcode), 0x00000007, "", 0x00000007, 0, 0, 0, NULL, NULL } + }, + { &hf_ecat_mailbox_soe_header_incomplete, + { "More Follows...", "ecat_mailbox.soe_header_incomplete", + FT_BOOLEAN, 16, TFS(&flags_set_truth), 0x00000008, "", HFILL } + }, + { &hf_ecat_mailbox_soe_header_error, + { "Error", "ecat_mailbox.soe_header_error", + FT_BOOLEAN, 16, TFS(&flags_set_truth), 0x00000010, + "", HFILL } + }, + { &hf_ecat_mailbox_soe_header_driveno, + { "Drive No", "ecat_mailbox.soe_header_driveno", + FT_UINT16, BASE_DEC, NULL, 0x000000e0, "", 0x000000e0, 0, 0, 0, NULL, NULL} + }, + { &hf_ecat_mailbox_soe_header_datastate, + { "Datastate", "ecat_mailbox.soe_header_datastate", + FT_BOOLEAN, 16, TFS(&flags_set_truth), 0x00000100, + "", HFILL } + }, + { &hf_ecat_mailbox_soe_header_name, + { "Name", "ecat_mailbox.soe_header_name", + FT_BOOLEAN, 16, TFS(&flags_set_truth), 0x00000200, + "", HFILL } + }, + { &hf_ecat_mailbox_soe_header_attribute, + { "Attribute", "ecat_mailbox.soe_header_attribute", + FT_BOOLEAN, 16, TFS(&flags_set_truth), 0x00000400, + "", HFILL } + }, + { &hf_ecat_mailbox_soe_header_unit, + { "Unit", "ecat_mailbox.soe_header_unit", + FT_BOOLEAN, 16, TFS(&flags_set_truth), 0x00000800, + "", HFILL } + }, + { &hf_ecat_mailbox_soe_header_min, + { "Min", "ecat_mailbox.soe_header_min", + FT_BOOLEAN, 16, TFS(&flags_set_truth), 0x00001000, + "", HFILL } + }, + { &hf_ecat_mailbox_soe_header_max, + { "Max", "ecat_mailbox.soe_header_max", + FT_BOOLEAN, 16, TFS(&flags_set_truth), 0x00002000, + "", HFILL } + }, + { &hf_ecat_mailbox_soe_header_value, + { "Value", "ecat_mailbox.soe_header_value", + FT_BOOLEAN, 16, TFS(&flags_set_truth), 0x00004000, + "", HFILL } + }, + { &hf_ecat_mailbox_soe_header_reserved, + { "Reserved", "ecat_mailbox.soe_header_reserved", + FT_BOOLEAN, 16, TFS(&flags_set_truth), 0x00008000, + "", HFILL } + }, + { &hf_ecat_mailbox_soe_idn, + { "SoE IDN ", "ecat_mailbox.soe_idn", + FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_soe_data, + { "SoE Data ", "ecat_mailbox.soe_data", + FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_soe_frag, + { "SoE FragLeft ", "ecat_mailbox.soe_frag", + FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_mailbox_soe_error, + { "SoE Error ", "ecat_mailbox.soe_error", + FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL } + } + }; + + static gint *ett[] = + { + &ett_ecat_mailbox, + &ett_ecat_mailbox_eoe, + &ett_ecat_mailbox_eoe_init, + &ett_ecat_mailbox_eoe_macfilter, + &ett_ecat_mailbox_eoe_macfilter_filter, + &ett_ecat_mailbox_eoe_macfilter_filtermask, + &ett_ecat_mailbox_coe, + &ett_ecat_mailbox_sdo, + &ett_ecat_mailbox_coe_sdoccs, + &ett_ecat_mailbox_coe_sdoscs, + &ett_ecat_mailbox_foe, + &ett_ecat_mailbox_foe_efw, + &ett_ecat_mailbox_soeopmode, + &ett_ecat_mailbox_soeflag, + &ett_ecat_mailbox_soe, + &ett_ecat_mailbox_fraghead + }; + + proto_ecat_mailbox = proto_register_protocol("EtherCAT Mailbox Protocol", + "ECAT_MAILBOX","ecat_mailbox"); + proto_register_field_array(proto_ecat_mailbox,hf,array_length(hf)); + proto_register_subtree_array(ett,array_length(ett)); + + register_dissector("ecat_mailbox", dissect_ecat_mailbox, proto_ecat_mailbox); +} + +void proto_reg_handoff_ecat_mailbox(void) +{ + static dissector_handle_t ecat_mailbox_handle; + + /* Register this dissector as a sub dissector to E88A4 based on ether type. */ + ecat_mailbox_handle = create_dissector_handle(dissect_ecat_mailbox, proto_ecat_mailbox); + dissector_add("ecatf.type", 5, ecat_mailbox_handle); + + eth_handle = find_dissector("eth_withoutfcs"); + ams_handle = find_dissector("ams"); +} diff --git a/plugins/ethercat/packet-ecatmb.h b/plugins/ethercat/packet-ecatmb.h new file mode 100644 index 0000000000..29ba4d3b9c --- /dev/null +++ b/plugins/ethercat/packet-ecatmb.h @@ -0,0 +1,512 @@ +/* Copyright (c) 2007 by Beckhoff Automation GmbH + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * 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. + */ +#ifndef _PACKET_ECATMAILBOX_H_ +#define _PACKET_ECATMAILBOX_H_ + +/* Ensure the same data layout for all platforms */ +#pragma pack(push, 1) + +typedef struct TETHERNET_ADDRESS +{ + guint8 b[6]; +} ETHERNET_ADDRESS, *PETHERNET_ADDRESS; +#define ETHERNET_ADDRESS_LEN sizeof(ETHERNET_ADDRESS) + +/* Mailbox*/ +#define ETHERCAT_MBOX_TYPE_ADS 1 /* AMS/ADS header follows*/ +#define ETHERCAT_MBOX_TYPE_EOE 2 /* ETHERCAT_EOE_HEADER follows*/ +#define ETHERCAT_MBOX_TYPE_COE 3 /* ETHERCAT_COE_HEADER follows*/ +#define ETHERCAT_MBOX_TYPE_FOE 4 /* ETHERCAT_FOE_HEADER follows*/ +#define ETHERCAT_MBOX_TYPE_SOE 5 /* ETHERCAT_SOE_HEADER follows*/ + +typedef union tMbxHeaderControlUnion +{ + guint16 Control; + struct + { + guint16 Channel : 6; /* optional communication channels (default = 0)*/ + guint16 Priority : 2; /* optional communication priority (default = 0)*/ + guint16 Type : 4; /* TETHERCAT_MBOX_TYPE_xxx*/ + guint16 Counter : 3; /* 0 = counter not used (old version)*/ + guint16 Unsupported : 1; /* unsupported protocol detected*/ + }; +} MbxHeaderControlUnion; + +typedef struct TETHERCAT_MBOX_HEADER +{ + guint16 Length; /* following bytes*/ + guint16 Address; /* S->M: phys addr of destination; M->S: phys addr of source; 0 = master*/ + MbxHeaderControlUnion aControlUnion; +} ETHERCAT_MBOX_HEADER, *PETHERCAT_MBOX_HEADER; + +#define ETHERCAT_MBOX_HEADER_LEN sizeof(ETHERCAT_MBOX_HEADER) + +/*/////////////////////////////////////////////////////////////////////////////*/ +/* EoE*/ +#define ETHERNET_FRAMENO_MASK 0x0000000F + +#define EOE_TYPE_FRAME_FRAG 0 /* ETHERCAT_EOE_HEADER followed by frame fragment (ETHERCAT_EOE_TIMESTAMP may included) */ +#define EOE_TYPE_TIMESTAMP_RES 1 /* ETHERCAT_EOE_HEADER followed by ETHERCAT_EOE_TIMESTAMP */ +#define EOE_TYPE_INIT_REQ 2 /* ETHERCAT_EOE_HEADER followed by ETHERCAT_EOE_INIT */ +#define EOE_TYPE_INIT_RES 3 /* ETHERCAT_EOE_HEADER */ +#define EOE_TYPE_MACFILTER_REQ 4 /* ETHERCAT_EOE_HEADER followed by ETHERCAT_EOE_MACFILTER */ +#define EOE_TYPE_MACFILTER_RES 5 /* ETHERCAT_EOE_HEADER */ + +#define EOE_RESULT_NOERROR 0x0000 +#define EOE_RESULT_UNSPECIFIED_ERROR 0x0001 +#define EOE_RESULT_UNSUPPORTED_TYPE 0x0002 +#define EOE_RESULT_NO_IP_SUPPORT 0x0201 +#define EOE_RESULT_NO_MACFILTERMASK_SUPPORT 0x0401 + +static char* EoEResultText(guint16 result) +{ + switch (result) + { + case EOE_RESULT_NOERROR: + return "No error"; + case EOE_RESULT_UNSPECIFIED_ERROR: + return "Unspecified error"; + case EOE_RESULT_UNSUPPORTED_TYPE: + return "Unsupported type"; + case EOE_RESULT_NO_IP_SUPPORT: + return "No IP support"; + case EOE_RESULT_NO_MACFILTERMASK_SUPPORT: + return "No MAC filter support"; + } + return ""; +} + +typedef struct TETHERCAT_EOE_INIT +{ + guint32 ContainsMacAddr :1; + guint32 ContainsIpAddr :1; + guint32 ContainsSubnetMask :1; + guint32 ContainsDefaultGateway :1; + guint32 ContainsDnsServer :1; + guint32 ContainsDnsName :1; + guint32 Reserved :26; + ETHERNET_ADDRESS MacAddr; + guint32 IpAddr; + guint32 SubnetMask; + guint32 DefaultGateway; + guint32 DnsServer; + char DnsName[32]; +} ETHERCAT_EOE_INIT, *PETHERCAT_EOE_INIT; +#define ETHERCAT_EOE_INIT_LEN sizeof(ETHERCAT_EOE_INIT) + +typedef union tEoeMacFilterOptionsUnion +{ + struct + { + guint16 MacFilterCount :4; + guint16 MacFilterMaskCount :2; + guint16 Reserved1 :1; + guint16 NoBroadcasts :1; + guint16 Reserved2 :8; + }; + guint16 Options; +} EoeMacFilterOptionsUnion; + + +typedef struct TETHERCAT_EOE_MACFILTER +{ + EoeMacFilterOptionsUnion anEoeMacFilterOptionsUnion; + ETHERNET_ADDRESS MacFilter[16]; + ETHERNET_ADDRESS MacFilterMask[4]; +} ETHERCAT_EOE_MACFILTER, *PETHERCAT_EOE_MACFILTER; +#define ETHERCAT_EOE_MACFILTER_LEN sizeof(ETHERCAT_EOE_MACFILTER) + +typedef struct TETHERCAT_EOE_TIMESTAMP +{ + guint32 TimeStamp; /* 32 bit time stamp */ +} ETHERCAT_EOE_TIMESTAMP, *PETHERCAT_EOE_TIMESTAMP; +#define ETHERCAT_EOE_TIMESTAMP_LEN sizeof(ETHERCAT_EOE_TIMESTAMP) + +typedef union tEoeHeaderDataUnion +{ + struct + { /* EOE_TYPE_FRAME_FRAG and EOE_TYPE_TIMESTAMP_RES only */ + guint16 Fragment : 6; /* fragment number (EOE_TYPE_FRAME_FRAG only) */ + guint16 OffsetBuffer : 6; /* byte offset multiplied by 32 (if Fragment != 0) (EOE_TYPE_FRAME_FRAG only) */ + /* buffer size multiplied by 32 (if Fragment == 0) (EOE_TYPE_FRAME_FRAG only) */ + guint16 FrameNo : 4; /* frame number (EOE_TYPE_FRAME_FRAG and EOE_TYPE_TIMESTAMP_RES only) */ + }; + guint16 Result; /* EOE_TYPE_INIT_RES and EOE_TYPE_MACFILTER_RES only */ +} EoeHeaderDataUnion; + +typedef union tEoeHeaderInfoUnion +{ + struct + { + guint16 Type : 4; /* specifies following data */ + guint16 PortAssign : 4; /* 0 = unspecified, 1 = port 1 */ + guint16 LastFragment : 1; /* TRUE if last fragment (EOE_TYPE_FRAME_FRAG only) */ + guint16 TimeStampAppended : 1; /* 32 bit time stamp appended (EOE_TYPE_FRAME_FRAG with LastFragment=1 only) */ + guint16 TimeStampRequested : 1; /* time stamp response requested (EOE_TYPE_FRAME_FRAG only) */ + guint16 Reserved : 5; + }; + guint16 Info; +} EoeHeaderInfoUnion; + + +typedef struct TETHERCAT_EOE_HEADER +{ + EoeHeaderInfoUnion anEoeHeaderInfoUnion; + EoeHeaderDataUnion anEoeHeaderDataUnion; +} ETHERCAT_EOE_HEADER, *PETHERCAT_EOE_HEADER; +#define ETHERCAT_EOE_HEADER_LEN sizeof(ETHERCAT_EOE_HEADER) + +/*/////////////////////////////////////////////////////////////////////////////*/ +/* CANopen*/ +#define ETHERCAT_COE_TYPE_EMERGENCY 1 +#define ETHERCAT_COE_TYPE_SDOREQ 2 +#define ETHERCAT_COE_TYPE_SDORES 3 +#define ETHERCAT_COE_TYPE_TXPDO 4 +#define ETHERCAT_COE_TYPE_RXPDO 5 +#define ETHERCAT_COE_TYPE_TXPDO_RTR 6 /* Remote transmission request of TXPDO (master requested)*/ +#define ETHERCAT_COE_TYPE_RXPDO_RTR 7 /* Remote transmission request of RXPDO (slave requested) */ +#define ETHERCAT_COE_TYPE_SDOINFO 8 + +typedef union TETHERCAT_COE_HEADER +{ + struct + { + guint16 Number : 9; /* e.g. PDO number*/ + guint16 Reserved : 3; /* = 0*/ + guint16 Type : 4; /* CANopen type*/ + }; + guint16 header; +} ETHERCAT_COE_HEADER, *PETHERCAT_COE_HEADER; +#define ETHERCAT_COE_HEADER_LEN sizeof(ETHERCAT_COE_HEADER) + +#pragma pack(pop) +/*ETHERCAT_SDO_HEADER not naturally aligned -> can't use pragma pack 1*/ + +typedef union tSdoHeaderUnion +{ + struct + { /* Initiate Download Request*/ + guint8 SizeInd : 1; + guint8 Expedited : 1; + guint8 Size : 2; + guint8 Complete : 1; + guint8 Ccs : 3; /* = 1*/ + } Idq; + struct + { /* Initiate Download Response*/ + guint8 Reserved : 5; + guint8 Scs : 3; /* = 3*/ + } Ids; + struct + { /* Download Segment Request*/ + guint8 LastSeg : 1; + guint8 Size : 3; + guint8 Toggle : 1; + guint8 Ccs : 3; /* = 0*/ + } Dsq; + struct + { /* Download Segment Response*/ + guint8 Reserved : 4; + guint8 Toggle : 1; + guint8 Scs : 3; /* = 1*/ + } Dss; + struct + { /* Initiate Upload Request*/ + guint8 Reserved : 4; + guint8 Complete : 1; + guint8 Ccs : 3; /* = 2*/ + } Iuq; + struct + { /* Initiate Upload Response*/ + guint8 SizeInd : 1; + guint8 Expedited : 1; + guint8 Size : 2; + guint8 Complete : 1; + guint8 Scs : 3; /* = 2*/ + } Ius; + struct + { /* Upload Segment Request*/ + guint8 Reserved : 4; + guint8 Toggle : 1; + guint8 Ccs : 3; /* = 3*/ + } Usq; + struct + { /* Upload Segment Response*/ + guint8 LastSeg : 1; + guint8 Bytes : 3; + guint8 Toggle : 1; + guint8 Scs : 3; /* = 0*/ + } Uss; + struct + { /* Abort Transfer*/ + guint8 Reserved : 5; + guint8 Ccs : 3; /* = 4*/ + } Abt; + guint8 CS; +} SdoHeaderUnion; + +typedef struct TETHERCAT_SDO_HEADER +{ + SdoHeaderUnion anSdoHeaderUnion; + + guint16 Index; + guint8 SubIndex; + guint32 Data; +} ETHERCAT_SDO_HEADER, *PETHERCAT_SDO_HEADER; + +#define ETHERCAT_SDO_HEADER_LEN 8 /* sizeof(ETHERCAT_SDO_HEADER)*/ + +#pragma pack(push,1) + +#define SDO_CCS_DOWNLOAD_SEGMENT 0 +#define SDO_CCS_INITIATE_DOWNLOAD 1 +#define SDO_CCS_INITIATE_UPLOAD 2 +#define SDO_CCS_UPLOAD_SEGMENT 3 +#define SDO_CCS_ABORT_TRANSFER 4 + +#define SDO_SCS_UPLOAD_SEGMENT 0 +#define SDO_SCS_DOWNLOAD_SEGMENT 1 +#define SDO_SCS_INITIATE_UPLOAD 2 +#define SDO_SCS_INITIATE_DOWNLOAD 3 + +/* CoE SDO Information */ +#define ECAT_COE_INFO_OPCODE_LIST_Q 1 +#define ECAT_COE_INFO_OPCODE_LIST_S 2 +#define ECAT_COE_INFO_OPCODE_OBJ_Q 3 +#define ECAT_COE_INFO_OPCODE_OBJ_S 4 +#define ECAT_COE_INFO_OPCODE_ENTRY_Q 5 +#define ECAT_COE_INFO_OPCODE_ENTRY_S 6 +#define ECAT_COE_INFO_OPCODE_ERROR_S 7 + +#define ECAT_COE_INFO_LIST_TYPE_LENGTH 0 +#define ECAT_COE_INFO_LIST_TYPE_ALL 1 +#define ECAT_COE_INFO_LIST_TYPE_PDOMAP 2 +#define ECAT_COE_INFO_LIST_TYPE_BACKUP 3 + +#define ECAT_COE_INFO_OBJCODE_NULL 0 +#define ECAT_COE_INFO_OBJCODE_DOMAIN 2 +#define ECAT_COE_INFO_OBJCODE_DEFTYPE 5 +#define ECAT_COE_INFO_OBJCODE_DEFSTRUCT 6 +#define ECAT_COE_INFO_OBJCODE_VAR 7 +#define ECAT_COE_INFO_OBJCODE_ARRAY 8 +#define ECAT_COE_INFO_OBJCODE_RECORD 9 + +#define ECAT_COE_INFO_OBJCAT_OPTIONAL 0 +#define ECAT_COE_INFO_OBJCAT_MANDATORY 1 + +#define ECAT_COE_INFO_OBJACCESS_RO 0x07 +#define ECAT_COE_INFO_OBJACCESS_RW 0x3f + +typedef struct TETHERCAT_SDO_INFO_LIST +{ + guint16 ListType; /* == SDO_INFO_LIST_TYPE_XXX */ + struct + { + guint16 Index[1]; + } Res; +} ETHERCAT_SDO_INFO_LIST, *PETHERCAT_SDO_INFO_LIST; + +typedef struct TETHERCAT_SDO_INFO_OBJ +{ + guint16 Index; + struct + { + guint16 DataType; /* refer to data type index */ + guint8 MaxSubIndex; /* max subIndex */ + guint8 ObjCode; /* defined in DS 301 (Table 37)*/ + char Name[1]; /* rest of mailbox data*/ + } Res; +} ETHERCAT_SDO_INFO_OBJ, *PETHERCAT_SDO_INFO_OBJ; + +typedef struct TETHERCAT_SDO_INFO_ENTRY +{ + guint16 Index; + guint8 SubIdx; + guint8 ValueInfo; /* bit0 = ObjAccess, bit1 = ObjCategory, bit2 = PdoMapping, bit3 = UnitType + bit4 = DefaultValue, bit5 = MinValue, bit6 = MaxValue*/ + struct + { + guint16 DataType; /* refer to data type index */ + guint16 BitLen; + guint16 ObjAccess; /* bit0 = read; bit1 = write; bit2 = const. bit3 = 'PRE-OP'; bit4 = 'SAFE-OP'; bit5 = 'OP'.*/ + } Res; +} ETHERCAT_SDO_INFO_ENTRY, *PETHERCAT_SDO_INFO_ENTRY; + +typedef struct TETHERCAT_SDO_INFO_ERROR +{ + guint32 ErrorCode; + char ErrorText[1]; /* rest of mailbox data */ +} ETHERCAT_SDO_INFO_ERROR, *PETHERCAT_SDO_INFO_ERROR; + +typedef union tSdoInfoUnion +{ + ETHERCAT_SDO_INFO_LIST List; + ETHERCAT_SDO_INFO_OBJ Obj; + ETHERCAT_SDO_INFO_ENTRY Entry; + ETHERCAT_SDO_INFO_ERROR Error; + guint8 Data[1]; +} SdoInfoUnion; + +typedef union tSdoControlUnion +{ + struct + { + guint8 OpCode : 7; /* == SDO_INFO_TYPE_XXX */ + guint8 InComplete : 1; + }; + guint8 Control; +} SdoControlUnion; + +typedef struct TETHERCAT_SDO_INFO_HEADER +{ + SdoControlUnion anSdoControlUnion; + guint8 Reserved; /* == 0 */ + guint16 FragmentsLeft; + SdoInfoUnion anSdoInfoUnion; +} ETHERCAT_SDO_INFO_HEADER, *PETHERCAT_SDO_INFO_HEADER; + +#define ETHERCAT_SDO_INFO_LISTREQ_LEN offsetof(ETHERCAT_SDO_INFO_HEADER, anSdoInfoUnion.List.Res) +#define ETHERCAT_SDO_INFO_OBJREQ_LEN offsetof(ETHERCAT_SDO_INFO_HEADER, anSdoInfoUnionObj.Res) +#define ETHERCAT_SDO_INFO_ENTRYREQ_LEN offsetof(ETHERCAT_SDO_INFO_HEADER, anSdoInfoUnionEntry.Res) + +/* FoE (File Access over EtherCAT)*/ +#define ECAT_FOE_OPMODE_RRQ 1 +#define ECAT_FOE_OPMODE_WRQ 2 +#define ECAT_FOE_OPMODE_DATA 3 +#define ECAT_FOE_OPMODE_ACK 4 +#define ECAT_FOE_OPMODE_ERR 5 +#define ECAT_FOE_OPMODE_BUSY 6 + +#define ECAT_FOE_ERRCODE_NOTDEFINED 0 +#define ECAT_FOE_ERRCODE_NOTFOUND 1 +#define ECAT_FOE_ERRCODE_ACCESS 2 +#define ECAT_FOE_ERRCODE_DISKFULL 3 +#define ECAT_FOE_ERRCODE_ILLEAGAL 4 +#define ECAT_FOE_ERRCODE_PACKENO 5 +#define ECAT_FOE_ERRCODE_EXISTS 6 +#define ECAT_FOE_ERRCODE_NOUSER 7 +#define ECAT_FOE_ERRCODE_BOOTSTRAPONLY 8 +#define ECAT_FOE_ERRCODE_NOTINBOOTSTRAP 9 + +#pragma pack(pop) +/*ETHERCAT_FOE_HEADER is not naturally aligned --> can't use pragma pack 1*/ + +typedef union tFoeHeaderDataUnion +{ + guint32 FileLength; /* (RRQ, WRQ) = 0 if unknown */ + struct + { + guint16 PacketNo; /* (DATA, ACK)*/ + guint16 Reserved2; /* (DATA, ACK)*/ + }; + guint32 ErrorCode; /* (ERR)*/ + struct + { + guint16 Done; /* (BUSY)*/ + guint16 Entire; /* (BUSY)*/ + }; +} FoeHeaderDataUnion; + +typedef struct TETHERCAT_FOE_HEADER +{ + guint8 OpMode; /* = 1 (RRQ), = 2 (WRQ), = 3 (DATA), = 4 (ACK), = 5 (ERR), = 6 (BUSY) */ + guint8 Reserved1; /* = 0 */ + + FoeHeaderDataUnion aFoeHeaderDataUnion; + /* typedef union tMailBoxDataUnion + { + char Name[] (RRQ, WRQ) rest of mailbox data + guint8 Data[] (DATA) rest of mailbox data (if OpMode = 3) + char ErrorText[] (ERR) rest of mailbox data + } MailBoxDataUnion;*/ +} ETHERCAT_FOE_HEADER, *PETHERCAT_FOE_HEADER; +#define ETHERCAT_FOE_HEADER_LEN 6 /*sizeof(ETHERCAT_FOE_HEADER)*/ + +#pragma pack(push,1) + +typedef struct +{ + guint16 Cmd; + guint16 Size; + guint16 AddressLW; + guint16 AddressHW; +} TEFWUPDATE_HEADER; + + +/* SoE (SOE over EtherCAT)*/ +#define ECAT_SOE_OPCODE_RRQ 1 +#define ECAT_SOE_OPCODE_RRS 2 +#define ECAT_SOE_OPCODE_WRQ 3 +#define ECAT_SOE_OPCODE_WRS 4 +#define ECAT_SOE_OPCODE_NFC 5 + + +typedef union tSoeHeaderControlUnion +{ + struct + { + guint8 OpCode : 3; /* 0 = unused, 1 = readReq, 2 = readRes, 3 = writeReq, 4 = writeRes + 5 = notification (command changed notification)*/ + guint8 InComplete : 1; /* more follows*/ + guint8 Error : 1; /* an error word follows */ + guint8 DriveNo : 3; /* drive number */ + + guint8 DataState : 1; /* follows or requested */ + guint8 Name : 1; /* follows or requested */ + guint8 Attribute : 1; /* follows or requested */ + guint8 Unit : 1; /* follows or requested */ + guint8 Min : 1; /* follows or requested */ + guint8 Max : 1; /* follows or requested */ + guint8 Value : 1; /* follows or requested */ + guint8 Reserved : 1; + }; + struct + { + guint8 Control; + guint8 Element; + }; +} SoeHeaderControlUnion; + +typedef union tSoeHeaderDataUnion +{ + guint16 IDN; /* SOE IDN if (InComplete==0) */ + guint16 FragmentsLeft; /* Pending fragments if (InComplete==1) */ +} SoeHeaderDataUnion; + +typedef struct TETHERCAT_SOE_HEADER +{ + SoeHeaderControlUnion anSoeHeaderControlUnion; + SoeHeaderDataUnion anSoeHeaderDataUnion; + /* typedef union tMailBoxDataUnion + { + guint8 Data[] rest of mailbox data if (Error==0) + guint16 ErrorCode if (Error==1) + } MailBoxDataUnion;*/ +} ETHERCAT_SOE_HEADER, *PETHERCAT_SOE_HEADER; +#define ETHERCAT_SOE_HEADER_LEN sizeof(ETHERCAT_SOE_HEADER) + + + +#pragma pack(pop) + +extern void init_mbx_header(PETHERCAT_MBOX_HEADER pMbox, tvbuff_t *tvb, gint offset); + +#endif diff --git a/plugins/ethercat/packet-ethercat-datagram.c b/plugins/ethercat/packet-ethercat-datagram.c new file mode 100644 index 0000000000..7f8e3517b8 --- /dev/null +++ b/plugins/ethercat/packet-ethercat-datagram.c @@ -0,0 +1,1569 @@ +/* packet-ethercat-datagram.c + * Routines for ethercat packet disassembly + * + * $Id$ + * + * Copyright (c) 2007 by Beckhoff Automation GmbH + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * 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. + */ + +/* Include files */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include "packet-ethercat-datagram.h" +#include "packet-ecatmb.h" + + +void proto_reg_handoff_ecat(void); + +static dissector_handle_t ecat_mailbox_handle; + +/* Define the ethercat proto */ +static int proto_ecat_datagram = -1; + +/* Define the tree for ethercat */ +static int ett_ecat = -1; +static int ett_ecat_summary = -1; +static int ett_ecat_sub; +static int ett_ecat_header = -1; +static int ett_ecat_fmmu = -1; +static int ett_ecat_syncman = -1; +static int ett_ecat_syncflag = -1; +static int ett_ecat_fmmu_type = -1; +static int ett_ecat_fmmu_active = -1; +static int ett_ecat_dc = -1; + +static int hf_ecat_sub; +static int hf_ecat_sub_data[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; +static int hf_ecat_sub_cmd[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; +static int hf_ecat_sub_idx[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; +static int hf_ecat_sub_cnt[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; +static int hf_ecat_sub_ado[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; +static int hf_ecat_sub_adp[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; +static int hf_ecat_sub_lad[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; + +static int hf_ecat_header = -1; +static int hf_ecat_data = -1; +static int hf_ecat_cnt = -1; +static int hf_ecat_cmd = -1; +static int hf_ecat_idx = -1; +static int hf_ecat_adp = -1; +static int hf_ecat_ado = -1; +static int hf_ecat_lad = -1; +static int hf_ecat_len = -1; +static int hf_ecat_int = -1; +static int hf_ecat_syncman = -1; +static int hf_ecat_syncman_start = -1; +static int hf_ecat_syncman_len = -1; +static int hf_ecat_syncman_flags = -1; +static int hf_ecat_syncman_flag0 = -1; +static int hf_ecat_syncman_flag1 = -1; +static int hf_ecat_syncman_flag2 = -1; +static int hf_ecat_syncman_flag4 = -1; +static int hf_ecat_syncman_flag5 = -1; +static int hf_ecat_syncman_flag8 = -1; +static int hf_ecat_syncman_flag9 = -1; +static int hf_ecat_syncman_flag10 = -1; +static int hf_ecat_syncman_flag11 = -1; +static int hf_ecat_syncman_flag12 = -1; +static int hf_ecat_syncman_flag13 = -1; +static int hf_ecat_syncman_flag16 = -1; +static int hf_ecat_fmmu = -1; +static int hf_ecat_fmmu_lstart = -1; +static int hf_ecat_fmmu_llen = -1; +static int hf_ecat_fmmu_lstartbit = -1; +static int hf_ecat_fmmu_lendbit = -1; +static int hf_ecat_fmmu_pstart = -1; +static int hf_ecat_fmmu_pstartbit = -1; +static int hf_ecat_fmmu_type = -1; +static int hf_ecat_fmmu_typeread = -1; +static int hf_ecat_fmmu_typewrite = -1; +static int hf_ecat_fmmu_active = -1; +static int hf_ecat_fmmu_active0 = -1; + +static int hf_ecat_sub_dc_diff_da[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; +static int hf_ecat_sub_dc_diff_bd[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; +static int hf_ecat_sub_dc_diff_cb[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; +static int hf_ecat_sub_dc_diff_cd[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; +static int hf_ecat_sub_dc_diff_ba[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; +static int hf_ecat_sub_dc_diff_ca[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; + +static int hf_ecat_dc_diff_da = -1; +static int hf_ecat_dc_diff_bd = -1; +static int hf_ecat_dc_diff_cb = -1; +static int hf_ecat_dc_diff_cd = -1; +static int hf_ecat_dc_diff_ba = -1; +static int hf_ecat_dc_diff_ca = -1; + + +static const value_string EcCmd[] = +{ + { 0, "NOP", }, + { 1, "APRD", }, + { 2, "APWR", }, + { 3, "APRW", }, + { 4, "FPRD", }, + { 5, "FPWR", }, + { 6, "FPRW", }, + { 7, "BRD", }, + { 8, "BWR", }, + { 9, "BRW", }, + { 10, "LRD", }, + { 11, "LWR", }, + { 12, "LRW", }, + { 13, "ARMW", }, + { 14, "FRMW", }, + { 255, "EXT", }, + { 0, NULL } +}; + + +static const true_false_string tfs_ecat_fmmu_typeread = +{ + "Read in use", "Read ignore" +}; + +static const true_false_string tfs_ecat_fmmu_typewrite = +{ + "Write in use", "Write ignore" +}; + +static const true_false_string tfs_ecat_fmmu_active = +{ + "Enabled", "Disabled" +}; + +static const true_false_string tfs_ecat_syncman_flag0 = +{ + "OPMODE xx", "OPMODE xx" +}; + +static const true_false_string tfs_ecat_syncman_flag1 = +{ + "00: 3-Buf, 01: 3-Buf (Mon.), 10: 1-Buf", "00: 3-Buf, 01: 3-Buf (Mon.), 10: 1-Buf", +}; + +static const true_false_string tfs_ecat_syncman_flag2 = +{ + "Write", "Read" +}; + +static const true_false_string tfs_ecat_syncman_flag4 = +{ + "IRQ ECAT enabled", "IRQ ECAT disabled" +}; + +static const true_false_string tfs_ecat_syncman_flag5 = +{ + "IRQ PDI enabled", "IRQ PDI disabled" +}; + +static const true_false_string tfs_ecat_syncman_flag8 = +{ + "IRQ Write 1", "IRQ Write 0" +}; + +static const true_false_string tfs_ecat_syncman_flag9 = +{ + "IRQ Read 1", "IRQ Read 0" +}; + +static const true_false_string tfs_ecat_syncman_flag10 = +{ + "Watchdog", "No Watchdog" +}; + +static const true_false_string tfs_ecat_syncman_flag11 = +{ + "1-Buf written", "1-Buf read" +}; + +static const true_false_string tfs_ecat_syncman_flag12 = +{ + "Buffer Status xx", "Buffer Status xx" +}; + +static const true_false_string tfs_ecat_syncman_flag13 = +{ + "00: 1.Buf, 01: 2.Buf, 10: 3.Buf", "00: 1.Buf, 01: 2.Buf, 10: 3.Buf" +}; + +static const true_false_string tfs_ecat_syncman_flag16 = +{ + "SyncMan enabled", "SyncMan disabled", +}; + +static const char* convertEcCmdToText(int cmd) +{ + return val_to_str(cmd, EcCmd, ""); +} + +#define ENDOF(p) ((p)+1) /* pointer to end of *p*/ + +typedef enum +{ + EC_CMD_TYPE_NOP = 0, + EC_CMD_TYPE_APRD = 1, + EC_CMD_TYPE_APWR = 2, + EC_CMD_TYPE_APRW = 3, + EC_CMD_TYPE_FPRD = 4, + EC_CMD_TYPE_FPWR = 5, + EC_CMD_TYPE_FPRW = 6, + EC_CMD_TYPE_BRD = 7, + EC_CMD_TYPE_BWR = 8, + EC_CMD_TYPE_BRW = 9, + EC_CMD_TYPE_LRD = 10, + EC_CMD_TYPE_LWR = 11, + EC_CMD_TYPE_LRW = 12, + EC_CMD_TYPE_ARMW = 13, + EC_CMD_TYPE_FRMW = 14, + EC_CMD_TYPE_EXT = 255 +} EC_CMD_TYPE; + +static void init_EcParserHDR(EcParserHDR* pHdr, tvbuff_t *tvb, gint offset) +{ + pHdr->cmd = tvb_get_guint8(tvb, offset++); + pHdr->idx = tvb_get_guint8(tvb, offset++); + pHdr->adp = tvb_get_letohs(tvb, offset); offset+=sizeof(guint16); + pHdr->ado = tvb_get_letohs(tvb, offset); offset+=sizeof(guint16); + pHdr->len = tvb_get_letohs(tvb, offset); offset+=sizeof(guint16); + pHdr->intr = tvb_get_letohs(tvb, offset); +} + +static void init_dc_measure(guint32* pDC, tvbuff_t *tvb, gint offset) +{ + int i; + for ( i=0; i<4; i++ ) + { + pDC[i] = tvb_get_letohl(tvb, offset); + offset+=sizeof(guint32); + } +} + +static guint16 get_wc(EcParserHDR* pHdr, tvbuff_t *tvb, gint offset) +{ + return tvb_get_letohs(tvb, offset+EcParserHDR_Len+(pHdr->len&0x07ff)); +} + +static guint16 get_cmd_len(EcParserHDR* pHdr) +{ + return (EcParserHDR_Len+(pHdr->len&0x07ff)+sizeof(guint16)); /*Header + data + wc*/ +} + + +static void EcSummaryFormater(guint32 datalength, tvbuff_t *tvb, gint offset, char *szText, gint nMax) +{ + guint nSub=0; + guint nLen=0; + guint8 nCmds[4]; + guint nLens[4]; + EcParserHDR ecFirst; + EcParserHDR ecParser; + + guint suboffset=0; + + init_EcParserHDR(&ecFirst, tvb, offset); + + while ( suboffset < datalength ) + { + PEcParserHDR pEcParser; + if ( nSub > 0 ) + { + init_EcParserHDR(&ecParser, tvb, offset+suboffset); + pEcParser = &ecParser; + } + else + pEcParser = &ecFirst; + + if ( nSub < 4 ) + { + nCmds[nSub] = pEcParser->cmd; + nLens[nSub] = pEcParser->len&0x07ff; + } + nSub++; + nLen += (pEcParser->len&0x07ff); + /* bit 14 -- roundtrip */ + + if ( (pEcParser->len&0x8000) == 0 ) + break; + + suboffset+=get_cmd_len(pEcParser); + } + if ( nSub == 1 ) + { + guint16 len = ecFirst.len&0x07ff; + guint16 cnt = get_wc(&ecFirst, tvb, offset); + g_snprintf ( szText, nMax, "'%s', Len: %d, Adp 0x%x, Ado 0x%x, Wc %d ", + convertEcCmdToText(ecFirst.cmd), len, ecFirst.adp, ecFirst.ado, cnt ); + } + else if ( nSub == 2 ) + { + g_snprintf ( szText, nMax, "%d Cmds, '%s', Len %d, '%s', Len %d ", + nSub, convertEcCmdToText(nCmds[0]), nLens[0], convertEcCmdToText(nCmds[1]), nLens[1]); + } + else if ( nSub == 3 ) + { + g_snprintf ( szText, nMax, "%d Cmds, '%s', Len %d, '%s', Len %d, '%s', Len %d", + nSub, convertEcCmdToText(nCmds[0]), nLens[0], convertEcCmdToText(nCmds[1]), nLens[1], convertEcCmdToText(nCmds[2]), nLens[2]); + } + else if ( nSub == 4 ) + { + g_snprintf ( szText, nMax, "%d Cmds, '%s', L %d, '%s', L %d, '%s', L %d, '%s', L %d", + nSub, convertEcCmdToText(nCmds[0]), nLens[0], convertEcCmdToText(nCmds[1]), nLens[1], convertEcCmdToText(nCmds[2]), nLens[2], convertEcCmdToText(nCmds[3]), nLens[3]); + } + else + g_snprintf ( szText, nMax, "%d Cmds, SumLen %d, '%s'... ", + nSub, nLen, convertEcCmdToText(ecFirst.cmd)); +} + +static void EcSubFormater(tvbuff_t *tvb, gint offset, char *szText, gint nMax) +{ + EcParserHDR ecParser; + guint16 len, cnt; + + init_EcParserHDR(&ecParser, tvb, offset); + len = ecParser.len&0x07ff; + cnt = get_wc(&ecParser, tvb, offset); + + switch ( ecParser.cmd ) + { + case EC_CMD_TYPE_NOP: + case EC_CMD_TYPE_APRD: + case EC_CMD_TYPE_APWR: + case EC_CMD_TYPE_APRW: + case EC_CMD_TYPE_FPRD: + case EC_CMD_TYPE_FPWR: + case EC_CMD_TYPE_FPRW: + case EC_CMD_TYPE_BRD: + case EC_CMD_TYPE_BWR: + case EC_CMD_TYPE_BRW: + case EC_CMD_TYPE_ARMW: + case EC_CMD_TYPE_FRMW: + g_snprintf ( szText, nMax, "Sub Frame: Cmd: '%s' (%d), Len: %d, Adp 0x%x, Ado 0x%x, Cnt %d", + convertEcCmdToText(ecParser.cmd), ecParser.cmd, len, ecParser.adp, ecParser.ado, cnt); + break; + case EC_CMD_TYPE_LRD: + case EC_CMD_TYPE_LWR: + case EC_CMD_TYPE_LRW: + g_snprintf ( szText, nMax, "Sub Frame: Cmd: '%s' (%d), Len: %d, Addr 0x%x, Cnt %d", + convertEcCmdToText(ecParser.cmd), ecParser.cmd, len, *(guint32*)&ecParser.adp, cnt); + break; + case EC_CMD_TYPE_EXT: + g_snprintf ( szText, nMax, "Sub Frame: Cmd: 'EXT' (%d), Len: %d", ecParser.cmd, len); + break; + default: + g_snprintf ( szText, nMax, "Sub Frame: Cmd: 'Unknown' (%d), Len: %d", ecParser.cmd, len); + } +} + +static void EcLenFormater(guint16 len, char *szText, gint nMax) +{ + g_snprintf( szText, nMax, "(0x%x) - %s - %s", len&0x07ff, len&0x4000 ? "Roundtrip" : "No Roundtrip", len&0x8000 ? "More Follows...":"Last Sub Command" ); +} + +/* Ethercat Datagram */ +static void dissect_ecat_datagram(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + tvbuff_t *next_tvb; + proto_item *ti, *aitem; + proto_tree *ecat_tree = NULL; + gint offset = 0; + char szText[200]; + int nMax = sizeof(szText)-1; + guint b; + + guint ecat_length = tvb_reported_length(tvb); + + guint32 ecLength=0; + guint subCount = 0; + + if (check_col(pinfo->cinfo, COL_PROTOCOL)) + col_set_str(pinfo->cinfo, COL_PROTOCOL, "ECAT"); + + if (check_col(pinfo->cinfo, COL_INFO)) + col_clear(pinfo->cinfo, COL_INFO); + + while ( TRUE ) + { + EcParserHDR ecHdr; + init_EcParserHDR(&ecHdr, tvb, ecLength); + ecLength+=get_cmd_len(&ecHdr); + if ( (ecHdr.len&0x8000) == 0 ) + break; + } + + EcSummaryFormater(ecLength, tvb, offset, szText, nMax); + if (check_col(pinfo->cinfo, COL_INFO)) + col_append_str(pinfo->cinfo, COL_INFO, szText); + + if( tree ) + { + ti = proto_tree_add_item(tree, proto_ecat_datagram, tvb, 0, -1, TRUE); + ecat_tree = proto_item_add_subtree(ti, ett_ecat); + + proto_item_append_text(ti,": %s",szText); + } + + while ( TRUE ) + { + proto_tree *ecat_sub_tree = 0, *ecat_header_tree, *ecat_fmmu_tree, *ecat_fmmu_active_tree, + *ecat_fmmu_type_tree, *ecat_syncman_tree, *ecat_syncflag_tree, *ecat_dc_tree; + + gint bMBox = FALSE; + guint32 subsize; + guint32 suboffset; + guint32 len; + + EcParserHDR ecHdr; + suboffset = offset; + init_EcParserHDR(&ecHdr, tvb, suboffset); + + subsize = get_cmd_len(&ecHdr); + len = ecHdr.len&0x7fff; + + if ( len >= sizeof(ETHERCAT_MBOX_HEADER) && + (ecHdr.cmd==EC_CMD_TYPE_FPWR || ecHdr.cmd==EC_CMD_TYPE_FPRD || ecHdr.cmd==EC_CMD_TYPE_APWR || ecHdr.cmd==EC_CMD_TYPE_APRD) && + ecHdr.ado>=0x1000 + ) + { + ETHERCAT_MBOX_HEADER mbox; + init_mbx_header(&mbox, tvb, suboffset+EcParserHDR_Len); + + switch ( mbox.aControlUnion.Type ) + { + case ETHERCAT_MBOX_TYPE_EOE: + case ETHERCAT_MBOX_TYPE_ADS: + case ETHERCAT_MBOX_TYPE_FOE: + case ETHERCAT_MBOX_TYPE_COE: + case ETHERCAT_MBOX_TYPE_SOE: + if ( /*pMBox->Length > 0 &&*/ mbox.Length <= 1500 /*&& pMBox->Length+sizeof(ETHERCAT_MBOX_HEADER) >= len*/ ) + { + bMBox = TRUE; + } + break; + } + } + + if( tree ) + { + aitem = proto_tree_add_item(ecat_tree, hf_ecat_sub, tvb, suboffset, subsize, TRUE); + EcSubFormater(tvb, suboffset, szText, nMax); + proto_item_set_text(aitem,szText); + + ecat_sub_tree = proto_item_add_subtree(aitem, ett_ecat_sub); + aitem = proto_tree_add_item(ecat_sub_tree, hf_ecat_header, tvb, suboffset, EcParserHDR_Len, TRUE); + proto_item_set_text(aitem, "Header"); + + ecat_header_tree = proto_item_add_subtree(aitem, ett_ecat_header); + aitem = proto_tree_add_item(ecat_header_tree, hf_ecat_cmd, tvb, suboffset, sizeof(ecHdr.cmd), TRUE); + if( subCount < 10 ) + aitem = proto_tree_add_item_hidden(ecat_header_tree, hf_ecat_sub_cmd[subCount], tvb, suboffset, sizeof(ecHdr.cmd), TRUE); + suboffset+= sizeof(ecHdr.cmd); + + aitem = proto_tree_add_item(ecat_header_tree, hf_ecat_idx, tvb, suboffset, sizeof(ecHdr.idx), TRUE); + if( subCount < 10 ) + aitem = proto_tree_add_item_hidden(ecat_header_tree, hf_ecat_sub_idx[subCount], tvb, suboffset, sizeof(ecHdr.idx), TRUE); + suboffset+= sizeof(ecHdr.idx); + + switch ( ecHdr.cmd ) + { + case 10: + case 11: + case 12: + aitem = proto_tree_add_item(ecat_header_tree, hf_ecat_lad, tvb, suboffset, sizeof(ecHdr.adp)+sizeof(ecHdr.ado), TRUE); + if( subCount < 10 ) + aitem = proto_tree_add_item_hidden(ecat_header_tree, hf_ecat_sub_lad[subCount], tvb, suboffset, sizeof(ecHdr.adp)+sizeof(ecHdr.ado), TRUE); + + suboffset += (sizeof(ecHdr.adp)+sizeof(ecHdr.ado)); + break; + default: + aitem = proto_tree_add_item(ecat_header_tree, hf_ecat_adp, tvb, suboffset, sizeof(ecHdr.adp), TRUE); + if( subCount < 10 ) + aitem = proto_tree_add_item_hidden(ecat_header_tree, hf_ecat_sub_adp[subCount], tvb, suboffset, sizeof(ecHdr.adp), TRUE); + + suboffset+= sizeof(ecHdr.adp); + aitem = proto_tree_add_item(ecat_header_tree, hf_ecat_ado, tvb, suboffset, sizeof(ecHdr.ado), TRUE); + if( subCount < 10 ) + aitem = proto_tree_add_item_hidden(ecat_header_tree, hf_ecat_sub_ado[subCount], tvb, suboffset, sizeof(ecHdr.ado), TRUE); + + suboffset+= sizeof(ecHdr.ado); + } + + aitem = proto_tree_add_uint(ecat_header_tree, hf_ecat_len, tvb, suboffset, sizeof(ecHdr.len), ecHdr.len&0x07FF); + EcLenFormater(ecHdr.len, szText, nMax); + proto_item_append_text(aitem,szText); + + suboffset+= sizeof(ecHdr.len); + + aitem = proto_tree_add_item(ecat_header_tree, hf_ecat_int, tvb, suboffset, sizeof(ecHdr.intr), TRUE); + suboffset+= sizeof(ecHdr.intr); + } + else + { + suboffset+=EcParserHDR_Len; + } + + if ( ecHdr.cmd>=1 && ecHdr.cmd<=9 && ecHdr.ado>=0x600 && ecHdr.ado<0x700 && (ecHdr.ado%16)==0 && (len%16)==0 ) + { + if( tree ) + { + /* FMMU */ + for ( b=0; b < MIN(16, len/16); b++ ) + { + aitem = proto_tree_add_item(ecat_sub_tree, hf_ecat_fmmu, tvb, suboffset, 16, TRUE); + proto_item_set_text(aitem, "FMMU"); + + ecat_fmmu_tree = proto_item_add_subtree(aitem, ett_ecat_fmmu); + + aitem = proto_tree_add_item(ecat_fmmu_tree, hf_ecat_fmmu_lstart, tvb, suboffset, 4, TRUE); + suboffset += 4; + aitem = proto_tree_add_item(ecat_fmmu_tree, hf_ecat_fmmu_llen, tvb, suboffset, 2, TRUE); + suboffset += 2; + aitem = proto_tree_add_item(ecat_fmmu_tree, hf_ecat_fmmu_lstartbit, tvb, suboffset, 1, TRUE); + suboffset += 1; + aitem = proto_tree_add_item(ecat_fmmu_tree, hf_ecat_fmmu_lendbit, tvb, suboffset, 1, TRUE); + suboffset += 1; + aitem = proto_tree_add_item(ecat_fmmu_tree, hf_ecat_fmmu_pstart, tvb, suboffset, 2, TRUE); + suboffset += 2; + aitem = proto_tree_add_item(ecat_fmmu_tree, hf_ecat_fmmu_pstartbit, tvb, suboffset, 1, TRUE); + suboffset += 1; + aitem = proto_tree_add_item(ecat_fmmu_tree, hf_ecat_fmmu_type, tvb, suboffset, 1, TRUE); + ecat_fmmu_type_tree = proto_item_add_subtree(aitem, ett_ecat_fmmu_type); + aitem = proto_tree_add_item(ecat_fmmu_type_tree, hf_ecat_fmmu_typeread, tvb, suboffset, 1, TRUE); + aitem = proto_tree_add_item(ecat_fmmu_type_tree, hf_ecat_fmmu_typewrite, tvb, suboffset, 1, TRUE); + + suboffset += 1; + aitem = proto_tree_add_item(ecat_fmmu_tree, hf_ecat_fmmu_active, tvb, suboffset, 1, TRUE); + ecat_fmmu_active_tree = proto_item_add_subtree(aitem, ett_ecat_fmmu_active); + aitem = proto_tree_add_item(ecat_fmmu_active_tree, hf_ecat_fmmu_active0, tvb, suboffset, 1, TRUE); + + suboffset += 4; + } + if ( len > 0x100 ) + { + len -= 0x100; + for ( b=0; b < MIN(32, len/8); b++ ) + { + aitem = proto_tree_add_item(ecat_sub_tree, hf_ecat_syncman, tvb, suboffset, 8, TRUE); + proto_item_set_text(aitem, "SyncManager"); + ecat_syncman_tree = proto_item_add_subtree(aitem, ett_ecat_syncman); + + aitem = proto_tree_add_item(ecat_syncman_tree, hf_ecat_syncman_start, tvb, suboffset, 2, TRUE); + suboffset+=2; + aitem = proto_tree_add_item(ecat_syncman_tree, hf_ecat_syncman_len, tvb, suboffset, 2, TRUE); + suboffset+=2; + + aitem = proto_tree_add_item(ecat_syncman_tree, hf_ecat_syncman_flags, tvb, suboffset, 4, TRUE); + ecat_syncflag_tree = proto_item_add_subtree(aitem, ett_ecat_syncflag); + aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag0, tvb, suboffset, 4, TRUE); + aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag1, tvb, suboffset, 4, TRUE); + aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag2, tvb, suboffset, 4, TRUE); + aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag4, tvb, suboffset, 4, TRUE); + aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag5, tvb, suboffset, 4, TRUE); + aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag8, tvb, suboffset, 4, TRUE); + aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag9, tvb, suboffset, 4, TRUE); + aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag10, tvb, suboffset, 4, TRUE); + aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag11, tvb, suboffset, 4, TRUE); + aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag12, tvb, suboffset, 4, TRUE); + aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag13, tvb, suboffset, 4, TRUE); + aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag16, tvb, suboffset, 4, TRUE); + suboffset+=4; + } + } + } + } + else if ( ecHdr.cmd>=1 && ecHdr.cmd<=9 && ecHdr.ado>=0x800 && ecHdr.ado<0x880 && (ecHdr.ado%8)==0 && (len%8)==0 ) + { + if( tree ) + { + /* SyncMan*/ + for ( b=0; b < MIN(32, len/8); b++ ) + { + aitem = proto_tree_add_item(ecat_sub_tree, hf_ecat_syncman, tvb, suboffset, 8, TRUE); + proto_item_set_text(aitem, "SyncManager"); + ecat_syncman_tree = proto_item_add_subtree(aitem, ett_ecat_syncman); + + aitem = proto_tree_add_item(ecat_syncman_tree, hf_ecat_syncman_start, tvb, suboffset, 2, TRUE); + suboffset+=2; + aitem = proto_tree_add_item(ecat_syncman_tree, hf_ecat_syncman_len, tvb, suboffset, 2, TRUE); + suboffset+=2; + + aitem = proto_tree_add_item(ecat_syncman_tree, hf_ecat_syncman_flags, tvb, suboffset, 4, TRUE); + ecat_syncflag_tree = proto_item_add_subtree(aitem, ett_ecat_syncflag); + aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag0, tvb, suboffset, 4, TRUE); + aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag1, tvb, suboffset, 4, TRUE); + aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag2, tvb, suboffset, 4, TRUE); + aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag4, tvb, suboffset, 4, TRUE); + aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag5, tvb, suboffset, 4, TRUE); + aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag8, tvb, suboffset, 4, TRUE); + aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag9, tvb, suboffset, 4, TRUE); + aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag10, tvb, suboffset, 4, TRUE); + aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag11, tvb, suboffset, 4, TRUE); + aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag12, tvb, suboffset, 4, TRUE); + aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag13, tvb, suboffset, 4, TRUE); + aitem = proto_tree_add_item(ecat_syncflag_tree, hf_ecat_syncman_flag16, tvb, suboffset, 4, TRUE); + suboffset+=4; + } + } + } + else if ( (ecHdr.cmd == 1 || ecHdr.cmd == 4) && ecHdr.ado == 0x900 && ecHdr.len >= 16 ) + { + if (tree) + { + guint32 pDC[4]; + init_dc_measure(pDC, tvb, suboffset); + + aitem = proto_tree_add_item(ecat_sub_tree, hf_ecat_data, tvb, suboffset, ecHdr.len & 0x07ff, TRUE); + ecat_dc_tree = proto_item_add_subtree(aitem, ett_ecat_dc); + + if( subCount < 10 ) + aitem = proto_tree_add_item_hidden(ecat_sub_tree, hf_ecat_sub_data[subCount], tvb, offset + EcParserHDR_Len, ecHdr.len & 0x07ff, TRUE); + + if ( pDC[3] != 0 ) + { + proto_tree_add_uint(ecat_dc_tree, hf_ecat_dc_diff_da, tvb, suboffset, 4, pDC[3]-pDC[0]); + if( subCount < 10 ) + proto_tree_add_uint_hidden(ecat_dc_tree, hf_ecat_sub_dc_diff_da[subCount], tvb, suboffset, 4, pDC[3]-pDC[0]); + + if ( pDC[1] != 0 ) + { + proto_tree_add_uint(ecat_dc_tree, hf_ecat_dc_diff_bd, tvb, suboffset, 4, pDC[1]-pDC[3]); + if( subCount < 10 ) + proto_tree_add_uint_hidden(ecat_dc_tree, hf_ecat_sub_dc_diff_bd[subCount], tvb, suboffset, 4, pDC[1]-pDC[3]); + } + else if ( pDC[2] != 0 ) + { + proto_tree_add_uint(ecat_dc_tree, hf_ecat_dc_diff_cd, tvb, suboffset, 4, pDC[2]-pDC[3]); + if( subCount < 10 ) + proto_tree_add_uint_hidden(ecat_dc_tree, hf_ecat_sub_dc_diff_cd[subCount], tvb, suboffset, 4, pDC[2]-pDC[3]); + } + } + if ( pDC[1] != 0 ) + { + proto_tree_add_uint(ecat_dc_tree, hf_ecat_dc_diff_ba, tvb, suboffset, 4, pDC[1]-pDC[0]); + if( subCount < 10 ) + proto_tree_add_uint_hidden(ecat_dc_tree, hf_ecat_sub_dc_diff_ba[subCount], tvb, suboffset, 4, pDC[1]-pDC[0]); + if ( pDC[2] != 0 ) + { + proto_tree_add_uint(ecat_dc_tree, hf_ecat_dc_diff_cb, tvb, suboffset, 4, pDC[2]-pDC[1]); + if( subCount < 10 ) + proto_tree_add_uint_hidden(ecat_dc_tree, hf_ecat_sub_dc_diff_cb[subCount], tvb, suboffset, 4, pDC[2]-pDC[1]); + } + } + else if ( pDC[2] != 0 ) + { + proto_tree_add_uint(ecat_dc_tree, hf_ecat_dc_diff_ca, tvb, suboffset, 4, pDC[2]-pDC[0]); + if( subCount < 10 ) + proto_tree_add_uint_hidden(ecat_dc_tree, hf_ecat_sub_dc_diff_ca[subCount], tvb, suboffset, 4, pDC[2]-pDC[0]); + } + } + } + else if ( bMBox ) + { + next_tvb = tvb_new_subset(tvb, suboffset, -1, -1); + call_dissector( ecat_mailbox_handle, next_tvb, pinfo, ecat_sub_tree); + + if( tree ) + { + aitem = proto_tree_add_item(ecat_sub_tree, hf_ecat_data, tvb, offset + EcParserHDR_Len, ecHdr.len & 0x07ff, TRUE); + if( subCount < 10 ) + aitem = proto_tree_add_item_hidden(ecat_sub_tree, hf_ecat_sub_data[subCount], tvb, offset + EcParserHDR_Len, ecHdr.len & 0x07ff, TRUE); + } + } + else + { + if( tree ) + { + aitem = proto_tree_add_item(ecat_sub_tree, hf_ecat_data, tvb, suboffset, ecHdr.len & 0x07ff, TRUE); + switch ( len ) + { + case 1: + g_snprintf ( szText, nMax, "(0x%x)", tvb_get_guint8(tvb, suboffset)); + proto_item_append_text(aitem, szText); + break; + case 2: + g_snprintf ( szText, nMax, "(0x%x)", tvb_get_letohs(tvb, suboffset)); + proto_item_append_text(aitem, szText); + break; + case 4: + g_snprintf ( szText, nMax, "(0x%x)", tvb_get_letohl(tvb, suboffset)); + proto_item_append_text(aitem, szText); + break; + } + if( subCount < 10 ) + aitem = proto_tree_add_item_hidden(ecat_sub_tree, hf_ecat_sub_data[subCount], tvb, offset + EcParserHDR_Len, ecHdr.len & 0x07ff, TRUE); + } + } + + if( tree ) + { + aitem = proto_tree_add_item(ecat_sub_tree, hf_ecat_cnt, tvb, offset + EcParserHDR_Len + len , 2, TRUE); + if( subCount < 10 ) + aitem = proto_tree_add_item_hidden(ecat_sub_tree, hf_ecat_sub_cnt[subCount], tvb, offset + EcParserHDR_Len + len , 2, TRUE); + } + + if ( (ecHdr.len&0x8000) == 0 ) + break; + + offset+=subsize; + subCount++; + } +} + + +void proto_register_ecat(void) +{ + static hf_register_info hf[] = + { + { &hf_ecat_sub, + { "Sub Frame", "ecat.sub", FT_BYTES, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_header, + { "Header", "ecat.header", + FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_data[0], + { "Data ", "ecat.sub1.data", + FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_data[1], + { "Data ", "ecat.sub2.data", + FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_data[2], + { "Data ", "ecat.sub3.data", + FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_data[3], + { "Data ", "ecat.sub4.data", + FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_data[4], + { "Data ", "ecat.sub5.data", + FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_data[5], + { "Data ", "ecat.sub6.data", + FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_data[6], + { "Data ", "ecat.sub7.data", + FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_data[7], + { "Data ", "ecat.sub8.data", + FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_data[8], + { "Data ", "ecat.sub9.data", + FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_data[9], + { "Data ", "ecat.sub10.data", + FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_data, + { "Data ", "ecat.data", + FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_cnt, + { "Working Cnt", "ecat.cnt", + FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_cnt[0], + { "Working Cnt", "ecat.sub1.cnt", + FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_cnt[1], + { "Working Cnt", "ecat.sub2.cnt", + FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_cnt[2], + { "Working Cnt", "ecat.sub3.cnt", + FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_cnt[3], + { "Working Cnt", "ecat.sub4.cnt", + FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_cnt[4], + { "Working Cnt", "ecat.sub5.cnt", + FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_cnt[5], + { "Working Cnt", "ecat.sub6.cnt", + FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_cnt[6], + { "Working Cnt", "ecat.sub7.cnt", + FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_cnt[7], + { "Working Cnt", "ecat.sub8.cnt", + FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_cnt[8], + { "Working Cnt", "ecat.sub9.cnt", + FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_cnt[9], + { "Working Cnt", "ecat.sub10.cnt", + FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_cmd, + { "Command ", "ecat.cmd", + FT_UINT8, BASE_HEX, VALS(EcCmd), 0x0, "", HFILL } + }, + { &hf_ecat_sub_cmd[0], + { "Command ", "ecat.sub1.cmd", + FT_UINT8, BASE_HEX, VALS(EcCmd), 0x0, "", HFILL } + }, + { &hf_ecat_sub_cmd[1], + { "Command ", "ecat.sub2.cmd", + FT_UINT8, BASE_HEX, VALS(EcCmd), 0x0, "", HFILL } + }, + { &hf_ecat_sub_cmd[2], + { "Command ", "ecat.sub3.cmd", + FT_UINT8, BASE_HEX, VALS(EcCmd), 0x0, "", HFILL } + }, + { &hf_ecat_sub_cmd[3], + { "Command ", "ecat.sub4.cmd", + FT_UINT8, BASE_HEX, VALS(EcCmd), 0x0, "", HFILL } + }, + { &hf_ecat_sub_cmd[4], + { "Command ", "ecat.sub5.cmd", + FT_UINT8, BASE_HEX, VALS(EcCmd), 0x0, "", HFILL } + }, + { &hf_ecat_sub_cmd[5], + { "Command ", "ecat.sub6.cmd", + FT_UINT8, BASE_HEX, VALS(EcCmd), 0x0, "", HFILL } + }, + { &hf_ecat_sub_cmd[6], + { "Command ", "ecat.sub7.cmd", + FT_UINT8, BASE_HEX, VALS(EcCmd), 0x0, "", HFILL } + }, + { &hf_ecat_sub_cmd[7], + { "Command ", "ecat.sub8.cmd", + FT_UINT8, BASE_HEX, VALS(EcCmd), 0x0, "", HFILL } + }, + { &hf_ecat_sub_cmd[8], + { "Command ", "ecat.sub9.cmd", + FT_UINT8, BASE_HEX, VALS(EcCmd), 0x0, "", HFILL } + }, + { &hf_ecat_sub_cmd[9], + { "Command ", "ecat.sub10.cmd", + FT_UINT8, BASE_HEX, VALS(EcCmd), 0x0, "", HFILL } + }, + { &hf_ecat_idx, + { "Index ", "ecat.idx", + FT_UINT8, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_sub_idx[0], + { "Index ", "ecat.sub1.idx", + FT_UINT8, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_sub_idx[1], + { "Index ", "ecat.sub2.idx", + FT_UINT8, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_sub_idx[2], + { "Index ", "ecat.sub3.idx", + FT_UINT8, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_sub_idx[3], + { "Index ", "ecat.sub4.idx", + FT_UINT8, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_sub_idx[4], + { "Index ", "ecat.sub5.idx", + FT_UINT8, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_sub_idx[5], + { "Index ", "ecat.sub6.idx", + FT_UINT8, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_sub_idx[6], + { "Index ", "ecat.sub7.idx", + FT_UINT8, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_sub_idx[7], + { "Index ", "ecat.sub8.idx", + FT_UINT8, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_sub_idx[8], + { "Index ", "ecat.sub9.idx", + FT_UINT8, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_sub_idx[9], + { "Index ", "ecat.sub10.idx", + FT_UINT8, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_adp, + { "Slave Addr ", "ecat.adp", + FT_UINT16, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_sub_adp[0], + { "Slave Addr ", "ecat.sub1.adp", + FT_UINT16, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_sub_adp[1], + { "Slave Addr ", "ecat.sub2.adp", + FT_UINT16, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_sub_adp[2], + { "Slave Addr ", "ecat.sub3.adp", + FT_UINT16, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_sub_adp[3], + { "Slave Addr ", "ecat.sub4.adp", + FT_UINT16, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_sub_adp[4], + { "Slave Addr ", "ecat.sub5.adp", + FT_UINT16, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_sub_adp[5], + { "Slave Addr ", "ecat.sub6.adp", + FT_UINT16, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_sub_adp[6], + { "Slave Addr ", "ecat.sub7.adp", + FT_UINT16, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_sub_adp[7], + { "Slave Addr ", "ecat.sub8.adp", + FT_UINT16, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_sub_adp[8], + { "Slave Addr ", "ecat.sub9.adp", + FT_UINT16, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_sub_adp[9], + { "Slave Addr ", "ecat.sub10.adp", + FT_UINT16, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_ado, + { "Offset Addr", "ecat.ado", + FT_UINT16, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_sub_ado[0], + { "Offset Addr", "ecat.sub1.ado", + FT_UINT16, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_sub_ado[1], + { "Offset Addr", "ecat.sub2.ado", + FT_UINT16, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_sub_ado[2], + { "Offset Addr", "ecat.sub3.ado", + FT_UINT16, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_sub_ado[3], + { "Offset Addr", "ecat.sub4.ado", + FT_UINT16, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_sub_ado[4], + { "Offset Addr", "ecat.sub5.ado", + FT_UINT16, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_sub_ado[5], + { "Offset Addr", "ecat.sub6.ado", + FT_UINT16, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_sub_ado[6], + { "Offset Addr", "ecat.sub7.ado", + FT_UINT16, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_sub_ado[7], + { "Offset Addr", "ecat.sub8.ado", + FT_UINT16, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_sub_ado[8], + { "Offset Addr", "ecat.sub9.ado", + FT_UINT16, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_sub_ado[9], + { "Offset Addr", "ecat.sub10.ado", + FT_UINT16, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_lad, + { "Log Addr ", "ecat.lad", + FT_UINT32, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_sub_lad[0], + { "Log Addr ", "ecat.sub1.lad", + FT_UINT32, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_sub_lad[1], + { "Log Addr ", "ecat.sub2.lad", + FT_UINT32, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_sub_lad[2], + { "Log Addr ", "ecat.sub3.lad", + FT_UINT32, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_sub_lad[3], + { "Log Addr ", "ecat.sub4.lad", + FT_UINT32, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_sub_lad[4], + { "Log Addr ", "ecat.sub5.lad", + FT_UINT32, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_sub_lad[5], + { "Log Addr ", "ecat.sub6.lad", + FT_UINT32, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_sub_lad[6], + { "Log Addr ", "ecat.sub7.lad", + FT_UINT32, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_sub_lad[7], + { "Log Addr ", "ecat.sub8.lad", + FT_UINT32, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_sub_lad[8], + { "Log Addr ", "ecat.sub9.lad", + FT_UINT32, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_sub_lad[9], + { "Log Addr ", "ecat.sub10.lad", + FT_UINT32, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_len, + { "Length ", "ecat.len", + FT_UINT16, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_int, + { "Interrupt ", "ecat.int", + FT_UINT16, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_syncman, + { "SyncManager", "ecat.syncman", + FT_BYTES, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_syncman_start, + { "Start Addr", "ecat.syncman.start", + FT_UINT16, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_syncman_len, + { "SM Length ", "ecat.syncman.len", + FT_UINT16, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_syncman_flags, + { "SM Flags ", "ecat.syncman.flags", + FT_UINT32, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_syncman_flag0, + { "SM Flag0", "ecat.syncman_flag0", + FT_BOOLEAN, 32, TFS(&tfs_ecat_syncman_flag0), 0x00000001, + "", HFILL } + }, + { &hf_ecat_syncman_flag1, + { "SM Flag1", "ecat.syncman_flag1", + FT_BOOLEAN, 32, TFS(&tfs_ecat_syncman_flag1), 0x00000002, + "", HFILL } + }, + { &hf_ecat_syncman_flag2, + { "SM Flag2", "ecat.syncman_flag2", + FT_BOOLEAN, 32, TFS(&tfs_ecat_syncman_flag2), 0x00000004, + "", HFILL } + }, + { &hf_ecat_syncman_flag4, + { "SM Flag4", "ecat.syncman_flag4", + FT_BOOLEAN, 32, TFS(&tfs_ecat_syncman_flag4), 0x00000010, + "", HFILL } + }, + { &hf_ecat_syncman_flag5, + { "SM Flag5", "ecat.syncman_flag5", + FT_BOOLEAN, 32, TFS(&tfs_ecat_syncman_flag5), 0x00000020, + "", HFILL } + }, + { &hf_ecat_syncman_flag8, + { "SM Flag8", "ecat.syncman_flag8", + FT_BOOLEAN, 32, TFS(&tfs_ecat_syncman_flag8), 0x00000100, + "", HFILL } + }, + { &hf_ecat_syncman_flag9, + { "SM Flag9", "ecat.syncman_flag9", + FT_BOOLEAN, 32, TFS(&tfs_ecat_syncman_flag9), 0x00000200, + "", HFILL } + }, + { &hf_ecat_syncman_flag10, + { "SM Flag10", "ecat.syncman_flag10", + FT_BOOLEAN, 32, TFS(&tfs_ecat_syncman_flag10), 0x00000400, + "", HFILL } + }, + { &hf_ecat_syncman_flag11, + { "SM Flag11", "ecat.syncman_flag11", + FT_BOOLEAN, 32, TFS(&tfs_ecat_syncman_flag11), 0x00000800, + "", HFILL } + }, + { &hf_ecat_syncman_flag12, + { "SM Flag12", "ecat.syncman_flag12", + FT_BOOLEAN, 32, TFS(&tfs_ecat_syncman_flag12), 0x00001000, + "", HFILL } + }, + { &hf_ecat_syncman_flag13, + { "SM Flag13", "ecat.syncman_flag13", + FT_BOOLEAN, 32, TFS(&tfs_ecat_syncman_flag13), 0x00002000, + "", HFILL } + }, + { &hf_ecat_syncman_flag16, + { "SM Flag16", "ecat.syncman_flag16", + FT_BOOLEAN, 32, TFS(&tfs_ecat_syncman_flag16), 0x00010000, + "", HFILL } + }, + { &hf_ecat_fmmu, + { "FMMU", "ecat.fmmu", + FT_BYTES, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_fmmu_lstart, + { "Log Start ", "ecat.fmmu.lstart", + FT_UINT32, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_fmmu_llen, + { "Log Length ", "ecat.fmmu.llen", + FT_UINT16, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_fmmu_lstartbit, + { "Log StartBit ", "ecat.fmmu.lstartbit", + FT_UINT8, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_fmmu_lendbit, + { "Log EndBit ", "ecat.fmmu.lendbit", + FT_UINT8, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_fmmu_pstart, + { "Phys Start ", "ecat.fmmu.pstart", + FT_UINT8, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_fmmu_pstartbit, + { "Phys StartBit", "ecat.fmmu.pstartbit", + FT_UINT8, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_fmmu_type, + { "FMMU Type ", "ecat.fmmu.type", + FT_UINT8, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_fmmu_typeread, + { "Type", "ecat.fmmu.typeread", + FT_BOOLEAN, 8, TFS(&tfs_ecat_fmmu_typeread), 0x01, + "", HFILL } + }, + { &hf_ecat_fmmu_typewrite, + { "Type", "ecat.fmmu.typewrite", + FT_BOOLEAN, 8, TFS(&tfs_ecat_fmmu_typewrite), 0x02, + "", HFILL } + }, + { &hf_ecat_fmmu_active, + { "FMMU Active ", "ecat.fmmu.active", + FT_UINT8, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_fmmu_active0, + { "Active", "ecat.fmmu.active0", + FT_BOOLEAN, 8, TFS(&tfs_ecat_fmmu_active), 0x01, + "", HFILL } + }, + { &hf_ecat_dc_diff_da, + { "DC D-A", "ecat.dc.dif.da", + FT_UINT32, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_dc_diff_bd, + { "DC B-D", "ecat.dc.dif.bd", + FT_UINT32, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_dc_diff_cb, + { "DC C-B", "ecat.dc.dif.cb", + FT_UINT32, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_dc_diff_cd, + { "DC C-D", "ecat.dc.dif.cd", + FT_UINT32, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_dc_diff_ba, + { "DC B-A", "ecat.dc.dif.ba", + FT_UINT32, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_dc_diff_ca, + { "DC C-A", "ecat.dc.dif.ca", + FT_UINT32, BASE_DEC, NULL, 0x0, + "", HFILL } + }, + { &hf_ecat_sub_dc_diff_da[0], + { "DC D-A", "ecat.sub1.dc.dif.da", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_da[1], + { "DC D-A", "ecat.sub2.dc.dif.da", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_da[2], + { "DC D-A", "ecat.sub3.dc.dif.da", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_da[3], + { "DC D-A", "ecat.sub4.dc.dif.da", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_da[4], + { "DC D-A", "ecat.sub5.dc.dif.da", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_da[5], + { "DC D-A", "ecat.sub6.dc.dif.da", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_da[6], + { "DC D-A", "ecat.sub7.dc.dif.da", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_da[7], + { "DC D-A", "ecat.sub8.dc.dif.da", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_da[8], + { "DC D-A", "ecat.sub9.dc.dif.da", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_da[9], + { "DC D-A", "ecat.sub10.dc.dif.da", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + + { &hf_ecat_sub_dc_diff_bd[0], + { "DC B-C", "ecat.sub1.dc.dif.bd", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_bd[1], + { "DC B-C", "ecat.sub2.dc.dif.bd", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_bd[2], + { "DC B-C", "ecat.sub3.dc.dif.bd", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_bd[3], + { "DC B-C", "ecat.sub4.dc.dif.bd", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_bd[4], + { "DC B-C", "ecat.sub5.dc.dif.bd", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_bd[5], + { "DC B-C", "ecat.sub6.dc.dif.bd", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_bd[6], + { "DC B-C", "ecat.sub7.dc.dif.bd", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_bd[7], + { "DC B-C", "ecat.sub8.dc.dif.bd", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_bd[8], + { "DC B-C", "ecat.sub9.dc.dif.bd", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_bd[9], + { "DC B-D", "ecat.sub10.dc.dif.bd", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + + { &hf_ecat_sub_dc_diff_cb[0], + { "DC C-B", "ecat.sub1.dc.dif.cb", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_cb[1], + { "DC C-B", "ecat.sub2.dc.dif.cb", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_cb[2], + { "DC C-B", "ecat.sub3.dc.dif.cb", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_cb[3], + { "DC C-B", "ecat.sub4.dc.dif.cb", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_cb[4], + { "DC C-B", "ecat.sub5.dc.dif.cb", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_cb[5], + { "DC C-B", "ecat.sub6.dc.dif.cb", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_cb[6], + { "DC C-B", "ecat.sub7.dc.dif.cb", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_cb[7], + { "DC C-B", "ecat.sub8.dc.dif.cb", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_cb[8], + { "DC C-B", "ecat.sub9.dc.dif.cb", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_cb[9], + { "DC C-B", "ecat.sub10.dc.dif.cb", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + + { &hf_ecat_sub_dc_diff_cd[0], + { "DC C-D", "ecat.sub1.dc.dif.cd", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_cd[1], + { "DC C-D", "ecat.sub2.dc.dif.cd", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_cd[2], + { "DC C-D", "ecat.sub3.dc.dif.cd", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_cd[3], + { "DC C-D", "ecat.sub4.dc.dif.cd", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_cd[4], + { "DC C-D", "ecat.sub5.dc.dif.cd", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_cd[5], + { "DC C-D", "ecat.sub6.dc.dif.cd", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_cd[6], + { "DC C-D", "ecat.sub7.dc.dif.cd", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_cd[7], + { "DC C-D", "ecat.sub8.dc.dif.cd", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_cd[8], + { "DC C-D", "ecat.sub9.dc.dif.cd", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_cd[9], + { "DC C-D", "ecat.sub10.dc.dif.cd", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + + { &hf_ecat_sub_dc_diff_ba[0], + { "DC B-A", "ecat.sub1.dc.dif.ba", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_ba[1], + { "DC B-A", "ecat.sub2.dc.dif.ba", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_ba[2], + { "DC B-A", "ecat.sub3.dc.dif.ba", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_ba[3], + { "DC B-A", "ecat.sub4.dc.dif.ba", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_ba[4], + { "DC B-A", "ecat.sub5.dc.dif.ba", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_ba[5], + { "DC B-A", "ecat.sub6.dc.dif.ba", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_ba[6], + { "DC B-A", "ecat.sub7.dc.dif.ba", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_ba[7], + { "DC B-A", "ecat.sub8.dc.dif.ba", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_ba[8], + { "DC B-A", "ecat.sub9.dc.dif.ba", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_ba[9], + { "DC B-A", "ecat.sub10.dc.dif.ba", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + + { &hf_ecat_sub_dc_diff_ca[0], + { "DC C-A", "ecat.sub1.dc.dif.ca", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_ca[1], + { "DC C-A", "ecat.sub2.dc.dif.ca", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_ca[2], + { "DC C-A", "ecat.sub3.dc.dif.ca", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_ca[3], + { "DC C-A", "ecat.sub4.dc.dif.ca", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_ca[4], + { "DC C-A", "ecat.sub5.dc.dif.ca", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_ca[5], + { "DC C-A", "ecat.sub6.dc.dif.ca", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_ca[6], + { "DC C-A", "ecat.sub7.dc.dif.ca", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_ca[7], + { "DC C-A", "ecat.sub8.dc.dif.ca", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_ca[8], + { "DC C-A", "ecat.sub9.dc.dif.ca", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + }, + { &hf_ecat_sub_dc_diff_ca[9], + { "DC C-A", "ecat.sub10.dc.dif.ca", + FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } + } + }; + + static gint *ett[] = + { + &ett_ecat, + &ett_ecat_summary, + &ett_ecat_sub, + &ett_ecat_header, + &ett_ecat_syncman, + &ett_ecat_syncflag, + &ett_ecat_fmmu, + &ett_ecat_fmmu_type, + &ett_ecat_fmmu_active, + &ett_ecat_dc + }; + + proto_ecat_datagram = proto_register_protocol("EtherCAT Datagram", + "ECAT","ecat"); + proto_register_field_array(proto_ecat_datagram,hf,array_length(hf)); + proto_register_subtree_array(ett,array_length(ett)); +} + +/* The registration hand-off routing */ +void proto_reg_handoff_ecat(void) +{ + static dissector_handle_t ecat_handle; + + /* Register this dissector as a sub dissector to EtherCAT frame based on + ether type. */ + ecat_handle = create_dissector_handle(dissect_ecat_datagram, proto_ecat_datagram); + dissector_add("ecatf.type", 1, ecat_handle); + + ecat_mailbox_handle = find_dissector("ecat_mailbox"); +} diff --git a/plugins/ethercat/packet-ethercat-datagram.h b/plugins/ethercat/packet-ethercat-datagram.h new file mode 100644 index 0000000000..d1dccfc78a --- /dev/null +++ b/plugins/ethercat/packet-ethercat-datagram.h @@ -0,0 +1,43 @@ +/* Copyright (c) 2007 by Beckhoff Automation GmbH + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * 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. + */ +#ifndef _PACKET_ETHERCAT_DATAGRAM_ +#define _PACKET_ETHERCAT_DATAGRAM_ + +/* structure for decoding the header -----------------------------------------*/ + +/* Ensure the same data layout for all platforms */ +#pragma pack(push, 1) + +typedef struct _EcParser +{ + guint8 cmd; + guint8 idx; + guint16 adp; + guint16 ado; + guint16 len; + guint16 intr; +} EcParserHDR, *PEcParserHDR; + +#define EcParserHDR_Len sizeof(EcParserHDR) + +#pragma pack(pop) + +#endif /* _PACKET_ETHERCAT_DATAGRAM_ */ diff --git a/plugins/ethercat/packet-ethercat-frame.c b/plugins/ethercat/packet-ethercat-frame.c new file mode 100644 index 0000000000..75747c003d --- /dev/null +++ b/plugins/ethercat/packet-ethercat-frame.c @@ -0,0 +1,164 @@ +/* packet-ethercat-frame.c + * Routines for ethercat packet disassembly + * + * $Id$ + * + * Copyright (c) 2007 by Beckhoff Automation GmbH + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * 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. + */ + +/* Include files */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include "packet-ethercat-frame.h" + +void proto_reg_handoff_ethercat_frame(void); + +/* Define the Ethercat frame proto */ +static int proto_ethercat_frame = -1; + +static dissector_table_t ethercat_frame_dissector_table; +static dissector_handle_t ethercat_frame_data_handle; + +/* Define the tree for the EtherCAT frame */ +static int ett_ethercat_frame = -1; +static int hf_ethercat_frame_length = -1; +static int hf_ethercat_frame_type = -1; + +static const value_string EthercatFrameTypes[] = +{ + { 1, "ECAT", }, + { 2, "ADS", }, + { 3, "RAW-IO", }, + { 4, "NV", }, + { 0, NULL } +}; + + +/* Ethercat Frame */ +static void dissect_ethercat_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + tvbuff_t *next_tvb; + proto_item *ti; + proto_tree *ethercat_frame_tree; + gint offset = 0; + guint16 hdr_val; + guint16 protocol; + + if (check_col(pinfo->cinfo, COL_PROTOCOL)) + { + col_set_str(pinfo->cinfo, COL_PROTOCOL, "ECATF"); + } + + if (check_col(pinfo->cinfo, COL_INFO)) + { + col_clear(pinfo->cinfo, COL_INFO); + } + + if (tree) + { + ti = proto_tree_add_item(tree, proto_ethercat_frame, tvb, offset, sizeof(EtherCATFrameParserHDR), TRUE); + ethercat_frame_tree = proto_item_add_subtree(ti, ett_ethercat_frame); + + proto_tree_add_item(ethercat_frame_tree, hf_ethercat_frame_length, tvb, offset, sizeof(EtherCATFrameParserHDR), TRUE); + proto_tree_add_item(ethercat_frame_tree, hf_ethercat_frame_type, tvb, offset, sizeof(EtherCATFrameParserHDR), TRUE); + } + hdr_val = tvb_get_letohs(tvb, offset); + protocol = ((PEtherCATFrameParserHDR)(&hdr_val))->protocol; + + offset = sizeof(EtherCATFrameParserHDR); + + /* The Ethercat frame header has now been processed, allow sub dissectors to + handle the rest of the PDU. */ + next_tvb = tvb_new_subset (tvb, offset, -1, -1); + + if (!dissector_try_port (ethercat_frame_dissector_table, protocol, + next_tvb, pinfo, tree)) + { + if (check_col (pinfo->cinfo, COL_PROTOCOL)) + { + col_add_fstr (pinfo->cinfo, COL_PROTOCOL, "0x%04x", protocol); + } + /* No sub dissector wanted to handle this payload, decode it as general + data instead. */ + call_dissector (ethercat_frame_data_handle, next_tvb, pinfo, tree); + } +} + +void proto_register_ethercat_frame(void) +{ + static hf_register_info hf[] = + { + { &hf_ethercat_frame_length, + { "Length", "ecatf.length", + FT_UINT16, BASE_HEX, NULL, 0x07FF, + "", HFILL } + }, + { &hf_ethercat_frame_type, + { "Type", "ecatf.type", + FT_UINT16, BASE_HEX, VALS(EthercatFrameTypes), 0xF000, + "E88A4 Types", HFILL } + } + }; + + static gint *ett[] = + { + &ett_ethercat_frame + }; + + proto_ethercat_frame = proto_register_protocol("EtherCAT frame", + "ETHERCAT","ethercat"); + proto_register_field_array(proto_ethercat_frame,hf,array_length(hf)); + proto_register_subtree_array(ett,array_length(ett)); + + register_dissector("ecatf", dissect_ethercat_frame, proto_ethercat_frame); + + /* Define a handle (ecatf.type) for sub dissectors that want to dissect + the Ethercat frame ether type (E88A4) payload. */ + ethercat_frame_dissector_table = register_dissector_table("ecatf.type", + "EtherCAT frame type", FT_UINT8, BASE_DEC); +} + +void proto_reg_handoff_ethercat_frame(void) +{ + static dissector_handle_t ethercat_frame_handle; + + ethercat_frame_handle = create_dissector_handle(dissect_ethercat_frame, proto_ethercat_frame); + dissector_add("ethertype", ETHERTYPE_ECATF, ethercat_frame_handle); + dissector_add("udp.port", ETHERTYPE_ECATF, ethercat_frame_handle); + ethercat_frame_data_handle = find_dissector("data"); +} diff --git a/plugins/ethercat/packet-ethercat-frame.h b/plugins/ethercat/packet-ethercat-frame.h new file mode 100644 index 0000000000..a9534880b7 --- /dev/null +++ b/plugins/ethercat/packet-ethercat-frame.h @@ -0,0 +1,38 @@ +/* Copyright (c) 2007 by Beckhoff Automation GmbH + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * 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. + */ +#ifndef _PACKET_ETHERCAT_FRAME_H +#define _PACKET_ETHERCAT_FRAME_H + +/* Ensure the same data layout for all platforms */ +#pragma pack(push, 1) + +/* structure for decoding the header -----------------------------------------*/ +typedef struct _EtherCATFrameParser +{ + guint16 length : 11; + guint16 reserved : 1; + guint16 protocol : 4; +} EtherCATFrameParserHDR; +typedef EtherCATFrameParserHDR *PEtherCATFrameParserHDR; + +#pragma pack(pop) + +#endif diff --git a/plugins/ethercat/packet-ioraw.c b/plugins/ethercat/packet-ioraw.c new file mode 100644 index 0000000000..07327e0134 --- /dev/null +++ b/plugins/ethercat/packet-ioraw.c @@ -0,0 +1,135 @@ +/* packet-ioraw.c + * Routines for ethercat packet disassembly + * + * $Id$ + * + * Copyright (c) 2007 by Beckhoff Automation GmbH + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * 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. + */ + +/* Include files */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include "packet-ioraw.h" + +void proto_reg_handoff_ioraw(void); + +/* Define the ioraw proto */ +int proto_ioraw = -1; + +static int ett_ioraw = -1; + +static int hf_ioraw_summary = -1; +static int hf_ioraw_header = -1; +static int hf_ioraw_data = -1; + +/*ioraw*/ +static void IoRawSummaryFormater( char *szText, int nMax) +{ + g_snprintf ( szText, nMax, "Raw IO Data" ); +} + +static void dissect_ioraw(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + proto_item *ti; + proto_tree *ioraw_tree; + gint offset = 0; + char szText[200]; + int nMax = sizeof(szText)-1; + + guint ioraw_length = tvb_reported_length(tvb); + + if (check_col(pinfo->cinfo, COL_PROTOCOL)) + col_set_str(pinfo->cinfo, COL_PROTOCOL, "IO-RAW"); + + if (check_col(pinfo->cinfo, COL_INFO)) + col_clear(pinfo->cinfo, COL_INFO); + + + IoRawSummaryFormater(szText, nMax); + if (check_col(pinfo->cinfo, COL_INFO)) + col_append_str(pinfo->cinfo, COL_INFO, szText); + + if (tree) + { + ti = proto_tree_add_item(tree, proto_ioraw, tvb, 0, -1, TRUE); + ioraw_tree = proto_item_add_subtree(ti, ett_ioraw); + + proto_item_append_text(ti,": %s",szText); + proto_tree_add_item(ioraw_tree, hf_ioraw_header, tvb, offset, sizeof(IoRawParserHDR), TRUE); + offset+=sizeof(IoRawParserHDR); + + proto_tree_add_item(ioraw_tree, hf_ioraw_data, tvb, offset, ioraw_length - offset, TRUE); + } +} + +void proto_register_ioraw(void) +{ + static hf_register_info hf[] = + { + { &hf_ioraw_summary, + { "Summary of the IoRaw Packet", "ioraw.summary", + FT_STRING, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_ioraw_header, { "Header", "ioraw.header", + FT_NONE, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_ioraw_data, { "VarData", "ioraw.data", + FT_NONE, BASE_NONE, NULL, 0x0, + "", HFILL } + } + }; + + static gint *ett[] = + { + &ett_ioraw + }; + + proto_ioraw = proto_register_protocol("TwinCAT IO-RAW", + "IO-RAW","ioraw"); + proto_register_field_array(proto_ioraw,hf,array_length(hf)); + proto_register_subtree_array(ett,array_length(ett)); +} + +void proto_reg_handoff_ioraw(void) +{ + static dissector_handle_t ioraw_handle; + + ioraw_handle = create_dissector_handle(dissect_ioraw, proto_ioraw); + dissector_add("ecatf.type", 3, ioraw_handle); +} diff --git a/plugins/ethercat/packet-ioraw.h b/plugins/ethercat/packet-ioraw.h new file mode 100644 index 0000000000..169f889eb9 --- /dev/null +++ b/plugins/ethercat/packet-ioraw.h @@ -0,0 +1,35 @@ +/* Copyright (c) 2007 by Beckhoff Automation GmbH + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * 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. + */ +#ifndef _PACKET_IORAW_H_ +#define _PACKET_IORAW_H_ + +/* Ensure the same data layout for all platforms */ +#pragma pack(push, 1) + +/* headers are only used for size and offset calculation*/ +typedef struct _IoRawParser +{ + guint32 head; +} IoRawParserHDR, *PIoRawParserHDR; + +#pragma pack(pop) + +#endif /* _PACKET_IORAW_H_*/ diff --git a/plugins/ethercat/packet-nv.c b/plugins/ethercat/packet-nv.c new file mode 100644 index 0000000000..4b89ec5a74 --- /dev/null +++ b/plugins/ethercat/packet-nv.c @@ -0,0 +1,256 @@ +/* packet-nv.c + * Routines for ethercat packet disassembly + * + * $Id$ + * + * Copyright (c) 2007 by Beckhoff Automation GmbH + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * 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. + */ + +/* Include files */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include "packet-nv.h" + +void proto_reg_handoff_nv(void); + +/* Define the nv proto */ +int proto_nv = -1; + +static int ett_nv = -1; +static int ett_nv_header = -1; +static int ett_nv_var = -1; +static int ett_nv_varheader = -1; + +static int hf_nv_summary = -1; +static int hf_nv_header = -1; +static int hf_nv_publisher = -1; +static int hf_nv_count = -1; +static int hf_nv_cycleindex = -1; +static int hf_nv_variable = -1; +static int hf_nv_varheader = -1; +static int hf_nv_id = -1; +static int hf_nv_hash = -1; +static int hf_nv_length = -1; +static int hf_nv_quality = -1; +static int hf_nv_data = -1; + +/*nv*/ +static void NvSummaryFormater(tvbuff_t *tvb, gint offset, char *szText, int nMax) +{ + guint32 pubOffset = offset+offsetof(NvParserHDR, Publisher); + + g_snprintf ( szText, nMax, "Network Vars from %d.%d.%d.%d.%d.%d - %d Var(s)", + tvb_get_guint8(tvb, pubOffset), + tvb_get_guint8(tvb, pubOffset+1), + tvb_get_guint8(tvb, pubOffset+2), + tvb_get_guint8(tvb, pubOffset+3), + tvb_get_guint8(tvb, pubOffset+4), + tvb_get_guint8(tvb, pubOffset+5), + tvb_get_letohs(tvb, offset+offsetof(NvParserHDR, CountNV))); +} + +static void NvPublisherFormater(tvbuff_t *tvb, gint offset, char *szText, int nMax) +{ + guint32 pubOffset = offset+offsetof(NvParserHDR, Publisher); + + g_snprintf ( szText, nMax, "Publisher %d.%d.%d.%d.%d.%d", + tvb_get_guint8(tvb, pubOffset), + tvb_get_guint8(tvb, pubOffset+1), + tvb_get_guint8(tvb, pubOffset+2), + tvb_get_guint8(tvb, pubOffset+3), + tvb_get_guint8(tvb, pubOffset+4), + tvb_get_guint8(tvb, pubOffset+5)); +} + +static void NvVarHeaderFormater(tvbuff_t *tvb, gint offset, char *szText, int nMax) +{ + g_snprintf ( szText, nMax, "Variable - Id = %d, Length = %d", + tvb_get_letohs(tvb, offset+offsetof(ETYPE_88A4_NV_DATA_HEADER, Id)), + tvb_get_letohs(tvb, offset+offsetof(ETYPE_88A4_NV_DATA_HEADER, Length))); +} + +static void dissect_nv(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + proto_item *ti; + proto_tree *nv_tree, *nv_header_tree, *nv_var_tree,*nv_varheader_tree; + gint offset = 0; + char szText[200]; + int nMax = sizeof(szText)-1; + + guint nv_length = tvb_reported_length(tvb); + gint i; + + if (check_col(pinfo->cinfo, COL_PROTOCOL)) + col_set_str(pinfo->cinfo, COL_PROTOCOL, "TC-NV"); + + if (check_col(pinfo->cinfo, COL_INFO)) + col_clear(pinfo->cinfo, COL_INFO); + + NvSummaryFormater(tvb, offset, szText, nMax); + if (check_col(pinfo->cinfo, COL_INFO)) + col_append_str(pinfo->cinfo, COL_INFO, szText); + + if (tree) + { + guint16 nv_count; + + ti = proto_tree_add_item(tree, proto_nv, tvb, 0, -1, TRUE); + nv_tree = proto_item_add_subtree(ti, ett_nv); + proto_item_append_text(ti,": %s",szText); + + ti = proto_tree_add_item(nv_tree, hf_nv_header, tvb, offset, sizeof(NvParserHDR), TRUE); + + nv_header_tree = proto_item_add_subtree(ti, ett_nv_header); + + ti= proto_tree_add_item(nv_header_tree, hf_nv_publisher, tvb, offset, sizeof(guint8)*6, TRUE); + NvPublisherFormater(tvb, offset, szText, nMax); + proto_item_set_text(ti, szText); + offset+=(sizeof(guint8)*6); + + ti= proto_tree_add_item(nv_header_tree, hf_nv_count, tvb, offset, sizeof(guint16), TRUE); + nv_count = tvb_get_letohs(tvb, offset); + offset+=sizeof(guint16); + + ti= proto_tree_add_item(nv_header_tree, hf_nv_cycleindex, tvb, offset, sizeof(guint16), TRUE); + offset = sizeof(NvParserHDR); + + for ( i=0; i < nv_count; i++ ) + { + guint16 var_length = tvb_get_letohs(tvb, offset+offsetof(ETYPE_88A4_NV_DATA_HEADER, Length)); + + ti = proto_tree_add_item(nv_tree, hf_nv_variable, tvb, offset, sizeof(ETYPE_88A4_NV_DATA_HEADER)+var_length, TRUE); + NvVarHeaderFormater(tvb, offset, szText, nMax); + proto_item_set_text(ti, szText); + + nv_var_tree = proto_item_add_subtree(ti, ett_nv_var); + ti = proto_tree_add_item(nv_var_tree, hf_nv_varheader, tvb, offset, sizeof(ETYPE_88A4_NV_DATA_HEADER), TRUE); + + nv_varheader_tree = proto_item_add_subtree(ti, ett_nv_varheader); + ti = proto_tree_add_item(nv_varheader_tree, hf_nv_id, tvb, offset, sizeof(guint16), TRUE); + offset+=sizeof(guint16); + + ti = proto_tree_add_item(nv_varheader_tree, hf_nv_hash, tvb, offset, sizeof(guint16), TRUE); + offset+=sizeof(guint16); + + ti = proto_tree_add_item(nv_varheader_tree, hf_nv_length, tvb, offset, sizeof(guint16), TRUE); + offset+=sizeof(guint16); + + ti = proto_tree_add_item(nv_varheader_tree, hf_nv_quality, tvb, offset, sizeof(guint16), TRUE); + offset+=sizeof(guint16); + + ti = proto_tree_add_item(nv_var_tree, hf_nv_data, tvb, offset, var_length, TRUE); + offset+=var_length; + } + } +} + +void proto_register_nv(void) +{ + static hf_register_info hf[] = + { + { &hf_nv_summary, + { "Summary of the Nv Packet", "tc_nv.summary", + FT_BYTES, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_nv_header, { "Header", "tc_nv.header", + FT_NONE, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_nv_publisher, { "Publisher", "tc_nv.publisher", + FT_BYTES, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_nv_count, { "Count", "tc_nv.count", + FT_UINT16, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_nv_cycleindex, { "CycleIndex", "tc_nv.cycleindex", + FT_UINT16, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_nv_variable, { "Variable", "tc_nv.variable", + FT_BYTES, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_nv_varheader, { "VarHeader", "tc_nv.varheader", + FT_NONE, BASE_NONE, NULL, 0x0, + "", HFILL } + }, + { &hf_nv_id, { "Id", "tc_nv.id", + FT_UINT16, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_nv_hash, { "Hash", "tc_nv.hash", + FT_UINT16, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_nv_length, { "Length", "tc_nv.length", + FT_UINT16, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_nv_quality, { "Quality", "tc_nv.quality", + FT_UINT16, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + { &hf_nv_data, { "Data", "tc_nv.data", + FT_BYTES, BASE_HEX, NULL, 0x0, + "", HFILL } + }, + }; + + static gint *ett[] = + { + &ett_nv, + &ett_nv_header, + &ett_nv_var, + &ett_nv_varheader + }; + + proto_nv = proto_register_protocol("TwinCAT NV", + "TC-NV","tc_nv"); + proto_register_field_array(proto_nv,hf,array_length(hf)); + proto_register_subtree_array(ett,array_length(ett)); +} + +void proto_reg_handoff_nv(void) +{ + static dissector_handle_t nv_handle; + + nv_handle = create_dissector_handle(dissect_nv, proto_nv); + dissector_add("ecatf.type", 4, nv_handle); +} diff --git a/plugins/ethercat/packet-nv.h b/plugins/ethercat/packet-nv.h new file mode 100644 index 0000000000..a25b79e566 --- /dev/null +++ b/plugins/ethercat/packet-nv.h @@ -0,0 +1,47 @@ +/* Copyright (c) 2007 by Beckhoff Automation GmbH + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * 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. + */ + +#ifndef _PACKET_NV_H_ +#define _PACKET_NV_H_ + +/* Ensure the same data layout for all platforms*/ +#pragma pack(push, 1) + +typedef struct _ETYPE_88A4_NV_DATA_HEADER +{ + guint16 Id; + guint16 Hash; + guint16 Length; + guint16 Quality; +} ETYPE_88A4_NV_DATA_HEADER, *PETYPE_88A4_NV_DATA_HEADER; + + +typedef struct _ETYPE_88A4_NV_HEADER +{ + guint8 Publisher[6]; + guint16 CountNV; + guint16 CycleIndex; + guint16 Reserved; +} ETYPE_88A4_NV_HEADER, *PETYPE_88A4_NV_HEADER, NvParserHDR, *PNvParserHDR; + +#pragma pack(pop) + +#endif /* _PACKET_NV_H_*/ diff --git a/plugins/ethercat/plugin.rc.in b/plugins/ethercat/plugin.rc.in new file mode 100644 index 0000000000..72b4de0775 --- /dev/null +++ b/plugins/ethercat/plugin.rc.in @@ -0,0 +1,34 @@ +#include "winver.h" + +VS_VERSION_INFO VERSIONINFO + FILEVERSION @RC_MODULE_VERSION@ + PRODUCTVERSION @RC_VERSION@,0 + FILEFLAGSMASK 0x0L +#ifdef _DEBUG + FILEFLAGS VS_FF_PRERELEASE+VS_FF_DEBUG +#else + FILEFLAGS VS_FF_PRERELEASE +#endif + FILEOS VOS_NT_WINDOWS32 + FILETYPE VFT_DLL +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "The Wireshark developer community, http://www.wireshark.org/\0" + VALUE "FileDescription", "@PACKAGE@ dissector\0" + VALUE "FileVersion", "@MODULE_VERSION@\0" + VALUE "InternalName", "@PACKAGE@ @MODULE_VERSION@\0" + VALUE "LegalCopyright", "Copyright © 1998 Gerald Combs , Gilbert Ramirez and others\0" + VALUE "OriginalFilename", "@PLUGIN_NAME@.dll\0" + VALUE "ProductName", "Wireshark\0" + VALUE "ProductVersion", "@VERSION@\0" + VALUE "Comments", "Build with @MSVC_VARIANT@\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END