博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
PTPD2源码解析之:packet的接收和发送
阅读量:6800 次
发布时间:2019-06-26

本文共 4865 字,大约阅读时间需要 16 分钟。

整个流程大概是:

  • 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;}
  • 上面是接收

转载地址:http://lnywl.baihongyu.com/

你可能感兴趣的文章
ZAM 3D入门教程(1):初识ZAM 3D
查看>>
nagios安装
查看>>
idea springboot热部署无效问题
查看>>
ReentrantLock详解
查看>>
即时通讯之数字电视
查看>>
【C++实现有序子序列合并算法】
查看>>
防病毒插件更新失败!?
查看>>
HTTP的post和get总结
查看>>
CEPH Cache Tiering
查看>>
Oracle 11g新特性之--Server Result Cache
查看>>
Oracle中的ORA-01548: active rollback segment '_SYSSMU1$' found
查看>>
AngularJs $anchorScroll、$controller、$document
查看>>
Microsoft资源
查看>>
WordPress 永久链接或固定链接设置技巧
查看>>
数据结构之线性表
查看>>
在PPT中插入FLASH遇到的系列问题
查看>>
2015百度之星 下棋
查看>>
常用的CMD命令
查看>>
搭建网站必不可少的知识11
查看>>
python下的MySQLdb使用
查看>>