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

📄 net.c

📁 IEEE1588 Protocol,用于同步局域网各站点时间
💻 C
📖 第 1 页 / 共 2 页
字号:
  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;}/* 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;}ssize_t netRecvEvent(Octet *buf, TimeInternal *time, NetPath *netPath){  ssize_t ret;  struct msghdr msg;  struct iovec vec[1];  struct sockaddr_in from_addr;  union {      struct cmsghdr cm;      char control[CMSG_SPACE(sizeof(struct timeval))];  } cmsg_un;  struct cmsghdr *cmsg;  struct timeval *tv;    vec[0].iov_base = buf;  vec[0].iov_len = PACKET_SIZE;    memset(&msg, 0, sizeof(msg));  memset(&from_addr, 0, sizeof(from_addr));  memset(buf, 0, PACKET_SIZE);  memset(&cmsg_un, 0, sizeof(cmsg_un));    msg.msg_name = (caddr_t)&from_addr;  msg.msg_namelen = sizeof(from_addr);  msg.msg_iov = vec;  msg.msg_iovlen = 1;  msg.msg_control = cmsg_un.control;  msg.msg_controllen = sizeof(cmsg_un.control);  msg.msg_flags = 0;    ret = recvmsg(netPath->eventSock, &msg, MSG_DONTWAIT);  if(ret <= 0)  {    if(errno == EAGAIN || errno == EINTR)      return 0;        return ret;  }    if(msg.msg_flags&MSG_TRUNC)  {    ERROR("received truncated message\n");    return 0;  }    /* get time stamp of packet */  if(!time)  {    ERROR("null receive time stamp argument\n");    return 0;  }    if(msg.msg_flags&MSG_CTRUNC)  {    ERROR("received truncated ancillary data\n");    return 0;  }    if(msg.msg_controllen < sizeof(cmsg_un.control))  {    ERROR("received short ancillary data (%d/%d)\n",      msg.msg_controllen, (int)sizeof(cmsg_un.control));        return 0;  }    tv = 0;  for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg))  {    if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_TIMESTAMP)      tv = (struct timeval *)CMSG_DATA(cmsg);  }    if(tv)  {    time->seconds = tv->tv_sec;    time->nanoseconds = tv->tv_usec*1000;    DBGV("kernel recv time stamp %us %dns\n", time->seconds, time->nanoseconds);  }  else  {    /* do not try to get by with recording the time here, better to fail       because the time recorded could be well after the message receive,       which would put a big spike in the offset signal sent to the clock servo */    DBG("no recieve time stamp\n");    return 0;  }  return ret;}ssize_t netRecvGeneral(Octet *buf, NetPath *netPath){  ssize_t ret;  struct sockaddr_in addr;  socklen_t addr_len = sizeof(struct sockaddr_in);    ret = recvfrom(netPath->generalSock, buf, PACKET_SIZE, MSG_DONTWAIT, (struct sockaddr *)&addr, &addr_len);  if(ret <= 0)  {    if(errno == EAGAIN || errno == EINTR)      return 0;        return ret;  }    return ret;}ssize_t netSendEvent(Octet *buf, UInteger16 length, NetPath *netPath){  ssize_t ret;  struct sockaddr_in addr;    addr.sin_family = AF_INET;  addr.sin_port = htons(PTP_EVENT_PORT);  addr.sin_addr.s_addr = netPath->multicastAddr;    ret = sendto(netPath->eventSock, buf, length, 0, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));  if(ret <= 0)    DBG("error sending multi-cast event message\n");    if(netPath->unicastAddr)  {    addr.sin_addr.s_addr = netPath->unicastAddr;        ret = sendto(netPath->eventSock, buf, length, 0, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));    if(ret <= 0)      DBG("error sending uni-cast event message\n");  }    return ret;}ssize_t netSendGeneral(Octet *buf, UInteger16 length, NetPath *netPath){  ssize_t ret;  struct sockaddr_in addr;    addr.sin_family = AF_INET;  addr.sin_port = htons(PTP_GENERAL_PORT);  addr.sin_addr.s_addr = netPath->multicastAddr;    ret = sendto(netPath->generalSock, buf, length, 0, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));  if(ret <= 0)    DBG("error sending multi-cast general message\n");    if(netPath->unicastAddr)  {    addr.sin_addr.s_addr = netPath->unicastAddr;        ret = sendto(netPath->eventSock, buf, length, 0, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));    if(ret <= 0)      DBG("error sending uni-cast general message\n");  }    return ret;}

⌨️ 快捷键说明

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