From 5e70c95ade7cbda75a632d9b6f71f19d5b3b383d Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Sun, 12 Jul 2015 18:05:07 +0200 Subject: [PATCH] latest revision of project code --- project/Makefile | 2 +- project/main.c | 14 ++-- project/probe.c | 171 ++++++++++++++++++++++++++++++++++++----------- project/tc.c | 12 ++++ 4 files changed, 155 insertions(+), 44 deletions(-) create mode 100644 project/tc.c diff --git a/project/Makefile b/project/Makefile index e516727..f314f84 100644 --- a/project/Makefile +++ b/project/Makefile @@ -3,7 +3,7 @@ TARGET = netem OBJS = main.o probe.o CC = gcc -CFLAGS = -g -lrt +CFLAGS = -g -lrt -std=c99 -Wall all: $(TARGET) Makefile diff --git a/project/main.c b/project/main.c index b490486..b412057 100644 --- a/project/main.c +++ b/project/main.c @@ -1,20 +1,26 @@ +#define _POSIX_C_SOURCE 199309L + #include #include +#include +#include +#include +#include + #include #include -#include -#include - #define VERSION "0.1" int running = 1; +int probe(); + void quit(int sig, siginfo_t *si, void *ptr) { printf("Goodbye!\n"); - running = 0; + exit(0); } int main(int argc, char *argv[]) diff --git a/project/probe.c b/project/probe.c index e29dd1a..99635ce 100644 --- a/project/probe.c +++ b/project/probe.c @@ -1,8 +1,95 @@ +#define _POSIX_C_SOURCE 199309L + #include #include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include #include #include +#include +#include + + +#define SIOCSHWTSTAMP 0x89b0 +#define SIOCGHWTSTAMP 0x89b1 + +void print_ts(struct timespec *ts) +{ + printf("%lld.%.9ld\n", (long long) ts->tv_sec, ts->tv_nsec); +} + +int if_enable_ts(const char *dev) +{ + struct hwtstamp_config tsc = { + .flags = 0, + .tx_type = HWTSTAMP_TX_ON, + .rx_filter = HWTSTAMP_FILTER_ALL + }; + struct ifreq ifr = { + .ifr_data = (void *) &tsc + }; + + strncpy(ifr.ifr_name, dev, IFNAMSIZ); + + int sd = socket(AF_INET, SOCK_DGRAM, 0); + if (sd < 0) + error(-1, errno, "Failed to create socket"); + + if (ioctl(sd, SIOCSHWTSTAMP, &ifr)) + error(-1, errno, "Failed to enable timestamping"); + + close(sd); + + return 0; +} + +int recvmsg_ts(int sd, struct msghdr *msgh, int flags, struct timespec *ts, int *key, int *id) +{ + char buf[1024]; + msgh->msg_control = &buf; + msgh->msg_controllen = sizeof(buf); + + struct cmsghdr *cmsg; + struct sock_extended_err *serr = NULL; + struct timespec *tss = NULL; + + int ret = recvmsg(sd, msgh, flags); + if (ret >= 0) { + for (cmsg = CMSG_FIRSTHDR(msgh); cmsg != NULL; cmsg = CMSG_NXTHDR(msgh, cmsg)) { + if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_TIMESTAMPING) + tss = (struct timespec *) CMSG_DATA(cmsg); + else if ((cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_RECVERR) || + (cmsg->cmsg_level == SOL_IPV6 && cmsg->cmsg_type == IPV6_RECVERR)) + serr = (struct sock_extended_err *) CMSG_DATA(cmsg); + } + + if (!tss) + return -2; + + for (int i = 0; i < 3; i++) + ts[i] = tss[i]; + + if (serr) { + *key = serr->ee_info; + *id = serr->ee_data; + } + } + + return ret; +} int probe() { @@ -10,51 +97,57 @@ int probe() printf("Start probing\n"); + //if_enable_ts("lo"); + /* Create RAW socket */ - int sd = socket(AF_INET, SOCK_RAW, IPPROTO_TCP); + int sd = socket(AF_INET, SOCK_RAW, 88); + if (sd < 0) + error(-1, errno, "Failed to create socket"); /* Enable kernel / hw timestamping */ - val = SOF_TIMESTAMPING_RX_HARDWARE | SOF_TIMESTAMPING_RX_SOFTWARE; /* Enable RX timestamps */ - val |= SOF_TIMESTAMPING_TX_HARDWARE | SOF_TIMESTAMPING_TX_SOFTWARE; /* Enable TX timestamps */ - - val |= SOF_TIMESTAMPING_SOFTWARE | SOF_TIMESTAMPING_RAW_HARDWARE; /* Report SW and HW timestamps */ - - val |= SOF_TIMESTAMPING_OPT_TSONLY; /* Only return timestamp in cmsg */ + val = SOF_TIMESTAMPING_RX_SOFTWARE | SOF_TIMESTAMPING_TX_SOFTWARE; /* Enable SW timestamps */ +// val |= SOF_TIMESTAMPING_TX_HARDWARE | SOF_TIMESTAMPING_RX_HARDWARE; /* Enable HW timestamps */ + val |= SOF_TIMESTAMPING_SOFTWARE; //| SOF_TIMESTAMPING_RAW_HARDWARE; /* Report SW and HW timestamps */ +// val |= SOF_TIMESTAMPING_OPT_TSONLY; /* Only return timestamp in cmsg */ - if (setsockopt(fd, SOL_SOCKET, SO_TIMESTAMPING, (void *) val, &val)) + if (setsockopt(sd, SOL_SOCKET, SO_TIMESTAMPING, (void *) &val, sizeof(val))) error(-1, errno, "Failed to set SO_TIMESTAMPING"); + struct timespec ts[3]; + struct sockaddr_in sa = { + .sin_family = AF_INET, + .sin_port = htons(7), + }; + struct msghdr msgh = { + .msg_name = (struct sockaddr *) &sa, + .msg_namelen = sizeof(sa) + }; + + inet_aton("8.8.8.8", &sa.sin_addr); + + //if (sendto(sd, "test", sizeof("test"), 0, (struct sockaddr*) &sa, sizeof(sa)) == -1) + // error(-1, errno, "Failed to send"); + + enum direction { TX, RX } dir = RX; + + /* Polling for new timestamps */ + struct pollfd pfd = { + .fd = sd, + .events = POLLIN + }; +retry: if (poll(&pfd, 1, 10000) < 0) + error(-1, errno, "Failed poll"); + if ((dir == TX) && !(pfd.revents & POLLERR)) + goto retry; + + int id, key; + if (recvmsg_ts(sd, &msgh, (dir == TX) ? MSG_ERRQUEUE : 0, ts, &key, &id) < 0) + error(-1, errno, "Failed to receive TS"); + + printf("Received key=%d, id=%d\n", key, id); + + for (int i = 0; i < 3; i++) + print_ts(&ts[i]); return 0; } - -int probe_read_ts(int sd) -{ - char cmsg[1024]; - struct msghdr msgh = { - .msg_name = NULL, .msg_namelen = 0, - .msg_iov = NULL, .msg_iovlen = 0, - .msg_control = &cmsg, .msg_controllen = sizeof(cmsg) - }; - struct cmsghdr *cmsg; - struct timespec *ts; - - if (recvmsg(sd, &msgh, 0) == -1) - error(-1, errno, "Failed to get control messages"); - - /* Receive auxiliary data in msgh */ - for (cmsg = CMSG_FIRSTHDR(&msgh); cmsg != NULL; cmsg = CMSG_NXTHDR(&msgh,cmsg)) { - if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_TIMESTAMPING) { - ts = (struct timespec*) CMSG_DATA(cmsg); - break; - } - } - if (cmsg == NULL) - error(-1, 0, "SO_TIMESTAMPING not enabled or small buffer or I/O error."); - - if (ts) { - for (int i = 0; i < 3; i++) { - print_ts(&ts[i]); - } - } -} \ No newline at end of file diff --git a/project/tc.c b/project/tc.c new file mode 100644 index 0000000..4264110 --- /dev/null +++ b/project/tc.c @@ -0,0 +1,12 @@ + + + +int netem_update(struct netem *ne) +{ + +} + +int netem_create(struct netem *ne) +{ + +} \ No newline at end of file