2 * Copyright (C) 1993-2001 by Darren Reed.
4 * See the IPFILTER.LICENCE file for details on licencing.
6 * Added redirect stuff and a variety of bug fixes. (mcn@EnGarde.com)
8 #if defined(__sgi) && (IRIX > 602)
9 # include <sys/ptimers.h>
15 #include <sys/types.h>
16 #if !defined(__SVR4) && !defined(__svr4__)
19 #include <sys/byteorder.h>
22 #include <sys/param.h>
26 #include <sys/socket.h>
27 #include <sys/ioctl.h>
28 #if defined(sun) && (defined(__svr4__) || defined(__SVR4))
29 # include <sys/ioccom.h>
30 # include <sys/sysmacros.h>
32 #include <netinet/in.h>
33 #include <netinet/in_systm.h>
34 #include <netinet/ip.h>
35 #include <netinet/tcp.h>
37 #if __FreeBSD_version >= 300000
38 # include <net/if_var.h>
41 #include <arpa/nameser.h>
42 #include <arpa/inet.h>
45 #include "netinet/ip_compat.h"
46 #include "netinet/ip_fil.h"
47 #include "netinet/ip_nat.h"
48 #include "netinet/ip_state.h"
49 #include "netinet/ip_proxy.h"
53 #if defined(sun) && !SOLARIS2
54 # define STRERROR(x) sys_errlist[x]
55 extern char *sys_errlist
[];
57 # define STRERROR(x) strerror(x)
61 static const char rcsid
[] = "@(#)$Id: printnat.c,v 1.1.2.15 2003/03/22 15:31:49 darrenr Exp $";
66 #define bzero(a,b) memset(a,0,b)
72 extern char thishost
[MAXHOSTNAMELEN
];
74 extern int countbits
__P((u_32_t
));
76 void printnat
__P((ipnat_t
*, int));
77 char *getnattype
__P((ipnat_t
*));
78 void printactivenat
__P((nat_t
*, int));
79 void printhostmap
__P((hostmap_t
*, u_int
));
80 char *getsumd
__P((u_32_t
));
82 static void printaps
__P((ap_session_t
*, int));
84 static void printaps(aps
, opts
)
94 if (kmemcpy((char *)&ap
, (long)aps
, sizeof(ap
)))
96 if (kmemcpy((char *)&apr
, (long)ap
.aps_apr
, sizeof(apr
)))
98 printf("\tproxy %s/%d use %d flags %x\n", apr
.apr_label
,
99 apr
.apr_p
, apr
.apr_ref
, apr
.apr_flags
);
100 printf("\t\tproto %d flags %#x bytes ", ap
.aps_p
, ap
.aps_flags
);
102 printf("%qu pkts %qu", (unsigned long long)ap
.aps_bytes
,
103 (unsigned long long)ap
.aps_pkts
);
105 printf("%lu pkts %lu", ap
.aps_bytes
, ap
.aps_pkts
);
107 printf(" data %s size %d\n", ap
.aps_data
? "YES" : "NO", ap
.aps_psiz
);
108 if ((ap
.aps_p
== IPPROTO_TCP
) && (opts
& OPT_VERBOSE
)) {
109 printf("\t\tstate[%u,%u], sel[%d,%d]\n",
110 ap
.aps_state
[0], ap
.aps_state
[1],
111 ap
.aps_sel
[0], ap
.aps_sel
[1]);
112 #if (defined(NetBSD) && (NetBSD >= 199905) && (NetBSD < 1991011)) || \
113 (__FreeBSD_version >= 300000) || defined(OpenBSD)
114 printf("\t\tseq: off %hd/%hd min %x/%x\n",
115 ap
.aps_seqoff
[0], ap
.aps_seqoff
[1],
116 ap
.aps_seqmin
[0], ap
.aps_seqmin
[1]);
117 printf("\t\tack: off %hd/%hd min %x/%x\n",
118 ap
.aps_ackoff
[0], ap
.aps_ackoff
[1],
119 ap
.aps_ackmin
[0], ap
.aps_ackmin
[1]);
121 printf("\t\tseq: off %hd/%hd min %lx/%lx\n",
122 ap
.aps_seqoff
[0], ap
.aps_seqoff
[1],
123 ap
.aps_seqmin
[0], ap
.aps_seqmin
[1]);
124 printf("\t\tack: off %hd/%hd min %lx/%lx\n",
125 ap
.aps_ackoff
[0], ap
.aps_ackoff
[1],
126 ap
.aps_ackmin
[0], ap
.aps_ackmin
[1]);
130 if (!strcmp(apr
.apr_label
, "raudio") && ap
.aps_psiz
== sizeof(ra
)) {
131 if (kmemcpy((char *)&ra
, (long)ap
.aps_data
, sizeof(ra
)))
133 printf("\tReal Audio Proxy:\n");
134 printf("\t\tSeen PNA: %d\tVersion: %d\tEOS: %d\n",
135 ra
.rap_seenpna
, ra
.rap_version
, ra
.rap_eos
);
136 printf("\t\tMode: %#x\tSBF: %#x\n", ra
.rap_mode
, ra
.rap_sbf
);
137 printf("\t\tPorts:pl %hu, pr %hu, sr %hu\n",
138 ra
.rap_plport
, ra
.rap_prport
, ra
.rap_srport
);
139 } else if (!strcmp(apr
.apr_label
, "ftp") &&
140 (ap
.aps_psiz
== sizeof(ftp
))) {
141 if (kmemcpy((char *)&ftp
, (long)ap
.aps_data
, sizeof(ftp
)))
143 printf("\tFTP Proxy:\n");
144 printf("\t\tpassok: %d\n", ftp
.ftp_passok
);
145 ftp
.ftp_side
[0].ftps_buf
[FTP_BUFSZ
- 1] = '\0';
146 ftp
.ftp_side
[1].ftps_buf
[FTP_BUFSZ
- 1] = '\0';
147 printf("\tClient:\n");
148 printf("\t\tseq %08x%08x len %d junk %d cmds %d\n",
149 ftp
.ftp_side
[0].ftps_seq
[1],
150 ftp
.ftp_side
[0].ftps_seq
[0],
151 ftp
.ftp_side
[0].ftps_len
,
152 ftp
.ftp_side
[0].ftps_junk
, ftp
.ftp_side
[0].ftps_cmds
);
154 printbuf(ftp
.ftp_side
[0].ftps_buf
, FTP_BUFSZ
, 1);
155 printf("]\n\tServer:\n");
156 printf("\t\tseq %08x%08x len %d junk %d cmds %d\n",
157 ftp
.ftp_side
[1].ftps_seq
[1],
158 ftp
.ftp_side
[1].ftps_seq
[0],
159 ftp
.ftp_side
[1].ftps_len
,
160 ftp
.ftp_side
[1].ftps_junk
, ftp
.ftp_side
[1].ftps_cmds
);
162 printbuf(ftp
.ftp_side
[1].ftps_buf
, FTP_BUFSZ
, 1);
164 } else if (!strcmp(apr
.apr_label
, "ipsec") &&
165 (ap
.aps_psiz
== sizeof(ipsec
))) {
166 if (kmemcpy((char *)&ipsec
, (long)ap
.aps_data
, sizeof(ipsec
)))
168 printf("\tIPSec Proxy:\n");
169 printf("\t\tICookie %08x%08x RCookie %08x%08x %s\n",
170 (u_int
)ntohl(ipsec
.ipsc_icookie
[0]),
171 (u_int
)ntohl(ipsec
.ipsc_icookie
[1]),
172 (u_int
)ntohl(ipsec
.ipsc_rcookie
[0]),
173 (u_int
)ntohl(ipsec
.ipsc_rcookie
[1]),
174 ipsec
.ipsc_rckset
? "(Set)" : "(Not set)");
180 * Get a nat filter type given its kernel address.
182 char *getnattype(ipnat
)
185 static char unknownbuf
[20];
189 if (!ipnat
|| (ipnat
&& kmemcpy((char *)&ipnatbuff
, (long)ipnat
,
193 switch (ipnatbuff
.in_redir
)
208 sprintf(unknownbuf
, "unknown(%04x)",
209 ipnatbuff
.in_redir
& 0xffffffff);
217 void printactivenat(nat
, opts
)
223 printf("%s %-15s", getnattype(nat
->nat_ptr
), inet_ntoa(nat
->nat_inip
));
225 if ((nat
->nat_flags
& IPN_TCPUDP
) != 0)
226 printf(" %-5hu", ntohs(nat
->nat_inport
));
228 printf(" <- -> %-15s",inet_ntoa(nat
->nat_outip
));
230 if ((nat
->nat_flags
& IPN_TCPUDP
) != 0)
231 printf(" %-5hu", ntohs(nat
->nat_outport
));
233 printf(" [%s", inet_ntoa(nat
->nat_oip
));
234 if ((nat
->nat_flags
& IPN_TCPUDP
) != 0)
235 printf(" %hu", ntohs(nat
->nat_oport
));
238 if (opts
& OPT_VERBOSE
) {
239 printf("\n\tage %lu use %hu sumd %s/",
240 nat
->nat_age
, nat
->nat_use
, getsumd(nat
->nat_sumd
[0]));
241 hv1
= NAT_HASH_FN(nat
->nat_inip
.s_addr
, nat
->nat_inport
,
243 hv1
= NAT_HASH_FN(nat
->nat_oip
.s_addr
, hv1
+ nat
->nat_oport
,
245 hv2
= NAT_HASH_FN(nat
->nat_outip
.s_addr
, nat
->nat_outport
,
247 hv2
= NAT_HASH_FN(nat
->nat_oip
.s_addr
, hv2
+ nat
->nat_oport
,
249 printf("%s pr %u bkt %d/%d flags %x drop %d/%d\n",
250 getsumd(nat
->nat_sumd
[1]), nat
->nat_p
,
251 hv1
, hv2
, nat
->nat_flags
,
252 nat
->nat_drop
[0], nat
->nat_drop
[1]);
253 printf("\tifp %s ", getifname(nat
->nat_ifp
));
255 printf("bytes %qu pkts %qu",
256 (unsigned long long)nat
->nat_bytes
,
257 (unsigned long long)nat
->nat_pkts
);
259 printf("bytes %lu pkts %lu", nat
->nat_bytes
, nat
->nat_pkts
);
262 printf(" %lx", nat
->nat_ipsumd
);
268 printaps(nat
->nat_aps
, opts
);
272 void printhostmap(hmp
, hv
)
276 printf("%s -> ", inet_ntoa(hmp
->hm_realip
));
277 printf("%s ", inet_ntoa(hmp
->hm_mapip
));
278 printf("(use = %d hv = %u)\n", hmp
->hm_ref
, hv
);
285 static char sumdbuf
[17];
287 if (sum
& NAT_HW_CKSUM
)
288 sprintf(sumdbuf
, "hw(%#0x)", sum
& 0xffff);
290 sprintf(sumdbuf
, "%#0x", sum
);
296 * Print out a NAT rule
298 void printnat(np
, opts
)
306 pr
= getprotobynumber(np
->in_p
);
308 switch (np
->in_redir
)
323 fprintf(stderr
, "unknown value for in_redir: %#x\n",
328 printf(" %s ", np
->in_ifname
);
330 if (np
->in_flags
& IPN_FILTER
) {
331 if (np
->in_flags
& IPN_NOTSRC
)
334 if (np
->in_redir
== NAT_REDIRECT
) {
335 printhostmask(4, (u_32_t
*)&np
->in_srcip
,
336 (u_32_t
*)&np
->in_srcmsk
);
338 printhostmask(4, (u_32_t
*)&np
->in_inip
,
339 (u_32_t
*)&np
->in_inmsk
);
342 printportcmp(np
->in_p
, &np
->in_tuc
.ftu_src
);
344 if (np
->in_flags
& IPN_NOTDST
)
347 if (np
->in_redir
== NAT_REDIRECT
) {
348 printhostmask(4, (u_32_t
*)&np
->in_outip
,
349 (u_32_t
*)&np
->in_outmsk
);
351 printhostmask(4, (u_32_t
*)&np
->in_srcip
,
352 (u_32_t
*)&np
->in_srcmsk
);
355 printportcmp(np
->in_p
, &np
->in_tuc
.ftu_dst
);
358 if (np
->in_redir
== NAT_REDIRECT
) {
359 if (!(np
->in_flags
& IPN_FILTER
)) {
360 printf("%s", inet_ntoa(np
->in_out
[0]));
361 bits
= countbits(np
->in_out
[1].s_addr
);
363 printf("/%d ", bits
);
365 printf("/%s ", inet_ntoa(np
->in_out
[1]));
366 printf("port %d", ntohs(np
->in_pmin
));
367 if (np
->in_pmax
!= np
->in_pmin
)
368 printf("- %d", ntohs(np
->in_pmax
));
370 printf(" -> %s", inet_ntoa(np
->in_in
[0]));
371 if (np
->in_flags
& IPN_SPLIT
)
372 printf(",%s", inet_ntoa(np
->in_in
[1]));
373 printf(" port %d", ntohs(np
->in_pnext
));
374 if ((np
->in_flags
& IPN_TCPUDP
) == IPN_TCPUDP
)
376 else if ((np
->in_flags
& IPN_TCP
) == IPN_TCP
)
378 else if ((np
->in_flags
& IPN_UDP
) == IPN_UDP
)
380 else if (np
->in_p
== 0)
382 else if (np
->in_p
!= 0) {
384 printf(" %s", pr
->p_name
);
386 printf(" %d", np
->in_p
);
388 if (np
->in_flags
& IPN_ROUNDR
)
389 printf(" round-robin");
390 if (np
->in_flags
& IPN_FRAG
)
393 printf(" age %d/%d", np
->in_age
[0], np
->in_age
[1]);
395 printf(" mssclamp %u", np
->in_mssclamp
);
397 if (opts
& OPT_DEBUG
)
398 printf("\tspc %lu flg %#x max %u use %d\n",
399 np
->in_space
, np
->in_flags
,
400 np
->in_pmax
, np
->in_use
);
402 if (!(np
->in_flags
& IPN_FILTER
)) {
403 printf("%s/", inet_ntoa(np
->in_in
[0]));
404 bits
= countbits(np
->in_in
[1].s_addr
);
408 printf("%s", inet_ntoa(np
->in_in
[1]));
411 if (np
->in_flags
& IPN_IPRANGE
) {
412 printf("range %s-", inet_ntoa(np
->in_out
[0]));
413 printf("%s", inet_ntoa(np
->in_out
[1]));
415 printf("%s/", inet_ntoa(np
->in_out
[0]));
416 bits
= countbits(np
->in_out
[1].s_addr
);
420 printf("%s", inet_ntoa(np
->in_out
[1]));
422 if (*np
->in_plabel
) {
423 printf(" proxy port");
424 if (np
->in_dcmp
!= 0)
425 np
->in_dport
= htons(np
->in_dport
);
426 if (np
->in_dport
!= 0) {
428 sv
= getservbyport(np
->in_dport
,
431 sv
= getservbyport(np
->in_dport
, NULL
);
433 printf(" %s", sv
->s_name
);
435 printf(" %hu", ntohs(np
->in_dport
));
437 printf(" %.*s/", (int)sizeof(np
->in_plabel
),
440 fputs(pr
->p_name
, stdout
);
442 printf("%d", np
->in_p
);
443 } else if (np
->in_redir
== NAT_MAPBLK
) {
444 if ((np
->in_pmin
== 0) &&
445 (np
->in_flags
& IPN_AUTOPORTMAP
))
446 printf(" ports auto");
448 printf(" ports %d", np
->in_pmin
);
449 if (opts
& OPT_DEBUG
)
450 printf("\n\tip modulous %d", np
->in_pmax
);
451 } else if (np
->in_pmin
|| np
->in_pmax
) {
453 if ((np
->in_flags
& IPN_TCPUDP
) == IPN_TCPUDP
)
455 else if (np
->in_flags
& IPN_TCP
)
457 else if (np
->in_flags
& IPN_UDP
)
459 if (np
->in_flags
& IPN_AUTOPORTMAP
) {
461 if (opts
& OPT_DEBUG
)
462 printf(" [%d:%d %d %d]",
465 np
->in_ippip
, np
->in_ppip
);
467 printf(" %d:%d", ntohs(np
->in_pmin
),
471 if (np
->in_flags
& IPN_FRAG
)
474 printf(" age %d/%d", np
->in_age
[0], np
->in_age
[1]);
476 if (opts
& OPT_DEBUG
) {
479 nip
.s_addr
= htonl(np
->in_nextip
.s_addr
);
481 printf("\tspace %lu nextip %s pnext %d", np
->in_space
,
482 inet_ntoa(nip
), np
->in_pnext
);
483 printf(" flags %x use %u\n",
484 np
->in_flags
, np
->in_use
);