PTPD2源码解析之:packet的接收和发送
整个流程大概是:
do_state(ptp_master状态)
issueAnnounce
- netSendGeneral
handle
- netRecvGeneral
ssize_t netSendGeneral(Octet * buf, UInteger16 length, NetPath * netPath, const const RunTimeOpts *rtOpts, Integer32 destinationAddress) { ssize_t ret; struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(PTP_GENERAL_PORT); #ifdef PTPD_PCAP if ((netPath->pcapGeneral != NULL) && (rtOpts->transport == IEEE_802_3)) { ret = netSendPcapEther(buf, length, &netPath->etherDest, (struct ether_addr *)netPath->interfaceID, netPath->pcapGeneral); if (ret <= 0) DBG("Error sending ether multicast general message\n"); else { netPath->sentPackets++; netPath->sentPacketsTotal++; } } else { #endif if(destinationAddress) { addr.sin_addr.s_addr = destinationAddress; /* * This function is used for PTP only anyway... * If we're sending to a unicast address, set the UNICAST flag. */ *(char *)(buf + 6) |= PTP_UNICAST; ret = sendto(netPath->generalSock, buf, length, 0, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)); if (ret <= 0) DBG("Error sending unicast general message\n"); else { netPath->sentPackets++; netPath->sentPacketsTotal++; } } else { addr.sin_addr.s_addr = netPath->multicastAddr; /* Is TTL OK? */ if(netPath->ttlGeneral != rtOpts->ttl) { /* Try restoring TTL */ if (netSetMulticastTTL(netPath->generalSock,rtOpts->ttl)) { netPath->ttlGeneral = rtOpts->ttl; } } ret = sendto(netPath->generalSock, buf, length, 0, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)); if (ret <= 0) DBG("Error sending multicast general message\n"); else { netPath->sentPackets++; netPath->sentPacketsTotal++; } } #ifdef PTPD_PCAP } #endif return ret; }
- 上面是发送网络包的源码,其中ret是为了配合接收packet而返回的文件描述字(符合Linux一切皆是文件的理念)。
- 其中PTPD_PCAP那部分不重要,貌似没有作用,暂不了解。
- 有destinationAddress就unicast,没有multicast。
ssize_t netRecvGeneral(Octet * buf, NetPath * netPath) { ssize_t ret = 0; struct sockaddr_in from_addr; #ifdef PTPD_PCAP struct pcap_pkthdr *pkt_header; const u_char *pkt_data; #endif socklen_t from_addr_len = sizeof(from_addr); netPath->lastSourceAddr = 0; #ifdef PTPD_PCAP if (netPath->pcapGeneral == NULL) { #endif ret=recvfrom(netPath->generalSock, buf, PACKET_SIZE, MSG_DONTWAIT, (struct sockaddr*)&from_addr, &from_addr_len); netPath->lastSourceAddr = from_addr.sin_addr.s_addr; /* do not report "from self" */ if(!netPath->lastSourceAddr || (netPath->lastSourceAddr != netPath->interfaceAddr.s_addr)) { netPath->receivedPackets++; } netPath->receivedPacketsTotal++; return ret; #ifdef PTPD_PCAP } #endif #ifdef PTPD_PCAP else { /* Using PCAP */ /* Discard packet on socket */ if (netPath->generalSock >= 0) recv(netPath->generalSock, buf, PACKET_SIZE, MSG_DONTWAIT); if (( ret = pcap_next_ex(netPath->pcapGeneral, &pkt_header, &pkt_data)) < 1) { if (ret < 0) DBGV("netRecvGeneral: pcap_next_ex failed %d %s\n", ret, pcap_geterr(netPath->pcapGeneral)); return 0; } /* Make sure this is IP (could dot1q get here?) */ if( ntohs(*(u_short *)(pkt_data + 12)) != ETHERTYPE_IP) { if( ntohs(*(u_short *)(pkt_data + 12)) != PTP_ETHER_TYPE) { DBG("PCAP payload ethertype received not IP or PTP: 0x%04x\n", ntohs(*(u_short *)(pkt_data + 12))); /* do not count packets if from self */ } else if(memcmp(&netPath->interfaceInfo.hwAddress, pkt_data + 6, 6)) { netPath->receivedPackets++; } } else { /* Retrieve source IP from the payload - 14 eth + 12 IP */ netPath->lastSourceAddr = *(Integer32 *)(pkt_data + 26); /* Retrieve destination IP from the payload - 14 eth + 16 IP */ netPath->lastDestAddr = *(Integer32 *)(pkt_data + 30); /* do not count packets from self */ if(netPath->lastSourceAddr != netPath->interfaceAddr.s_addr) { netPath->receivedPackets++; } } netPath->receivedPacketsTotal++; /* XXX Total cheat */ memcpy(buf, pkt_data + netPath->headerOffset, pkt_header->caplen - netPath->headerOffset); fflush(NULL); ret = pkt_header->caplen - netPath->headerOffset; } #endif return ret; }
- 上面是接收
相关推荐
chensen 2020-11-14
lwnylslwnyls 2020-11-06
ATenhong 2020-10-15
yanzhelee 2020-10-13
佛系程序员J 2020-10-10
guojin0 2020-10-08
佛系程序员J 2020-10-08
bluewelkin 2020-09-16
wwzaqw 2020-09-04
zhongdaowendao 2020-09-02
favouriter 2020-08-18
奎因amp华洛 2020-08-15
一青年 2020-08-13
千锋 2020-08-10
nangongyanya 2020-08-09
dongxurr 2020-08-08
明天你好 2020-08-03
kyelu 2020-08-03
Ashes 2020-08-03