본문 바로가기

OS/vxworks

Vxworks6에서 arpResolve 구현

Vxworks6.x에는 Vxworks5.x에서 있었던 arpResolve 함수가 없다. 윈드리버에 문의한 결과 아래와 같은 arpResolve의 구현물을 얻었다.

arpResolve

  1. #ifndef IPCOM_KERNEL
    #define IPCOM_KERNEL
    #endif
    #include <ipnet_config.h>

    #define IPCOM_USE_CLIB_PROTO
    #include <ipcom_type.h>

    #include <ipcom_cstyle.h>
    #include <ipcom_err.h>
    #include <ipcom_clib.h>
    #include <ipcom_syslog.h>

    #include "ipnet.h"
    #include "ipnet_h.h"
    #include "ipnet_eth.h"
    #include "ipnet_pkt_queue.h"

    #include <taskLib.h>
    #include <stdio.h>
    #include <errnoLib.h>

    int arpResolve(char *pIpAddr, char *pMac, int tries, int ticks) {
        struct Ip_in_addr target;
        Ipnet_route_entry *pRt;
        struct Ip_arpreq arpreq;
        int sock, i, j, ret;

        ipcom_inet_pton(IP_AF_INET, pIpAddr, &target);

        IPNET_CODE_LOCK();
        ret = ipnet_route_raw_lookup(IP_AF_INET, 0, IPCOM_ROUTE_TABLE_DEFAULT,
        IPNET_RTL_FLAG_LINK_LOCAL, &target, 0, 0, &pRt);

        if ((ret != 0) || (IP_BIT_ISFALSE(pRt->hdr.flags, IPNET_RTF_LLINFO))) {
            IPNET_CODE_UNLOCK();
            return (ERROR);
        }

        if (tries <= 0)
            tries = 1;

        for (i = 0; i < tries; i++) {
            if (i)
                IPNET_CODE_LOCK();
            ipnet_arp_set_state(pRt, IPNET_ND_INCOMPLETE);
            IPNET_CODE_UNLOCK();

            if (ticks == 0)
                ticks = 1;

            taskDelay(ticks);

            memset((void *)&arpreq, 0, sizeof(struct Ip_arpreq));

            ret = ipcom_getsockaddrbyaddr(IP_AF_INET, pIpAddr, &arpreq.arp_pa);
            if (ret < 0) {
                printf("iqArpResolve - ipcom_getsockaddrbyaddrfailed\n");
                return (ERROR);
            }

            arpreq.arp_ha.sdl_type = IP_IFT_ETHER;
            arpreq.arp_ha.sdl_family = IP_AF_UNSPEC;

            sock = ipcom_socket(IP_AF_INET, IP_SOCK_DGRAM, 0);
            if (sock < 0) {
                printf("iqArpResolve - ipcom_socket failed\n");
                return (ERROR);
            }

            ret = ipcom_socketioctl(sock, IP_SIOCGARP, &arpreq);
            ipcom_socketclose(sock);
            if (ret < 0) {
                if (errnoGet() != IP_ERRNO_ESRCH) {
                    printf("iqArpResolve - ipcom_socketioctl failed\n");
                    return (ERROR);
                }
            }

            for (j = 0; j < 6; j++)
                if (arpreq.arp_ha.sdl_data[j] != 0)
                    break;

            if (j != 6)
                break;
        }

        memcpy((void *)pMac, (void *)arpreq.arp_ha.sdl_data, 6);
        return (OK);
    }

    void arpResolveTest(char *pAddr) {
        char buff[6];
        int ret;

        memset(buff, 0x0, sizeof(buff));

        ret = arpResolve(pAddr, buff, 5, 10);

        if (ret == ERROR) {
            printf("Error to resolve.\n");
        } else {
            printf("MAC : ");
            for (int i =0; i < 6; i ++) {
                printf("%02X", buff[i]);
            }
            printf("\n");
        }
    }

 

 

위의 소스를 컴파일하기 위한 컴파일 옵션이다.

  • define

    • -DIP_PORT_VXWORKS
  • include path

    • -IC:/Windriver/vxWorks-6.6/target/h
      -IC:/Windriver/vxWorks-6.6/target/h/wrn/coreip
      -IC:/WindRiver/components/ip_net2-6.6/ipcom
      -IC:/WindRiver/components/ip_net2-6.6/ipcom/port/vxworks/include
      -IC:/WindRiver/components/ip_net2-6.6/ipcom/port/vxworks/config
      -IC:/WindRiver/components/ip_net2-6.6/ipcom/include
      -IC:/WindRiver/components/ip_net2-6.6/ipcom/config
      -IC:/WindRiver/components/ip_net2-6.6/ipnet2/src
      -IC:/WindRiver/components/ip_net2-6.6/ipnet2/include
      -IC:/WindRiver/components/ip_net2-6.6/ipnet2/config
      -IC:/WindRiver/components/ip_net2-6.6/ipappl/config

 

결과

  1. [0]->
    [0]->
    [0]->arpResolveTest("10.100.10.90")
    MAC : XXXXXXXXXXXX
    value = 1 = 0x1
    [0]->arpResolveTest("10.100.10.99")
    MAC : YYYYYYYYYYYY
    value = 1 = 0x1
    [0]->

 

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