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;
}- 上面是接收
相关推荐
lwnylslwnyls 2020-11-06
yanzhelee 2020-10-13
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