⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 net.c

📁 IEEE1588 Protocol,用于同步局域网各站点时间
💻 C
📖 第 1 页 / 共 2 页
字号:
/* net.c */#include "../ptpd.h"Boolean lookupSubdomainAddress(Octet *subdomainName, Octet *subdomainAddress){  UInteger32 h;    /* set multicast group address based on subdomainName */  if (!memcmp(subdomainName, DEFAULT_PTP_DOMAIN_NAME, PTP_SUBDOMAIN_NAME_LENGTH))    memcpy(subdomainAddress, DEFAULT_PTP_DOMAIN_ADDRESS, NET_ADDRESS_LENGTH);  else if(!memcmp(subdomainName, ALTERNATE_PTP_DOMAIN1_NAME, PTP_SUBDOMAIN_NAME_LENGTH))    memcpy(subdomainAddress, ALTERNATE_PTP_DOMAIN1_ADDRESS, NET_ADDRESS_LENGTH);  else if(!memcmp(subdomainName, ALTERNATE_PTP_DOMAIN2_NAME, PTP_SUBDOMAIN_NAME_LENGTH))    memcpy(subdomainAddress, ALTERNATE_PTP_DOMAIN2_ADDRESS, NET_ADDRESS_LENGTH);  else if(!memcmp(subdomainName, ALTERNATE_PTP_DOMAIN3_NAME, PTP_SUBDOMAIN_NAME_LENGTH))    memcpy(subdomainAddress, ALTERNATE_PTP_DOMAIN3_ADDRESS, NET_ADDRESS_LENGTH);  else  {    h = crc_algorithm(subdomainName, PTP_SUBDOMAIN_NAME_LENGTH) % 3;    switch(h)    {    case 0:      memcpy(subdomainAddress, ALTERNATE_PTP_DOMAIN1_ADDRESS, NET_ADDRESS_LENGTH);      break;    case 1:      memcpy(subdomainAddress, ALTERNATE_PTP_DOMAIN2_ADDRESS, NET_ADDRESS_LENGTH);      break;    case 2:      memcpy(subdomainAddress, ALTERNATE_PTP_DOMAIN3_ADDRESS, NET_ADDRESS_LENGTH);      break;    default:      ERROR("handle out of range for '%s'!\n", subdomainName);      return FALSE;    }  }    return TRUE;}UInteger8 lookupCommunicationTechnology(UInteger8 communicationTechnology){#if defined(linux)    switch(communicationTechnology)  {  case ARPHRD_ETHER:  case ARPHRD_EETHER:  case ARPHRD_IEEE802:    return PTP_ETHER;      default:    break;  }  #elif defined(BSD_INTERFACE_FUNCTIONS)  #endif    return PTP_DEFAULT;}UInteger32 findIface(Octet *ifaceName, UInteger8 *communicationTechnology,  Octet *uuid, NetPath *netPath){#if defined(linux)  /* depends on linux specific ioctls (see 'netdevice' man page) */  int i, flags;  struct ifconf data;  struct ifreq device[IFCONF_LENGTH];    data.ifc_len = sizeof(device);  data.ifc_req = device;    memset(data.ifc_buf,0,data.ifc_len);    flags = IFF_UP|IFF_RUNNING|IFF_MULTICAST;    /* look for an interface if none specified */  if(ifaceName[0] != '\0')  {    i = 0;    memcpy(device[i].ifr_name, ifaceName, IFACE_NAME_LENGTH);        if(ioctl(netPath->eventSock, SIOCGIFHWADDR, &device[i]) < 0)      DBGV("failed to get hardware address\n");    else if((*communicationTechnology = lookupCommunicationTechnology(device[i].ifr_hwaddr.sa_family)) == PTP_DEFAULT)      DBGV("unsupported communication technology (%d)\n", *communicationTechnology);    else      memcpy(uuid, device[i].ifr_hwaddr.sa_data, PTP_UUID_LENGTH);  }  else  {    /* no iface specified */    /* get list of network interfaces*/    if(ioctl(netPath->eventSock, SIOCGIFCONF, &data) < 0)    {      PERROR("failed query network interfaces");      return 0;    }        if(data.ifc_len >= sizeof(device))      DBG("device list may exceed allocated space\n");        /* search through interfaces */    for(i=0; i < data.ifc_len/sizeof(device[0]); ++i)    {      DBGV("%d %s %s\n",i,device[i].ifr_name,inet_ntoa(((struct sockaddr_in *)&device[i].ifr_addr)->sin_addr));            if(ioctl(netPath->eventSock, SIOCGIFFLAGS, &device[i]) < 0)        DBGV("failed to get device flags\n");      else if((device[i].ifr_flags&flags) != flags)        DBGV("does not meet requirements (%08x, %08x)\n", device[i].ifr_flags, flags);      else if(ioctl(netPath->eventSock, SIOCGIFHWADDR, &device[i]) < 0)        DBGV("failed to get hardware address\n");      else if((*communicationTechnology = lookupCommunicationTechnology(device[i].ifr_hwaddr.sa_family)) == PTP_DEFAULT)        DBGV("unsupported communication technology (%d)\n", *communicationTechnology);      else      {        DBGV("found interface (%s)\n", device[i].ifr_name);                memcpy(uuid, device[i].ifr_hwaddr.sa_data, PTP_UUID_LENGTH);        memcpy(ifaceName, device[i].ifr_name, IFACE_NAME_LENGTH);                break;      }    }  }    if(ifaceName[0] == '\0')  {    ERROR("failed to find a usable interface\n");    return 0;  }    if(ioctl(netPath->eventSock, SIOCGIFADDR, &device[i]) < 0)  {    PERROR("failed to get ip address");    return 0;  }    return ((struct sockaddr_in *)&device[i].ifr_addr)->sin_addr.s_addr;#elif defined(BSD_INTERFACE_FUNCTIONS)  struct ifaddrs *if_list, *ifv4, *ifh;  if (getifaddrs(&if_list) < 0)  {    PERROR("getifaddrs() failed");    return FALSE;  }  /* find an IPv4, multicast, UP interface, right name(if supplied) */  for (ifv4 = if_list; ifv4 != NULL; ifv4 = ifv4->ifa_next)  {    if ((ifv4->ifa_flags & IFF_UP) == 0)      continue;    if ((ifv4->ifa_flags & IFF_RUNNING) == 0)      continue;    if ((ifv4->ifa_flags & IFF_LOOPBACK))      continue;    if ((ifv4->ifa_flags & IFF_MULTICAST) == 0)      continue;    if (ifv4->ifa_addr->sa_family != AF_INET)  /* must have IPv4 address */      continue;    if (ifaceName[0] && strncmp(ifv4->ifa_name, ifaceName, IF_NAMESIZE) != 0)      continue;    break;  }  if (ifv4 == NULL)  {    if (ifaceName[0])    {      ERROR("interface \"%s\" does not exist, or is not appropriate\n", ifaceName);      return FALSE;    }    ERROR("no suitable interfaces found!");    return FALSE;  }  /* find the AF_LINK info associated with the chosen interface */  for (ifh = if_list; ifh != NULL; ifh = ifh->ifa_next)  {    if (ifh->ifa_addr->sa_family != AF_LINK)      continue;    if (strncmp(ifv4->ifa_name, ifh->ifa_name, IF_NAMESIZE) == 0)      break;  }  if (ifh == NULL)  {    ERROR("could not get hardware address for interface \"%s\"\n", ifv4->ifa_name);    return FALSE;  }  /* check that the interface TYPE is OK */  if ( ((struct sockaddr_dl *)ifh->ifa_addr)->sdl_type != IFT_ETHER )  {    ERROR("\"%s\" is not an ethernet interface!\n", ifh->ifa_name);    return FALSE;  }  printf("==> %s %s %s\n", ifv4->ifa_name,       inet_ntoa(((struct sockaddr_in *)ifv4->ifa_addr)->sin_addr),        ether_ntoa((struct ether_addr *)LLADDR((struct sockaddr_dl *)ifh->ifa_addr))        );  *communicationTechnology = PTP_ETHER;  memcpy(ifaceName, ifh->ifa_name, IFACE_NAME_LENGTH);  memcpy(uuid, LLADDR((struct sockaddr_dl *)ifh->ifa_addr), PTP_UUID_LENGTH);  return ((struct sockaddr_in *)ifv4->ifa_addr)->sin_addr.s_addr;#endif}/* start all of the UDP stuff *//* must specify 'subdomainName', optionally 'ifaceName', if not then pass ifaceName == "" *//* returns other args *//* 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 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -