コード例 #1
0
ファイル: ptpd_net.c プロジェクト: peterliu2/tivaWare
Boolean netInit(NetPath *netPath, RunTimeOpts *rtOpts, PtpClock *ptpClock)
{
    int i;
    struct in_addr netAddr;
    char addrStr[NET_ADDRESS_LENGTH];

    DBG("netInit\n");

    /* Allocate tx buffer for the event port. */
    netPath->eventTxBuf = pbuf_alloc(PBUF_TRANSPORT, PACKET_SIZE, PBUF_RAM);
    if(netPath->eventTxBuf == NULL) {
        PERROR("Failed to allocate Event Tx Buffer\n");
        return FALSE;
    }

    /* Allocate tx buffer for the general port. */
    netPath->generalTxBuf = pbuf_alloc(PBUF_TRANSPORT, PACKET_SIZE, PBUF_RAM);
    if(netPath->generalTxBuf == NULL) {
        PERROR("Failed to allocate Event Tx Buffer\n");
        pbuf_free(netPath->eventTxBuf);
        return FALSE;
    }

    /* Open lwIP raw udp interfaces for the event port. */
    netPath->eventPcb = udp_new();
    if(netPath->eventPcb == NULL) {
        PERROR("Failed to open Event UDP PCB\n");
        pbuf_free(netPath->eventTxBuf);
        pbuf_free(netPath->generalTxBuf);
        return FALSE;
    }

    /* Open lwIP raw udp interfaces for the general port. */
    netPath->generalPcb = udp_new();
    if(netPath->generalPcb == NULL) {
        PERROR("Failed to open General UDP PCB\n");
        udp_remove(netPath->eventPcb);
        pbuf_free(netPath->eventTxBuf);
        pbuf_free(netPath->generalTxBuf);
        return FALSE;
    }

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

    /* Configure network (broadcast/unicast) addresses. */
    netPath->unicastAddr = 0;
    if(!lookupSubdomainAddress(rtOpts->subdomainName, addrStr)) {
        udp_disconnect(netPath->eventPcb);
        udp_disconnect(netPath->generalPcb);
        udp_remove(netPath->eventPcb);
        udp_remove(netPath->generalPcb);
        pbuf_free(netPath->eventTxBuf);
        pbuf_free(netPath->generalTxBuf);
        return FALSE;
    }
    if(!inet_aton(addrStr, &netAddr)) {
        ERROR("failed to encode multi-cast address: %s\n", addrStr);
        udp_disconnect(netPath->eventPcb);
        udp_disconnect(netPath->generalPcb);
        udp_remove(netPath->eventPcb);
        udp_remove(netPath->generalPcb);
        pbuf_free(netPath->eventTxBuf);
        pbuf_free(netPath->generalTxBuf);
        return FALSE;
    }
    netPath->multicastAddr = netAddr.s_addr;

    /* Setup subdomain address string. */
    for(i = 0; i < SUBDOMAIN_ADDRESS_LENGTH; ++i) {
        ptpClock->subdomain_address[i] = (netAddr.s_addr >> (i * 8)) & 0xff;
    }

    /* Establish the appropriate UDP bindings/connections for events. */

    udp_recv(netPath->eventPcb, eventRecv, netPath);
    udp_bind(netPath->eventPcb, IP_ADDR_ANY, PTP_EVENT_PORT);
//  udp_connect(netPath->eventPcb, IP_ADDR_ANY, PTP_EVENT_PORT);
    *(Integer16*)ptpClock->event_port_address = PTP_EVENT_PORT;

    /* Establish the appropriate UDP bindings/connections for general. */
    udp_recv(netPath->generalPcb, generalRecv, netPath);
    udp_bind(netPath->generalPcb, IP_ADDR_ANY, PTP_GENERAL_PORT);
//  udp_connect(netPath->generalPcb, IP_ADDR_ANY, PTP_GENERAL_PORT);
    *(Integer16*)ptpClock->general_port_address = PTP_GENERAL_PORT;

    /* Return a success code. */
    return TRUE;
}
コード例 #2
0
ファイル: net.c プロジェクト: peterliu2/tivaWare
/* 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;
}
コード例 #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;
}