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>