티스토리 툴바


posted by ppiazi 2011/03/21 15:14
Creative Commons License
Creative Commons License

결론 : GUID를 재시작할때마다 Unique하게 만들자!!


Relevant versions: RTI Data Distribution Service 4.x


For dynamic discovery to work properly, RTI Data Distribution Service relies on a "globally unique identifier" (GUID) that uniquely identifies each instance of a participant in the network. By default, RTI Data Distribution Service will automatically choose values for the host ID and app ID that will generate unique GUIDs for different participant instances. This is documented in the WIRE_PROTOCOL QosPolicy (See [DomainParticipantQoS]).

Currently, RTI Data Distribution Service bases the host ID on the IPv4 address of the host (although this might change in the future). The app ID is calculated from the process (or task) ID and a counter that is incremented per new participant created in the process.

Note that the app ID is not based upon the participant index. When restarting an application with the same participant index, the application should announce itself as a new participant (with a different GUID) on the network, so other participants can respond with their configuration info. Therefore, RTI Data Distribution Service will assign it a different app ID, even if the participant uses the same participant index (and ports). After all, it is a different instance of this participant. If the app ID were unchanged, remote participants would simply interpret the announcement as an "I am still alive" message and not reply with their own information.

On many real-time operating systems, and even on some non-real-time operating system, when a node is rebooted, and applications are automatically started, process ids are deterministically assigned. That is, when the system restarts or if an application dies and is restarted, the application will be reassigned the same process or task ID. If this occurs before other applications in the system can detect that the previous application has died, the new application will appear to be the same as the previous application due to their identical GUIDs.

In such cases, to prevent duplicate GUIDs, you can set the host ID and/or app ID manually using the WIRE_PROTOCOL QosPolicy before creating the participant.

In publisher_main):

struct DDS_DomainParticipantQos participant_qos;

...

// Initialize participant_qos with default values

DDS_DomainParticipantFactory_get_default_participant_qos(

 

               DDS_TheParticipantFactory,

               &participant_qos);

 

// set the rtps host and/or app id.

participant_qos.wire_protocol.rtps_host_id = aRandomOrIncrementingValue;

participant_qos.wire_protocol.rtps_app_id = aRandomOrIncrementingValue;

 

// Create participant using modified DDS_DomainParticipantQos

participant = DDS_DomainParticipantFactory_create_participant(

 

      DDS_TheParticipantFactory, domainId, &participant_qos,

      NULL /* listener */, DDS_STATUS_MASK_NONE);

 

When the application is restarted, RTI DDS assigns it a different host and app ID -- in which case the GUID becomes unique and other applications will recognize this as a new instance of an application and will exchange discovery information.

 

Displaying the GUID

One can observe the GUID using RTI Protocol Analyzer with Wireshark or by turning on high verbosity output level for both the subscriber and publisher.

 

Set the NDDS_Config_LogCategory to NDDS_CONFIG_LOG_CATEGORY_ENTITIES to log messages pertaining to local and remote entities and to the discovery process.

 

NDDS_Config_Logger_set_verbosity_by_category(        NDDS_Config_Logger_get_instance(), NDDS_CONFIG_LOG_CATEGORY_ENTITIES,       NDDS_CONFIG_LOG_VERBOSITY_STATUS_ALL);

 

Look for the following line in output from both subscriber and publisher applications:

DISCDynamicParticipantSelfAnnouncer_enable:announcing participant: 0x7F000001,0x00100001,0x000001C1

 

The GUID is composed of three parts:

1. host ID: identifies the host on which the participant is running

2. app ID: uniquely identifies a particular instance of a participant on this host

3. object ID: has a fixed value in the case of a participant. Will be used to uniquely identify entities (pubs, subs) that belong to the participant.
저작자 표시 비영리 동일 조건 변경 허락
posted by ppiazi 2011/03/14 21:01
Creative Commons License
Creative Commons License

특정 IP를 가지는 NIC에서 RTI DDS를 사용하기 위한 방법이다. Method 2번으로 해결함.


[Applies to RTI Data Distribution Service 4.x]

On a machine with multiple NICs, you can restrict RTI Data Distribution Service traffic to a subset of the available network interfaces (NICs). For example, this would allow you to segregate DDS traffic from other application-specific data.

Selecting specific NICs involves configuring a transport plugin. For details on how this is done, see the HTML documentation under Modules, Programming How-To's, Transport Use Cases. The relevant section is called "Changing the properties of the automatically registered builtin transports."

The following members of the NDDS_Transport_Property_t struct should be set:

* allow_interfaces_list and allow_interfaces_list_length (to use only the specified interfaces)

or

* deny_interfaces_list and deny_interfaces_list_length (to disable only the specified interfaces).

The allow/deny lists are arrays of strings which are used to match the IP address of the interfaces (e.g., "10.10.1.123"). The * wildcard can be used to match a pattern of addresses. For example, to choose the NIC that is on the 10.10.0.0/16 network, use the string "10.10.*" to select the NIC. Alternatively, on most platforms the name of the interface may be used (e.g., "eth0" for the first Ethernet interface on a Linux system).

 

It should be noted that the allow and deny lists determine:

  • The set of interfaces used for the input ports.
  • The set of interfaces that multicast will use for output (if multicast is available on those interfaces).
  • The set of interfaces that will be put in the participant builtin topic data (which informs the remote participant(s) how to contact this participant).

The allow and deny lists have NO effect on unicast output. (This is controlled by the operating system routing table.)

There are three methods for selecting a subset of interfaces:

1.     Use the transport settings

2.     Use the DomainParticipant's Property QoS

3.     Use an XML QoS file

Older versions don't support all three -- see below for which methods are applicable for particular RTI versions.

 

Method 1 - Use the Transport Settings (all 4.x versions)

 

1. Before creating the DomainParticipant, make sure the DomainParticipant will be created in a disabled state. For example, in C++:

    

    retcode = DDSTheParticipantFactory->get_qos(factory_qos);

  factory_qos.entity_factory.autoenable_created_entities = DDS_BOOLEAN_FALSE;

  retcode = DDSTheParticipantFactory->set_qos(factory_qos);

 

2. Get the builtin transports and set the allowed interfaces.

 

3. Call set_builtin_transport_property() before the DomainParticipant is enabled. For example, in C++:

  #define NIC_IP "10.10.*"

  struct NDDS_Transport_UDPv4_Property_t property = NDDS_TRANSPORT_UDPV4_PROPERTY_DEFAULT;
             
  if (NDDSTransportSupport::get_builtin_transport_property
     (participant, DDS_TRANSPORTBUILTIN_UDPv4,
     (struct NDDS_Transport_Property_t&)property) != DDS_RETCODE_OK)
  {
      printf("***Error: get builtin transport property\n");                           
  }   

  /* Set the allowed interface(s) */
  property.parent.allow_interfaces_list = new char*[1];
  property.parent.allow_interfaces_list[0] = new char[strlen(NIC_IP)+1];

  strcpy(property.parent.allow_interfaces_list[0], NIC_IP);
  property.parent.allow_interfaces_list_length = 1;

  if (NDDSTransportSupport::set_builtin_transport_property
             (participant, DDS_TRANSPORTBUILTIN_UDPv4,
             (struct NDDS_Transport_Property_t&)property) != DDS_RETCODE_OK)
  {
    printf("***Error: set builtin transport property\n");                          
  }

    To deny a subset of interfaces, you would do exactly the same as above, but use
    "deny_interfaces_list" instead of "allow_interfaces_list".


4. Enable the DomainParticipant:

  retcode = participant->enable();

    The allow/deny lists are only used during transport initialization; after the DomainParticipant has been enabled, you may dispose of the memory allocated for them.


Method 2 - Use the DomainParticipant's Property QoS  (versions 4.2 and higher)

 

This method involves using the Property QosPolicy to modify the UDP builtin transport properties.

(The Property QoS policy is available in RTI Data Distribution Service 4.2 and higher.) This method is easier than Method 1 because you do not need to create the DomainParticipant disabled first.

 

1. Get the participant_qos and add the properties you want to modify to the QoS:

 

  #define NIC_IP   "10.10.*"

  #define NIC_IP_2 "10.15.*" 

 

  retcode = DDSTheParticipantFactory->get_default_participant_qos(domainparticipant_qos);

  if (retcode != DDS_RETCODE_OK) {

      puts("Error, impossible get default participant qos");

      return NULL;

  }

 

  retcode = DDSPropertyQosPolicyHelper::add_property (

              domainparticipant_qos.property,

              "dds.transport.UDPv4.builtin.parent.deny_interfaces",

              NIC_IP_2, DDS_BOOLEAN_FALSE);

 

  if (retcode != DDS_RETCODE_OK) {

      printf("Error, impossible add property1");

      return NULL;

  }

 

    retcode = DDSPropertyQosPolicyHelper::add_property(
              domainparticipant_qos.property,
              "dds.transport.UDPv4.builtin.parent.allow_interfaces"
,
                           
NIC_IP, DDS_BOOLEAN_FALSE);

   
if (retcode != DDS_RETCODE_OK) {
      printf("Error, impossible add property2");
      return NULL;
  }

2. Create the DomainParticipant.

 

Method 3 - Use an XML QoS Profile (version 4.3 and higher)


This method uses an XML QoS profile to configure the DomainParticipant and transport properties.

 

<dds>
  <qos_library name="test">
    <qos_profile name="UDPv4_properties">
      <participant_qos>
        <property>   
          <value>

            <element>

              <name>dds.transport.UDPv4.builtin.parent.deny_interfaces</name>

              <value>10.15.*</value>

            </element> 

            <element>
              <name>dds.transport.UDPv4.builtin.parent.allow_interfaces</name>
              <value>10.10.*,192.168.*</value>

            </element>            
          </value>
        </property>
      </participant_qos>
    </qos_profile>
  </qos_library>
</dds>


If you are using RTI Data Distribution Service 4.3e, you must call DDSTheParticipantFactory->load_profiles() before

creating the DomainParticipant with a profile.


When using RTI Data Distribution Service 4.4 and higher, the XML file can be automatically loaded.

If NDDS_QOS_PROFILES.xml is in the $NDDSHOME/resource/xml directory, it will be automatically loaded.

Similarly, if USER_QOS_PROFILES.xml is in the working directory, it will be automatically loaded.

See the User’s Manual for more details on XML file loading.


When using version RTI Data Distribution Service 4.4 and higher, place the attached USER_QOS_PROFILES.xml file

in the working directory.

저작자 표시 비영리 동일 조건 변경 허락
posted by ppiazi 2011/01/06 16:47
Creative Commons License
Creative Commons License
링크 장비 상태에 따라 GW를 동적으로 변경하기 위하여 발행하는 ARP 프로토콜.

자세한 설명은 아래의 링크를 참고한다.

VxWorks로의 구현은 다음 포스트로... 졸립다. =_=
저작자 표시 비영리 동일 조건 변경 허락
posted by ppiazi 2010/11/15 21:29
Creative Commons License
Creative Commons License
RTI DDS를 Vxworks에서 구동할 때 쓰레드 생성 기본 설정으로 VX_FP_TASK가 빠져있어 해당 Listener에서 실수 연산시 예기치 못한 에러가 발생할 수 있다. 이에 아래의 옵션을 켜주어야 한다.

C:\Program Files\RTI\ndds.4.5c\include\ndds\osapi 폴더의 osapi_thread.h 을 열어 아래를 수정한다.

/* #define RTI_OSAPI_THREAD_OPTION_DEFAULT     0x00 */
#define RTI_OSAPI_THREAD_OPTION_DEFAULT     0x01 /* modified by Joohyun Lee 2010.11.15 */

와 같이 수정을 한다.

QoS를 설정하는 더 좋은 방법이 있겠지만.. 일단은 이렇게 땜빵을 ㅎ;
저작자 표시 비영리 동일 조건 변경 허락
posted by ppiazi 2010/10/13 20:40
Creative Commons License
Creative Commons License

출처 : http://nmap.org/book/tcpip-ref.html

프로젝트를 진행하다가 IP/UDP 헤더를 조작해야하는 변태스러운 짓(?!)을 하고 있다.

TCP까지 열었으면 까무러칠뻔 ㅎㅎ



IP_Header.png

 

 

 

 

UDP_Header.png

이 글은 스프링노트에서 작성되었습니다.

저작자 표시 비영리 동일 조건 변경 허락
posted by ppiazi 2010/09/04 14:24
Creative Commons License
Creative Commons License
1. 예제 파일 작성
 rtiddsgen -language C++ -example ppc604Vx6.6gcc4.1.2 HelloWorld.idl -ppDisable

 생성된 예제파일들을 .h와 .cxx 파일들을 DKM 프로젝트로 생성된 폴더에 복사를 하여 사용한다.

2. DKM 프로젝트 생성 및 환경설정
2.1 VxWorks Image Project 생성하여 다음의 설정을 활성화한다.
Components
  C++ components >> standard library
                          >> C++ compiler support routines
                          >> C++ core runtime
                          >> run static initializers

2.2 Downloadable Kernel Module 프로젝트를 생성하여, Build Properties를 다음과 같이 설정한다.
Build Macro 탭
  DEFINES 에 -DRTI_VXWORKS 추가
  CC_ARCH_SPEC 에 -mlongcall 추가
  LIBPATH에 -L/{RTI DDS 라이브러리 폴더} 추가
  LIBS에 -nddscppz -nddscz -lnddscorez 추가
 
Build Paths 탭
  $(NDDSHOME)/include 와 $(NDDSHOME)/include/ndds 의 패쓰를 아래와 같이 추가.
  -IC:/Program Files/RTI/ndds.4.5c/include
  -IC:/Program Files/RTI/ndds.4.5c/include/ndds

저작자 표시 비영리 동일 조건 변경 허락
posted by ppiazi 2010/07/18 12:13
Creative Commons License
Creative Commons License
아래의 레퍼런스를 참고하였다.

dissector를 built-in으로 구성할지 plugin으로 구성할지 선택을 할 수가 있으나, 이곳에서는 plugin형식으로 구성하는 방법에 대하여 알아보도록 한다.

Example 1) Dissector 초기화
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include <epan/packet.h>

#define FOO_PORT 1234

static int proto_foo = -1;


void
proto_register_foo(void)
{
    proto_foo = proto_register_protocol (
        "FOO Protocol",    /* name       */
        "FOO",        /* short name */
        "foo"        /* abbrev     */
        );
}

예제에서는 UDP와 FOO_PORT 에 해당하는 패킷을 분석하는 dissector를 구성할 예정이다.

dissector를 등록하는데 호출하는 첫번째 함수는 proto_register_protocol 함수이다. 세가지 인자를 받아 dissector의 구분자를 반환한다.  인자로 받아들이는 문자열의 사용은 아래와 같다.
  • Full Name, Short Name는 "Preferences"와 "Enabled protocols"의 다이얼로그에 사용됨.
  • Abbreviation Name는 wireshark 필터에 사용됨.
Example 2) Dissector Handoff

void
proto_reg_handoff_foo(void)
{
    static dissector_handle_t foo_handle;

    foo_handle = create_dissector_handle(dissect_foo, proto_foo); //< 1
    dissector_add("udp.port", FOO_PORT, foo_handle); //< 2
}


dissector를 초기화를 수행한다.(위의 과정에서는 프로토콜을 등록하였었다.) 등록한 프로토콜와 처리를 위한 dissector 핸들러를 연계하여 dissector 핸들을 생성한다.(1) 그 후 생성된 핸들에 UDP 포트 넘버와 관련지어 wireshark로 하여금 해당하는 패킷을 처리할 수 있도록 등록한다.(2)

패킷을 분석하기 위한 dissector 핸들러 함수는 아래와 같이 구성된다.

Example 3) Dissection

static void
dissect_foo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "FOO");
    /* Clear out stuff in the info column */
    col_clear(pinfo->cinfo,COL_INFO);
}


컴파일을 위해 필요한 준비물
  • Makefile.am - This is the UNIX/Linux makefile template
  • Makefile.common - This contains the file names of this plugin
  • Makefile.nmake - This contains the Wireshark plugin makefile for Windows
  • moduleinfo.h - This contains plugin version info
  • moduleinfo.nmake - This contains DLL version info for Windows
  • packet-foo.c - This is your dissector source
  • plugin.rc.in - This contains the DLL resource template for Windows 

그 이후엔 해당 폴더에서(윈도우의 경우)
nmake -f Makefile.nmake distclean
nmake -f Makefile.nmake all

로 빌드하면 된다.


저작자 표시 비영리 동일 조건 변경 허락
posted by ppiazi 2010/07/16 17:02
Creative Commons License
Creative Commons License
[length : 4 bytes][type : 1byte][message : length - 1][null]
와 같은 포맷을 같는 프로토콜을 생성하는 파이썬 코드를 만들어서 dissector를 테스트 하였다.

AMIN_Server.py
from socket import *

def AMIN_Server():
    svrsock = socket(AF_INET, SOCK_DGRAM)
    print "haha"
    svrsock.bind(('', 999))

    while True:
        print "Waiting ..."

        s, addr = svrsock.recvfrom(1024)

        print s
        print addr

if __name__ == "__main__":
    AMIN_Server()

AMIN_Client.py
import struct
from socket import *

def AMIN_Client():
    clnsock = socket(AF_INET, SOCK_DGRAM)

    for i in range(0,100):
        t_str = "Hello World"
        t_pattern = "IB%ds" %(len(t_str) + 1)       
        t_packet = struct.pack(t_pattern, len(t_str), 1, t_str)
        clnsock.sendto(t_packet, ("10.29.4.143", 999))

if __name__ == "__main__":
    AMIN_Client()


저작자 표시 비영리 동일 조건 변경 허락
posted by ppiazi 2010/07/12 23:31
Creative Commons License
Creative Commons License

http://wireshark.askapache.com/docs/wsdg_html_chunked/ChSetupWin32.html#ChSetupPython

 

Wireshark 빌드는 아래의 링크를 확인한다.

 

위의 예제에 있는 것을 빌드하면 아래와 같이 VERSIONINFO filed 어쩌구 에러가 난다. 아마 0.99 버전대의 플러그인 예제라 그런거일 수도...

wireshark_dissector_err.jpg

 

아무튼 이 에러 해결을 위해 배포판의 plugins 아래의 아무 폴더나 들어가서 plugin.rc.in 파일을 amin 폴더에 덮어쓴다.

그 후

  1. nmake -f Makefile.nmake distclean
  2. nmake -f Makefile.nmake all

을 수행하면 빌드가 성공한다. Good!

wireshark_dissector_success.jpg

 

생성된 amin.dll 파일을 wireshark가 설치된 폴더 아래의 plugins\1.4.0rc1 에 넣으면 된다.

나의 경우는 커스텀 빌드한 wireshark를 사용한 것이 아니라, rc1 버전을 받아 설치하여, 경로가 아래와 같다.

  1. C:\Program Files\Wireshark\plugins

 

그 후 wireshark를 구동하여 About >> plugin을 확인하면, 해당 dissector가 로드된것을 확인할 수 있다.

 

about.jpg

 

이 글은 스프링노트에서 작성되었습니다.

저작자 표시 비영리 동일 조건 변경 허락
posted by ppiazi 2010/07/10 00:10
Creative Commons License
Creative Commons License

빌드에 참고한 URL

http://wireshark.askapache.com/docs/wsdg_html_chunked/ChSetupWin32.html#ChSetupPython

  1. Visual Studio 2008 설치

    • 회사가 구입한 버전으로 설치.. 느낌상으로는 2005빼구 다 될것 같다 ㅎ
  2. cygwin 설치 다음의 패키지는 반드시 포함

    • 반드시 포함해야하는 패키지

      • Archive/unzip
        Devel/bison
        Devel/flex
        Interpreters/perl
        Utils/patch
        Web/wget
    • 내가 사용한 버전 1.7.5
  3. python2.6설치

  4. wireshark 최신소스 받기 : tortoisesvn을 이용함

  5. cmd.exe를 실행하여 콘솔을 연다! 역시 빌드는 콘솔에서 빌드해야 제맛!

    • 비주얼 스튜디오 콘솔 빌드 환경을 가져오기 위해 아래의 배치파일을 실행한다.
    • C:\Program Files\Microsoft Visual Studio 9.0\VC\bin\vcvars32.bat

      • 폴더로 이동해서 vcvars32.bat를 실행시키던가
      • 콘솔에서 "C:\Program Files\Microsoft Visual Studio 9.0\VC\bin\vcvars32.bat" 이렇게 따옮표로 copy & paste 한후 실행 하던가
  6. nmake -f Makefile.nmake verify_tools 실행

    • 빌드에 필요한 툴들이 있는지 판단하는 과정. 알아서 잘 찾는다. 기특한 것!
    • 아무 무리없이 잘 넘어간다.
  7. nmake -f Makefile.nmake setup 실행

    • 에러가 발생할때도 있구 안날때도 있지만 바로 다시시도 하면 또 잘 된다. -_- 멍뮈...
    • 중도에 에러가 나면 C:\wireshark-win32-libs 의 내용을 다 지우고 다시 빌드
    • 와샥 빌드에 필요한 여러가지 라이브러리를 받는다. wget 이용하여(gtk라이브러리 등등)
    • 중간중간 cygwin path warning이 나오는데 그냥 무시... 무신 옵션을 주면 없앨수 있다고 하는데 일단 ㄱㄱ
  8. nmake -f Makefile.nmake distclean 실행

    • 이것도 꼭 해줘야 하는 시퀀스!! 필요없는게 아니었음 ㅎㅎa
    • 해주는 이유는 아래와 같음

      • The released Wireshark sources contain files that are prepared for a UNIX build (e.g. config.h). You must distclean your sources before building the first time!
  9. nmake -f Makefile.nmake all

    • 좀 오래걸린다.

 

모두 빌드가 끝난다음에 C:\wireshark\wireshark-gtk2 에 가보면 실행파일이 생겼다. wireshark.exe

실행하면,

우옷!! 성공!! TEST 문구 확인 ㅠ.ㅠ

success.jpg

이 글은 스프링노트에서 작성되었습니다.

저작자 표시 비영리 동일 조건 변경 허락