From a96272b12ac8e033012355506797466b8ed8a24d Mon Sep 17 00:00:00 2001 From: Beraldo Leal Date: Sun, 21 Jul 2013 12:18:06 -0400 Subject: [PATCH] support to transport layer --- inode.c | 42 +++++++++---------- proto.c | 122 ++++++++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 117 insertions(+), 47 deletions(-) diff --git a/inode.c b/inode.c index 40546c4..5f63faf 100644 --- a/inode.c +++ b/inode.c @@ -75,37 +75,37 @@ static ssize_t netsfs_read_stream(struct file *file, char __user *buf, struct sk_buff *skb; char stream_buf[STREAM_BUF_LEN]; - char *mac_string, *network_string; - size_t ret = 0, size = 0; - + char *mac_string, *network_string, *transport_string; + size_t ret = 0; -/* if (*ppos != 0) return 0; -*/ spin_lock(&file->f_dentry->d_parent->d_inode->i_lock); d_private = file->f_dentry->d_parent->d_inode->i_private; skb = cq_get(&d_private->queue_skbuff); + spin_unlock(&file->f_dentry->d_parent->d_inode->i_lock); if (skb) { -// mac_string = kmalloc(sizeof(char)*80, GFP_KERNEL); -// network_string = kmalloc(sizeof(char)*80, GFP_KERNEL); -// -// get_mac_string(mac_string, skb); -// get_network_string(network_string, skb); -// -// ret = sprintf(stream_buf, "%s\n%s\n", mac_string, network_string); -// -// if (ret > 0) -// ret = simple_read_from_buffer(buf, count, ppos, stream_buf, ret); -// + mac_string = kmalloc(sizeof(char)*80, GFP_KERNEL); + network_string = kmalloc(sizeof(char)*80, GFP_KERNEL); + transport_string = kmalloc(sizeof(char)*80, GFP_KERNEL); + + get_mac_string(mac_string, skb); + get_network_string(network_string, skb); + get_transport_string(transport_string, skb); + + ret = sprintf(stream_buf, "%s\n%s\n%s\n", mac_string, + network_string, + transport_string); + + if (ret > 0) + ret = simple_read_from_buffer(buf, count, ppos, stream_buf, ret); + dev_kfree_skb(skb); -// if (mac_string) kfree(mac_string); -// if (network_string) kfree(network_string); -// kfree(dst); -// kfree(network); + if (mac_string) kfree(mac_string); + if (network_string) kfree(network_string); + if (transport_string) kfree(transport_string); } - spin_unlock(&file->f_dentry->d_parent->d_inode->i_lock); return ret; } diff --git a/proto.c b/proto.c index 1b541d8..7fdf5c7 100644 --- a/proto.c +++ b/proto.c @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -34,6 +35,24 @@ enum { DST_ADDRESS = 1, }; +/* Return the Ethernet Packet "Type" field in string. + */ +char *get_ether_type(struct sk_buff *skb) +{ + switch (ntohs(eth_hdr(skb)->h_proto)) + { + case ETH_P_IP: + return "ipv4"; + break; + case ETH_P_IPV6: + return "ipv6"; + break; + default: + return "unknow"; + break; + } +} + int get_ipv4_address(char *ip, struct sk_buff *skb, __u8 type) { struct iphdr *iphdr; @@ -178,10 +197,82 @@ char *get_ip_protocol(struct sk_buff *skb) return "unknow1"; } +int get_ipv4_icmp_string(char *str, struct icmphdr *icmph) +{ + sprintf(str, "[ TRANSPORT ] type: %u, code: %u", icmph->type, icmph->code); + return 0; +} + +int get_ipv4_udp_string(char *str, struct udphdr *udph) +{ + sprintf(str, "[ TRANSPORT ] %d -> %d", ntohs(udph->source), + ntohs(udph->dest)); + return 0; +} + +int get_ipv4_tcp_string(char *str, struct tcphdr *tcph) +{ + + sprintf(str, "[ TRANSPORT ] %d -> %d", ntohs(tcph->source), + ntohs(tcph->dest)); + + if (tcph->fin == 1) strcat(str, "[FIN]"); + if (tcph->syn == 1) strcat(str, "[SYN]"); + if (tcph->rst == 1) strcat(str, "[RST]"); + if (tcph->psh == 1) strcat(str, "[PSH]"); + if (tcph->ack == 1) strcat(str, "[ACK]"); + if (tcph->urg == 1) strcat(str, "[URG]"); + if (tcph->ece == 1) strcat(str, "[ECE]"); + if (tcph->cwr == 1) strcat(str, "[CWR]"); + + return 0; +} + +int get_ipv4_string(char *str, struct sk_buff *skb) +{ + struct tcphdr *tcphdr; + struct udphdr *udphdr; + struct icmphdr *icmphdr; + + struct iphdr *iph; + + iph = ip_hdr(skb); + + switch (iph->protocol) + { + case IPPROTO_ICMP: + icmphdr = (struct icmphdr *)((__u32 *)iph + iph->ihl); + return get_ipv4_icmp_string(str, icmphdr); + break; + case IPPROTO_TCP: + tcphdr = (struct tcphdr *)((__u32 *)iph + iph->ihl); + return get_ipv4_tcp_string(str, tcphdr); + break; + case IPPROTO_UDP: + udphdr = (struct udphdr *)((__u32 *)iph + iph->ihl); + return get_ipv4_udp_string(str, udphdr); + break; + default: + sprintf(str, "[ TRANPORT ] unknow"); + break; + } + return 0; +} + int get_transport_string(char *str, struct sk_buff *skb) { - sprintf(str, "[TRANSPORT] ************* "); + struct ethhdr *eth; + eth = eth_hdr(skb); + + switch (ntohs(eth->h_proto)) { + case ETH_P_IP: + return get_ipv4_string(str, skb); + case ETH_P_IPV6: + default: + sprintf(str, "[ TRANSPORT ] unknow"); + break; + } return 0; } @@ -192,10 +283,6 @@ int get_network_string(char *str, struct sk_buff *skb) struct iphdr *iphdr; char *src, *dst; - sprintf(str, "[NETWORK]"); - return 0; - - iphdr = ip_hdr(skb); src = kmalloc(sizeof(char)*35, GFP_KERNEL); @@ -204,7 +291,7 @@ int get_network_string(char *str, struct sk_buff *skb) get_ip_address(src, skb, SRC_ADDRESS); get_ip_address(dst, skb, DST_ADDRESS); - sprintf(str, "[ NETWORK ] version: %d, tos: %02x, id: %04x, protocol: %s, %s -> %s", + sprintf(str, "[ NETWORK ] version: %d, tos: %02x, id: %04x, protocol: %s, %s -> %s", iphdr->version, iphdr->tos, iphdr->id, @@ -219,11 +306,11 @@ int get_network_string(char *str, struct sk_buff *skb) int get_mac_string(char *str, struct sk_buff *skb) { - sprintf(str, "[ MAC ] ts: %llu, dev: %s, len: %d", + sprintf(str, "[ MAC ] ts: %llu, dev: %s, len: %d, type: %s", skb->tstamp.tv64, skb->dev->name, - skb->len); -// get_ether_type(skb)); + skb->len, + get_ether_type(skb)); return 0; } @@ -277,23 +364,6 @@ int get_dst_mac(char *dst, struct sk_buff *skb) } -/* Return the Ethernet Packet "Type" field in string. - */ -char *get_ether_type(struct sk_buff *skb) -{ - switch (ntohs(eth_hdr(skb)->h_proto)) - { - case ETH_P_IP: - return "ipv4"; - break; - case ETH_P_IPV6: - return "ipv6"; - break; - default: - return "unknow"; - break; - } -}