/* Prevajanje: make Namestitev v jedro: insmod tcp_times.ko Uporaba v C: #include #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 #include #include #include #include #include #include #include #include "tcp_times.h" #define MIN(a,b) (((a)<(b))?(a):(b)) MODULE_AUTHOR("Anton Luka Šijanec "); 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);