File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / trafshow / parse_ip.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 16:55:18 2012 UTC (12 years, 4 months ago) by misho
Branches: trafshow, MAIN
CVS tags: v5_2_3p0, v5_2_3, HEAD
trafshow

    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>