summaryrefslogtreecommitdiffstats
path: root/iv/orodja/ldmitm/tcp_times.c
diff options
context:
space:
mode:
Diffstat (limited to 'iv/orodja/ldmitm/tcp_times.c')
-rw-r--r--iv/orodja/ldmitm/tcp_times.c117
1 files changed, 117 insertions, 0 deletions
diff --git a/iv/orodja/ldmitm/tcp_times.c b/iv/orodja/ldmitm/tcp_times.c
new file mode 100644
index 0000000..0996857
--- /dev/null
+++ b/iv/orodja/ldmitm/tcp_times.c
@@ -0,0 +1,117 @@
+/*
+Prevajanje: make
+Namestitev v jedro: insmod tcp_times.ko
+Uporaba v C:
+#include <stdint.h>
+#include "tcp_times.h"
+int tcp_times = open("/proc/tcp_times", O_RDWR);
+if (tcp_times == -1) {
+ perror("open tcp_times");
+ break;
+}
+int tcpsock = accept(boundsocket, &address, &addrlen);
+struct tcp_times tt = {
+ .fd = tcpsock
+};
+if (ioctl(tcp_times, 0, &tt) == -1) {
+ perror("ioctl tcp_times");
+ break;
+}
+// sedaj so polja v tt populirana
+*/
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/uaccess.h>
+#include <linux/fs.h>
+#include <linux/proc_fs.h>
+#include <linux/net.h>
+#include <linux/tcp.h>
+#include <linux/version.h>
+#include "tcp_times.h"
+#define MIN(a,b) (((a)<(b))?(a):(b))
+MODULE_AUTHOR("Anton Luka Šijanec <anton@sijanec.eu>");
+MODULE_DESCRIPTION("tcp last received tsval, rtt procfs ioctl driver");
+MODULE_LICENSE("");
+static struct proc_dir_entry * ent;
+static long myioctl (struct file * filep, unsigned int cmd, unsigned long arg) {
+ switch(cmd) {
+ case 0:
+ struct tcp_times tt;
+ if (copy_from_user(&tt, (void *) arg, sizeof tt))
+ return -EFAULT;
+ struct fd f = fdget(tt.fd);
+ if (!f.file)
+ return -EBADF;
+ struct socket * sock = sock_from_file(f.file);
+ if (!sock) {
+ fdput(f);
+ return -ENOTSOCK;
+ }
+ if (!(sock->type & SOCK_STREAM)) {
+ fdput(f);
+ return -ENOSTR;
+ }
+ if (!sock->sk) {
+ fdput(f);
+ return -EBADFD;
+ }
+ if (sock->sk->sk_protocol != IPPROTO_TCP) {
+ fdput(f);
+ return -ESOCKTNOSUPPORT;
+ }
+ struct tcp_sock * tp = tcp_sk(sock->sk);
+ tt.ts_recent_stamp = tp->rx_opt.ts_recent_stamp;
+ tt.ts_recent = tp->rx_opt.ts_recent;
+ tt.rcv_tsval = tp->rx_opt.rcv_tsval;
+ tt.rcv_tsecr = tp->rx_opt.rcv_tsecr;
+ tt.saw_tstamp = tp->rx_opt.saw_tstamp;
+ tt.tstamp_ok = tp->rx_opt.tstamp_ok;
+ tt.dsack = tp->rx_opt.dsack;
+ tt.wscale_ok = tp->rx_opt.wscale_ok;
+ tt.sack_ok = tp->rx_opt.sack_ok;
+ tt.smc_ok = tp->rx_opt.smc_ok;
+ tt.snd_wscale = tp->rx_opt.snd_wscale;
+ tt.rcv_wscale = tp->rx_opt.rcv_wscale;
+ tt.advmss = tp->advmss;
+ tt.rttvar_us = tp->rttvar_us;
+ tt.srtt_us = tp->srtt_us;
+ tt.rcv_rtt_est.rtt_us = tp->rcv_rtt_est.rtt_us;
+ tt.rcv_rtt_est.seq = tp->rcv_rtt_est.seq;
+ tt.rcv_rtt_est.time = tp->rcv_rtt_est.time;
+ tt.rtt_us = tp->rack.rtt_us;
+ tt.mdev_max_us = tp->mdev_max_us;
+ fdput(f);
+ if (copy_to_user((void *) arg, &tt, sizeof tt)) {
+ fdput(f);
+ return -EFAULT;
+ }
+ return 0;
+ default:
+ return -EINVAL;
+ }
+}
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5,6,0)
+static const struct file_operations ops = {
+ .owner = THIS_MODULE,
+ .unlocked_ioctl = myioctl,
+};
+#else
+static const struct proc_ops ops = {
+ .proc_ioctl = myioctl,
+};
+#endif
+static int __init custom_init (void) {
+ ent = proc_create("tcp_times", 0666, NULL, &ops);
+ if (!ent) {
+ printk(KERN_INFO "tcp_times failed to create procfs entry.");
+ return -EINVAL;
+ }
+ printk(KERN_INFO "tcp_times kernel module loaded.");
+ return 0;
+}
+static void __exit custom_exit (void) {
+ proc_remove(ent);
+ printk(KERN_INFO "tcp_times kernel module exiting ...");
+}
+module_init(custom_init);
+module_exit(custom_exit);