Example #1
0
/**
  * @brief  Start all of the UDP stuff
  * @param  netPath network object
  * @param  ptpClock PTP clock object
  * @retval Boolean success
  */
Boolean netInit(NetPath *netPath, PtpClock *ptpClock)
{

    struct ip_addr interfaceAddr;

    struct in_addr netAddr;
    char addrStr[NET_ADDRESS_LENGTH];

    DBG("netInit\n");

    /* find a network interface */
    interfaceAddr.addr = findIface(ptpClock->rtOpts->ifaceName, ptpClock->portUuidField, netPath);

    if (!(interfaceAddr.addr))
    {

        goto fail01;
    }

    /* Open lwIP raw udp interfaces for the event port. */
    netPath->eventPcb = udp_new();

    if (NULL == netPath->eventPcb)
    {
        ERROR("netInit: Failed to open Event UDP PCB\n");
        goto fail02;
    }

    /* Open lwIP raw udp interfaces for the general port. */
    netPath->generalPcb = udp_new();

    if (NULL == netPath->generalPcb)
    {
        ERROR("netInit: Failed to open General UDP PCB\n");
        goto fail03;
    }

    /* Initialize the buffer queues. */
    netQInit(&netPath->eventQ);

    netQInit(&netPath->generalQ);

    /* Configure network (broadcast/unicast) addresses. */
    netPath->unicastAddr = 0; /* disable unicast */

    /*Init General multicast IP address*/
    memcpy(addrStr, DEFAULT_PTP_DOMAIN_ADDRESS, NET_ADDRESS_LENGTH);

    if (!inet_aton(addrStr, &netAddr))
    {
        ERROR("netInit: failed to encode multi-cast address: %s\n", addrStr);
        goto fail04;
    }

    netPath->multicastAddr = netAddr.s_addr;

    /* join multicast group (for receiving) on specified interface */
    igmp_joingroup(&interfaceAddr, (struct ip_addr *)&netAddr);


    /*Init Peer multicast IP address*/
    memcpy(addrStr, PEER_PTP_DOMAIN_ADDRESS, NET_ADDRESS_LENGTH);

    if (!inet_aton(addrStr, &netAddr))
    {
        ERROR("netInit: failed to encode peer multi-cast address: %s\n", addrStr);
        goto fail04;
    }

    netPath->peerMulticastAddr = netAddr.s_addr;

    /* join peer multicast group (for receiving) on specified interface */
    igmp_joingroup(&interfaceAddr, (struct ip_addr *)&netAddr);


    /* multicast send only on specified interface */
    netPath->eventPcb->multicast_ip.addr = netPath->multicastAddr;
    netPath->generalPcb->multicast_ip.addr = netPath->multicastAddr;

    /* Establish the appropriate UDP bindings/connections for events. */
    udp_recv(netPath->eventPcb, netRecvEventCallback, netPath);
    udp_bind(netPath->eventPcb, IP_ADDR_ANY, PTP_EVENT_PORT);
    /*  udp_connect(netPath->eventPcb, &netAddr, PTP_EVENT_PORT); */

    /* Establish the appropriate UDP bindings/connections for general. */
    udp_recv(netPath->generalPcb, netRecvGeneralCallback, netPath);
    udp_bind(netPath->generalPcb, IP_ADDR_ANY, PTP_GENERAL_PORT);
    /*  udp_connect(netPath->generalPcb, &netAddr, PTP_GENERAL_PORT); */

    /* Return a success code. */
    return TRUE;

    /*
    fail05:
        udp_disconnect(netPath->eventPcb);
        udp_disconnect(netPath->generalPcb);
    */
fail04:
    udp_remove(netPath->generalPcb);
fail03:
    udp_remove(netPath->eventPcb);
fail02:
fail01:
    return FALSE;
}
Example #2
0
/* on socket options, see the 'socket(7)' and 'ip' man pages */
Boolean
netInit(NetPath * netPath, RunTimeOpts * rtOpts, PtpClock * ptpClock)
{
    int temp, i;
    struct in_addr interfaceAddr, netAddr;
    struct sockaddr_in addr;
    struct ip_mreq imr;
    char addrStr[NET_ADDRESS_LENGTH];
    char *s;

    DBG("netInit\n");

    /* open sockets */
    if ((netPath->eventSock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0
            || (netPath->generalSock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
        PERROR("failed to initalize sockets");
        return FALSE;
    }
    /* find a network interface */
    if (!(interfaceAddr.s_addr = findIface(rtOpts->ifaceName, &ptpClock->port_communication_technology,
                                           ptpClock->port_uuid_field, netPath)))
        return FALSE;

    temp = 1;			/* allow address reuse */
    if (setsockopt(netPath->eventSock, SOL_SOCKET, SO_REUSEADDR, &temp, sizeof(int)) < 0
            || setsockopt(netPath->generalSock, SOL_SOCKET, SO_REUSEADDR, &temp, sizeof(int)) < 0) {
        DBG("failed to set socket reuse\n");
    }
    /* bind sockets */
    /*
     * need INADDR_ANY to allow receipt of multi-cast and uni-cast
     * messages
     */
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
    addr.sin_port = htons(PTP_EVENT_PORT);
    if (bind(netPath->eventSock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0) {
        PERROR("failed to bind event socket");
        return FALSE;
    }
    addr.sin_port = htons(PTP_GENERAL_PORT);
    if (bind(netPath->generalSock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0) {
        PERROR("failed to bind general socket");
        return FALSE;
    }
    /* set general and port address */
    *(Integer16 *) ptpClock->event_port_address = PTP_EVENT_PORT;
    *(Integer16 *) ptpClock->general_port_address = PTP_GENERAL_PORT;

    /* send a uni-cast address if specified (useful for testing) */
    if (rtOpts->unicastAddress[0]) {
        if (!inet_aton(rtOpts->unicastAddress, &netAddr)) {
            ERROR("failed to encode uni-cast address: %s\n", rtOpts->unicastAddress);
            return FALSE;
        }
        netPath->unicastAddr = netAddr.s_addr;
    } else
        netPath->unicastAddr = 0;

    /* resolve PTP subdomain */
    if (!lookupSubdomainAddress(rtOpts->subdomainName, addrStr))
        return FALSE;

    if (!inet_aton(addrStr, &netAddr)) {
        ERROR("failed to encode multi-cast address: %s\n", addrStr);
        return FALSE;
    }
    netPath->multicastAddr = netAddr.s_addr;

    s = addrStr;
    for (i = 0; i < SUBDOMAIN_ADDRESS_LENGTH; ++i) {
        ptpClock->subdomain_address[i] = strtol(s, &s, 0);

        if (!s)
            break;

        ++s;
    }

    /* multicast send only on specified interface */
    imr.imr_multiaddr.s_addr = netAddr.s_addr;
    imr.imr_interface.s_addr = interfaceAddr.s_addr;
    if (setsockopt(netPath->eventSock, IPPROTO_IP, IP_MULTICAST_IF, &imr.imr_interface.s_addr, sizeof(struct in_addr)) < 0
            || setsockopt(netPath->generalSock, IPPROTO_IP, IP_MULTICAST_IF, &imr.imr_interface.s_addr, sizeof(struct in_addr)) < 0) {
        PERROR("failed to enable multi-cast on the interface");
        return FALSE;
    }
    /* join multicast group (for receiving) on specified interface */
    if (setsockopt(netPath->eventSock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr, sizeof(struct ip_mreq)) < 0
            || setsockopt(netPath->generalSock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr, sizeof(struct ip_mreq)) < 0) {
        PERROR("failed to join the multi-cast group");
        return FALSE;
    }
    /* set socket time-to-live */
    if (setsockopt(netPath->eventSock, IPPROTO_IP, IP_MULTICAST_TTL, &rtOpts->ttl, sizeof(int)) < 0
            || setsockopt(netPath->generalSock, IPPROTO_IP, IP_MULTICAST_TTL, &rtOpts->ttl, sizeof(int)) < 0) {
        PERROR("failed to set the multi-cast time-to-live");
        return FALSE;
    }
    /* enable loopback */
    temp = 1;
    if (setsockopt(netPath->eventSock, IPPROTO_IP, IP_MULTICAST_LOOP, &temp, sizeof(int)) < 0
            || setsockopt(netPath->generalSock, IPPROTO_IP, IP_MULTICAST_LOOP, &temp, sizeof(int)) < 0) {
        PERROR("failed to enable multi-cast loopback");
        return FALSE;
    }
    /* make timestamps available through recvmsg() */

    temp = 1;
#if defined(linux)
    if (setsockopt(netPath->eventSock, SOL_SOCKET, SO_TIMESTAMP, &temp, sizeof(int)) < 0
            || setsockopt(netPath->generalSock, SOL_SOCKET, SO_TIMESTAMP, &temp, sizeof(int)) < 0) {
#else /* BSD */
    if (setsockopt(netPath->eventSock, SOL_SOCKET, SO_BINTIME, &temp, sizeof(int)) < 0
            || setsockopt(netPath->generalSock, SOL_SOCKET, SO_BINTIME, &temp, sizeof(int)) < 0) {
#endif /* linux or BSD */
        PERROR("failed to enable receive time stamps");
        return FALSE;
    }

    return TRUE;
}

/* shut down the UDP stuff */
Boolean
netShutdown(NetPath * netPath)
{
    struct ip_mreq imr;

    imr.imr_multiaddr.s_addr = netPath->multicastAddr;
    imr.imr_interface.s_addr = htonl(INADDR_ANY);

    setsockopt(netPath->eventSock, IPPROTO_IP, IP_DROP_MEMBERSHIP, &imr, sizeof(struct ip_mreq));
    setsockopt(netPath->generalSock, IPPROTO_IP, IP_DROP_MEMBERSHIP, &imr, sizeof(struct ip_mreq));

    netPath->multicastAddr = 0;
    netPath->unicastAddr = 0;

    if (netPath->eventSock > 0)
        close(netPath->eventSock);
    netPath->eventSock = -1;

    if (netPath->generalSock > 0)
        close(netPath->generalSock);
    netPath->generalSock = -1;

    return TRUE;
}

int
netSelect(TimeInternal * timeout, NetPath * netPath)
{
    int ret, nfds;
    fd_set readfds;
    struct timeval tv, *tv_ptr;

    if (timeout < 0)
        return FALSE;

    FD_ZERO(&readfds);
    FD_SET(netPath->eventSock, &readfds);
    FD_SET(netPath->generalSock, &readfds);

    if (timeout) {
        tv.tv_sec = timeout->seconds;
        tv.tv_usec = timeout->nanoseconds / 1000;
        tv_ptr = &tv;
    } else
        tv_ptr = 0;

    if (netPath->eventSock > netPath->generalSock)
        nfds = netPath->eventSock;
    else
        nfds = netPath->generalSock;

    ret = select(nfds + 1, &readfds, 0, 0, tv_ptr) > 0;
    if (ret < 0) {
        if (errno == EAGAIN || errno == EINTR)
            return 0;
    }
    return ret;
}
Example #3
0
/* on socket options, see the 'socket(7)' and 'ip' man pages */
Boolean netInit(NetPath *netPath, RunTimeOpts *rtOpts, PtpClock *ptpClock)
{
  int temp, i;
  struct in_addr interfaceAddr, netAddr;
  struct sockaddr_in addr;
  struct ip_mreq imr;
  char addrStr[NET_ADDRESS_LENGTH];
  char *s;
  
  DBG("netInit\n");
  
  /* open sockets */
  if( (netPath->eventSock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP) ) < 0
    || (netPath->generalSock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP) ) < 0 )
  {
    PERROR("failed to initalize sockets");
    return FALSE;
  }

  /* find a network interface */
  if( !(interfaceAddr.s_addr = findIface(rtOpts->ifaceName, &ptpClock->port_communication_technology,
    ptpClock->port_uuid_field, netPath)) )
    return FALSE;
  
  temp = 1;  /* allow address reuse */
  if( setsockopt(netPath->eventSock, SOL_SOCKET, SO_REUSEADDR, &temp, sizeof(int)) < 0
    || setsockopt(netPath->generalSock, SOL_SOCKET, SO_REUSEADDR, &temp, sizeof(int)) < 0 )
  {
    DBG("failed to set socket reuse\n");
  }

  /* bind sockets */
  /* need INADDR_ANY to allow receipt of multi-cast and uni-cast messages */
  addr.sin_family = AF_INET;
  addr.sin_addr.s_addr = htonl(INADDR_ANY);
  addr.sin_port = htons(PTP_EVENT_PORT);
  if(bind(netPath->eventSock, (struct sockaddr*)&addr, sizeof(struct sockaddr_in)) < 0)
  {
    PERROR("failed to bind event socket");
    return FALSE;
  }
  
  addr.sin_port = htons(PTP_GENERAL_PORT);
  if(bind(netPath->generalSock, (struct sockaddr*)&addr, sizeof(struct sockaddr_in)) < 0)
  {
    PERROR("failed to bind general socket");
    return FALSE;
  }
  
  /* set general and port address */
  *(Integer16*)ptpClock->event_port_address = PTP_EVENT_PORT;
  *(Integer16*)ptpClock->general_port_address = PTP_GENERAL_PORT;
  
  /* send a uni-cast address if specified (useful for testing) */
  if(rtOpts->unicastAddress[0])
  {
    if(!inet_aton(rtOpts->unicastAddress, &netAddr))
    {
      ERROR("failed to encode uni-cast address: %s\n", rtOpts->unicastAddress);
      return FALSE;
    }
    
    netPath->unicastAddr = netAddr.s_addr;
  }
  else
    netPath->unicastAddr = 0;
  
  /* resolve PTP subdomain */
  if(!lookupSubdomainAddress(rtOpts->subdomainName, addrStr))
    return FALSE;
  
  if(!inet_aton(addrStr, &netAddr))
  {
    ERROR("failed to encode multi-cast address: %s\n", addrStr);
    return FALSE;
  }
  
  netPath->multicastAddr = netAddr.s_addr;
  
  s = addrStr;
  for(i = 0; i < SUBDOMAIN_ADDRESS_LENGTH; ++i)
  {
    ptpClock->subdomain_address[i] = strtol(s, &s, 0);
    
    if(!s)
      break;
    
    ++s;
  }
  
  /* multicast send only on specified interface */
  imr.imr_multiaddr.s_addr = netAddr.s_addr;
  imr.imr_interface.s_addr = interfaceAddr.s_addr;
  if( setsockopt(netPath->eventSock, IPPROTO_IP, IP_MULTICAST_IF, &imr.imr_interface.s_addr, sizeof(struct in_addr)) < 0
    || setsockopt(netPath->generalSock, IPPROTO_IP, IP_MULTICAST_IF, &imr.imr_interface.s_addr, sizeof(struct in_addr)) < 0 )
  {
    PERROR("failed to enable multi-cast on the interface");
    return FALSE;
  }
  
  /* join multicast group (for receiving) on specified interface */
  if( setsockopt(netPath->eventSock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr, sizeof(struct ip_mreq))  < 0
    || setsockopt(netPath->generalSock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr, sizeof(struct ip_mreq)) < 0 )
  {
    PERROR("failed to join the multi-cast group");
    return FALSE;
  }

  /* set socket time-to-live to 1 */
  temp = 1;
  if( setsockopt(netPath->eventSock, IPPROTO_IP, IP_MULTICAST_TTL, &temp, sizeof(int)) < 0
    || setsockopt(netPath->generalSock, IPPROTO_IP, IP_MULTICAST_TTL, &temp, sizeof(int)) < 0 )
  {
    PERROR("failed to set the multi-cast time-to-live");
    return FALSE;
  }
  
  /* enable loopback */
  temp = 1;
  if( setsockopt(netPath->eventSock, IPPROTO_IP, IP_MULTICAST_LOOP, &temp, sizeof(int)) < 0
    || setsockopt(netPath->generalSock, IPPROTO_IP, IP_MULTICAST_LOOP, &temp, sizeof(int)) < 0 )
  {
    PERROR("failed to enable multi-cast loopback");
    return FALSE;
  }

  /* make timestamps available through recvmsg() */
  temp = 1;
  if( setsockopt(netPath->eventSock, SOL_SOCKET, SO_TIMESTAMP, &temp, sizeof(int)) < 0
    || setsockopt(netPath->generalSock, SOL_SOCKET, SO_TIMESTAMP, &temp, sizeof(int)) < 0 )
  {
    PERROR("failed to enable receive time stamps");
    return FALSE;
  }


  return TRUE;
}