Annotation of embedaddon/trafshow/parse_ip.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  *     Copyright (c) 2004 Rinet Corp., Novosibirsk, Russia
                      3:  *
                      4:  * Redistribution and use in source forms, with and without modification,
                      5:  * are permitted provided that this entire comment appears intact.
                      6:  *
                      7:  * THIS SOURCE CODE IS PROVIDED ``AS IS'' WITHOUT ANY WARRANTIES OF ANY KIND.
                      8:  */
                      9: 
                     10: #ifdef HAVE_CONFIG_H
                     11: #include <config.h>
                     12: #endif
                     13: 
                     14: #include <sys/types.h>
                     15: #include <sys/socket.h>
                     16: #include <netinet/in.h>
                     17: #include <netinet/in_systm.h>
                     18: #include <netinet/ip.h>
                     19: #include <netinet/ip_icmp.h>
                     20: #include <netinet/udp.h>
                     21: #include <netinet/tcp.h>
                     22: #ifdef INET6
                     23: #include <netinet/ip6.h>
                     24: #include <netinet/icmp6.h>
                     25: #endif
                     26: 
                     27: #include "parse_ip.h"
                     28: #include "netstat.h"
                     29: 
                     30: 
                     31: int
                     32: parse_ip(ns, caplen, ip)
                     33:        NETSTAT *ns;
                     34:        int caplen;
                     35:        const struct ip *ip;
                     36: {
                     37:        int hdrlen = 0, len;
                     38:        const u_char *p;
                     39: 
                     40:        /* sanity check */
                     41:        if (!ip) return -1;
                     42: 
                     43:        if (ns) ns->ip_ver = ip->ip_v;
                     44: 
                     45:        if (ip->ip_v == 4) {
                     46:                struct ip_address *src = 0, *dst = 0;
                     47:                if (ns) {
                     48:                        src = &ns->ip_src_addr;
                     49:                        dst = &ns->ip_dst_addr;
                     50: 
                     51:                        ns->ip_proto = ip->ip_p;
                     52:                        src->ip_addr = ip->ip_src;
                     53:                        dst->ip_addr = ip->ip_dst;
                     54: 
                     55:                        ns->pkt_len = ntohs(ip->ip_len);
                     56:                }
                     57:                hdrlen = ip->ip_hl << 2;
                     58:                caplen -= hdrlen;
                     59:                if ((ntohs(ip->ip_off) & 0x1fff) == 0) {
                     60:                        p = (const u_char *)ip + hdrlen;
                     61:                        switch (ip->ip_p) {
                     62:                        case IPPROTO_TCP:
                     63: #if defined(linux)
                     64:                                len = ((const struct tcphdr *)p)->doff << 2;
                     65: #else
                     66:                                len = ((const struct tcphdr *)p)->th_off << 2;
                     67: #endif
                     68:                                hdrlen += len;
                     69:                                caplen -= len;
                     70:                                if (caplen >= 0 && src && dst) {
                     71: #if defined(linux)
                     72:                                        src->ip_port = ((const struct tcphdr *)p)->source;
                     73:                                        dst->ip_port = ((const struct tcphdr *)p)->dest;
                     74: #else
                     75:                                        src->ip_port = ((const struct tcphdr *)p)->th_sport;
                     76:                                        dst->ip_port = ((const struct tcphdr *)p)->th_dport;
                     77: #endif
                     78:                                }
                     79:                                break;
                     80:                        case IPPROTO_UDP:
                     81:                                len = sizeof(struct udphdr);
                     82:                                hdrlen += len;
                     83:                                caplen -= len;
                     84:                                if (caplen >= 0 && src && dst) {
                     85: #if defined(linux)
                     86:                                        src->ip_port = ((const struct udphdr *)p)->source;
                     87:                                        dst->ip_port = ((const struct udphdr *)p)->dest;
                     88: #else
                     89:                                        src->ip_port = ((const struct udphdr *)p)->uh_sport;
                     90:                                        dst->ip_port = ((const struct udphdr *)p)->uh_dport;
                     91: #endif
                     92:                                }
                     93:                                break;
                     94:                        case IPPROTO_ICMP:
                     95:                                len = (u_char *)((const struct icmp *)p)->icmp_data - p;
                     96:                                hdrlen += len;
                     97:                                caplen -= len;
                     98:                                if (caplen >= 0 && src) {
                     99:                                        src->ip_port =
                    100:                                        ((((const struct icmp *)p)->icmp_type << 8) |
                    101:                                         ((const struct icmp *)p)->icmp_code) + 1;
                    102:                                }
                    103:                                break;
                    104:                        }
                    105:                }
                    106:        }
                    107: #ifdef INET6
                    108:        else if (ip->ip_v == 6) {
                    109:                struct ip6_hdr *ip6 = (struct ip6_hdr *)ip;
                    110:                struct ip_address *src = 0, *dst = 0;
                    111:                if (ns) {
                    112:                        src = &ns->ip_src_addr;
                    113:                        dst = &ns->ip_dst_addr;
                    114: 
                    115:                        ns->ip_proto = ip6->ip6_nxt;
                    116:                        src->ip6_addr = ip6->ip6_src;
                    117:                        dst->ip6_addr = ip6->ip6_dst;
                    118: 
                    119:                        ns->pkt_len = sizeof(struct ip6_hdr) + ntohs(ip6->ip6_plen);
                    120:                }
                    121:                hdrlen = sizeof(struct ip6_hdr);
                    122:                caplen -= hdrlen;
                    123:                p = (const u_char *)ip6 + hdrlen;
                    124:                switch (ip6->ip6_nxt) {
                    125:                case IPPROTO_TCP:
                    126: #if defined(linux)
                    127:                        len = ((const struct tcphdr *)p)->doff << 2;
                    128: #else
                    129:                        len = ((const struct tcphdr *)p)->th_off << 2;
                    130: #endif
                    131:                        hdrlen += len;
                    132:                        caplen -= len;
                    133:                        if (caplen >= 0 && src && dst) {
                    134: #if defined(linux)
                    135:                                src->ip_port = ((const struct tcphdr *)p)->source;
                    136:                                dst->ip_port = ((const struct tcphdr *)p)->dest;
                    137: #else
                    138:                                src->ip_port = ((const struct tcphdr *)p)->th_sport;
                    139:                                dst->ip_port = ((const struct tcphdr *)p)->th_dport;
                    140: #endif
                    141:                        }
                    142:                        break;
                    143:                case IPPROTO_UDP:
                    144:                        len = sizeof(struct udphdr);
                    145:                        hdrlen += len;
                    146:                        caplen -= len;
                    147:                        if (caplen >= 0 && src && dst) {
                    148: #if defined(linux)
                    149:                                src->ip_port = ((const struct udphdr *)p)->source;
                    150:                                dst->ip_port = ((const struct udphdr *)p)->dest;
                    151: #else
                    152:                                src->ip_port = ((const struct udphdr *)p)->uh_sport;
                    153:                                dst->ip_port = ((const struct udphdr *)p)->uh_dport;
                    154: #endif
                    155:                        }
                    156:                        break;
                    157:                case IPPROTO_ICMPV6:
                    158:                        len = sizeof(struct icmp6_hdr);
                    159:                        hdrlen += len;
                    160:                        caplen -= len;
                    161:                        if (caplen >= 0 && src) {
                    162:                                src->ip_port =
                    163:                                ((((const struct icmp6_hdr *)p)->icmp6_type << 8) |
                    164:                                 ((const struct icmp6_hdr *)p)->icmp6_code) + 1;
                    165:                        }
                    166:                        break;
                    167:                }
                    168:        }
                    169: #endif
                    170:        else {
                    171:                /* unknown IP version */
                    172:                return -1;
                    173:        }
                    174: 
                    175:        if (ns) {
                    176:                ns->pkt_cnt = 1;
                    177:                if (ns->pkt_len >= hdrlen)
                    178:                        ns->data_len = ns->pkt_len - hdrlen;
                    179:        }
                    180:        return hdrlen;
                    181: }
                    182: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>