0001
0002
0003
0004
0005
0006
0007 #include <errno.h>
0008 #include <stdio.h>
0009 #include <stdlib.h>
0010 #include <string.h>
0011
0012 #include <sys/socket.h>
0013 #include <sys/ioctl.h>
0014
0015 #include <linux/if.h>
0016 #include <linux/net_tstamp.h>
0017 #include <linux/sockios.h>
0018
0019 static int
0020 lookup_value(const char **names, int size, const char *name)
0021 {
0022 int value;
0023
0024 for (value = 0; value < size; value++)
0025 if (names[value] && strcasecmp(names[value], name) == 0)
0026 return value;
0027
0028 return -1;
0029 }
0030
0031 static const char *
0032 lookup_name(const char **names, int size, int value)
0033 {
0034 return (value >= 0 && value < size) ? names[value] : NULL;
0035 }
0036
0037 static void list_names(FILE *f, const char **names, int size)
0038 {
0039 int value;
0040
0041 for (value = 0; value < size; value++)
0042 if (names[value])
0043 fprintf(f, " %s\n", names[value]);
0044 }
0045
0046 static const char *tx_types[] = {
0047 #define TX_TYPE(name) [HWTSTAMP_TX_ ## name] = #name
0048 TX_TYPE(OFF),
0049 TX_TYPE(ON),
0050 TX_TYPE(ONESTEP_SYNC)
0051 #undef TX_TYPE
0052 };
0053 #define N_TX_TYPES ((int)(sizeof(tx_types) / sizeof(tx_types[0])))
0054
0055 static const char *rx_filters[] = {
0056 #define RX_FILTER(name) [HWTSTAMP_FILTER_ ## name] = #name
0057 RX_FILTER(NONE),
0058 RX_FILTER(ALL),
0059 RX_FILTER(SOME),
0060 RX_FILTER(PTP_V1_L4_EVENT),
0061 RX_FILTER(PTP_V1_L4_SYNC),
0062 RX_FILTER(PTP_V1_L4_DELAY_REQ),
0063 RX_FILTER(PTP_V2_L4_EVENT),
0064 RX_FILTER(PTP_V2_L4_SYNC),
0065 RX_FILTER(PTP_V2_L4_DELAY_REQ),
0066 RX_FILTER(PTP_V2_L2_EVENT),
0067 RX_FILTER(PTP_V2_L2_SYNC),
0068 RX_FILTER(PTP_V2_L2_DELAY_REQ),
0069 RX_FILTER(PTP_V2_EVENT),
0070 RX_FILTER(PTP_V2_SYNC),
0071 RX_FILTER(PTP_V2_DELAY_REQ),
0072 #undef RX_FILTER
0073 };
0074 #define N_RX_FILTERS ((int)(sizeof(rx_filters) / sizeof(rx_filters[0])))
0075
0076 static void usage(void)
0077 {
0078 fputs("Usage: hwtstamp_config if_name [tx_type rx_filter]\n"
0079 "tx_type is any of (case-insensitive):\n",
0080 stderr);
0081 list_names(stderr, tx_types, N_TX_TYPES);
0082 fputs("rx_filter is any of (case-insensitive):\n", stderr);
0083 list_names(stderr, rx_filters, N_RX_FILTERS);
0084 }
0085
0086 int main(int argc, char **argv)
0087 {
0088 struct ifreq ifr;
0089 struct hwtstamp_config config;
0090 const char *name;
0091 int sock;
0092
0093 if ((argc != 2 && argc != 4) || (strlen(argv[1]) >= IFNAMSIZ)) {
0094 usage();
0095 return 2;
0096 }
0097
0098 if (argc == 4) {
0099 config.flags = 0;
0100 config.tx_type = lookup_value(tx_types, N_TX_TYPES, argv[2]);
0101 config.rx_filter = lookup_value(rx_filters, N_RX_FILTERS, argv[3]);
0102 if (config.tx_type < 0 || config.rx_filter < 0) {
0103 usage();
0104 return 2;
0105 }
0106 }
0107
0108 sock = socket(AF_INET, SOCK_DGRAM, 0);
0109 if (sock < 0) {
0110 perror("socket");
0111 return 1;
0112 }
0113
0114 strcpy(ifr.ifr_name, argv[1]);
0115 ifr.ifr_data = (caddr_t)&config;
0116
0117 if (ioctl(sock, (argc == 2) ? SIOCGHWTSTAMP : SIOCSHWTSTAMP, &ifr)) {
0118 perror("ioctl");
0119 return 1;
0120 }
0121
0122 printf("flags = %#x\n", config.flags);
0123 name = lookup_name(tx_types, N_TX_TYPES, config.tx_type);
0124 if (name)
0125 printf("tx_type = %s\n", name);
0126 else
0127 printf("tx_type = %d\n", config.tx_type);
0128 name = lookup_name(rx_filters, N_RX_FILTERS, config.rx_filter);
0129 if (name)
0130 printf("rx_filter = %s\n", name);
0131 else
0132 printf("rx_filter = %d\n", config.rx_filter);
0133
0134 return 0;
0135 }