1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
| 3611 static int 3612 create_ring(pcap_t *handle, int *status) ... 3787 /* 3788 * PACKET_TIMESTAMP was added after linux/net_tstamp.h was, 3789 * so we check for PACKET_TIMESTAMP. We check for 3790 * linux/net_tstamp.h just in case a system somehow has 3791 * PACKET_TIMESTAMP but not linux/net_tstamp.h; that might 3792 * be unnecessary. 3793 * 3794 * SIOCSHWTSTAMP was introduced in the patch that introduced 3795 * linux/net_tstamp.h, so we don't bother checking whether 3796 * SIOCSHWTSTAMP is defined (if your Linux system has 3797 * linux/net_tstamp.h but doesn't define SIOCSHWTSTAMP, your 3798 * Linux system is badly broken). 3799 */ 3800 #if defined(HAVE_LINUX_NET_TSTAMP_H) && defined(PACKET_TIMESTAMP) 3801 /* 3802 * If we were told to do so, ask the kernel and the driver 3803 * to use hardware timestamps. 3804 * 3805 * Hardware timestamps are only supported with mmapped 3806 * captures. 3807 */ 3808 if (handle->opt.tstamp_type == PCAP_TSTAMP_ADAPTER || 3809 handle->opt.tstamp_type == PCAP_TSTAMP_ADAPTER_UNSYNCED) { 3810 struct hwtstamp_config hwconfig; 3811 struct ifreq ifr; 3812 int timesource; 3813 3814 /* 3815 * Ask for hardware time stamps on all packets, 3816 * including transmitted packets. 3817 */ 3818 memset(&hwconfig, 0, sizeof(hwconfig)); 3819 hwconfig.tx_type = HWTSTAMP_TX_ON; 3820 hwconfig.rx_filter = HWTSTAMP_FILTER_ALL; 3821 3822 memset(&ifr, 0, sizeof(ifr)); 3823 strlcpy(ifr.ifr_name, handle->opt.source, sizeof(ifr.ifr_name)); 3824 ifr.ifr_data = (void *)&hwconfig; 3825 3826 if (ioctl(handle->fd, SIOCSHWTSTAMP, &ifr) < 0) { 3827 switch (errno) { 3828 3829 case EPERM: 3830 /* 3831 * Treat this as an error, as the 3832 * user should try to run this 3833 * with the appropriate privileges - 3834 * and, if they can't, shouldn't 3835 * try requesting hardware time stamps. 3836 */ 3837 *status = PCAP_ERROR_PERM_DENIED; 3838 return -1; 3839 3840 case EOPNOTSUPP: 3841 /* 3842 * Treat this as a warning, as the 3843 * only way to fix the warning is to 3844 * get an adapter that supports hardware 3845 * time stamps. We'll just fall back 3846 * on the standard host time stamps. 3847 */ 3848 *status = PCAP_WARNING_TSTAMP_TYPE_NOTSUP; 3849 break; 3850 3851 default: 3852 snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 3853 "SIOCSHWTSTAMP failed: %s", 3854 pcap_strerror(errno)); 3855 *status = PCAP_ERROR; 3856 return -1; 3857 } 3858 } else { 3859 /* 3860 * Well, that worked. Now specify the type of 3861 * hardware time stamp we want for this 3862 * socket. 3863 */ 3864 if (handle->opt.tstamp_type == PCAP_TSTAMP_ADAPTER) { 3865 /* 3866 * Hardware timestamp, synchronized 3867 * with the system clock. 3868 */ 3869 timesource = SOF_TIMESTAMPING_SYS_HARDWARE; 3870 } else { 3871 /* 3872 * PCAP_TSTAMP_ADAPTER_UNSYNCED - hardware 3873 * timestamp, not synchronized with the 3874 * system clock. 3875 */ 3876 timesource = SOF_TIMESTAMPING_RAW_HARDWARE; 3877 } 3878 if (setsockopt(handle->fd, SOL_PACKET, PACKET_TIMESTAMP, <======= 3879 (void *)×ource, sizeof(timesource))) { 3880 snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 3881 "can't set PACKET_TIMESTAMP: %s", 3882 pcap_strerror(errno)); 3883 *status = PCAP_ERROR; 3884 return -1; 3885 } 3886 } 3887 } 3888 #endif /* HAVE_LINUX_NET_TSTAMP_H && PACKET_TIMESTAMP */
|