2 * Copyright (C) 1993-2002 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>
46 #include "netinet/ip_compat.h"
47 #include "netinet/ip_fil.h"
48 #include "netinet/ip_nat.h"
49 #include "netinet/ip_state.h"
50 #include "netinet/ip_proxy.h"
54 #if defined(sun) && !SOLARIS2
55 # define STRERROR(x) sys_errlist[x]
56 extern char *sys_errlist[];
58 # define STRERROR(x) strerror(x)
62 static const char sccsid[] ="@(#)ipnat.c 1.9 6/5/96 (C) 1993 Darren Reed";
63 static const char rcsid[] = "@(#)$Id: ipnat.c,v 2.16.2.22 2002/12/06 11:40:26 darrenr Exp $";
68 #define bzero(a,b) memset(a,0,b)
71 char thishost[MAXHOSTNAMELEN];
74 extern ipnat_t *natparse __P((char *, int));
75 extern void natparsefile __P((int, char *, int));
76 extern void printnat __P((ipnat_t *, int));
77 extern void printactivenat __P((nat_t *, int));
78 extern void printhostmap __P((hostmap_t *, u_int));
79 extern char *getsumd __P((u_32_t));
81 void dostats __P((natstat_t *, int)), flushtable __P((int, int));
82 void usage __P((char *));
83 int countbits __P((u_32_t));
84 char *getnattype __P((ipnat_t *));
85 int main __P((int, char*[]));
86 void printaps __P((ap_session_t *, int));
87 void showhostmap __P((natstat_t *nsp));
88 void natstat_dead __P((natstat_t *, char *));
94 fprintf(stderr, "%s: [-CFhlnrsv] [-f filename]\n", name);
103 natstat_t ns, *nsp = &ns;
104 char *file, *core, *kernel;
105 int fd, opts, c, mode;
114 while ((c = getopt(argc, argv, "CdFf:hlM:N:nrsv")) != -1)
160 if ((kernel != NULL) || (core != NULL)) {
161 (void) setgid(getgid());
162 (void) setuid(getuid());
165 bzero((char *)&ns, sizeof(ns));
167 gethostname(thishost, sizeof(thishost));
168 thishost[sizeof(thishost) - 1] = '\0';
170 if (!(opts & OPT_NODO) && (kernel == NULL) && (core == NULL)) {
171 if (openkmem(kernel, core) == -1)
174 if (((fd = open(IPL_NAT, mode)) == -1) &&
175 ((fd = open(IPL_NAT, O_RDONLY)) == -1)) {
176 (void) fprintf(stderr, "%s: open: %s\n", IPL_NAT,
179 fprintf(stderr, "IPFilter enabled?\n");
182 if (ioctl(fd, SIOCGNATS, &nsp) == -1) {
183 perror("ioctl(SIOCGNATS)");
186 (void) setgid(getgid());
187 (void) setuid(getuid());
188 } else if ((kernel != NULL) || (core != NULL)) {
189 if (openkmem(kernel, core) == -1)
192 natstat_dead(nsp, kernel);
193 if (opts & (OPT_LIST|OPT_STAT))
198 if (opts & (OPT_FLUSH|OPT_CLEAR))
199 flushtable(fd, opts);
201 natparsefile(fd, file, opts);
202 if (opts & (OPT_LIST|OPT_STAT))
209 * Read nat statistic information in using a symbol table and memory file
210 * rather than doing ioctl's.
212 void natstat_dead(nsp, kernel)
216 struct nlist nat_nlist[10] = {
217 { "nat_table" }, /* 0 */
220 { "ipf_nattable_sz" },
221 { "ipf_natrules_sz" },
222 { "ipf_rdrrules_sz" }, /* 5 */
223 { "ipf_hostmap_sz" },
230 if (nlist(kernel, nat_nlist) == -1) {
231 fprintf(stderr, "nlist error\n");
236 * Normally the ioctl copies all of these values into the structure
237 * for us, before returning it to useland, so here we must copy each
238 * one in individually.
240 kmemcpy((char *)&tables, nat_nlist[0].n_value, sizeof(tables));
241 nsp->ns_table[0] = tables[0];
242 nsp->ns_table[1] = tables[1];
244 kmemcpy((char *)&nsp->ns_list, nat_nlist[1].n_value,
245 sizeof(nsp->ns_list));
246 kmemcpy((char *)&nsp->ns_maptable, nat_nlist[2].n_value,
247 sizeof(nsp->ns_maptable));
248 kmemcpy((char *)&nsp->ns_nattab_sz, nat_nlist[3].n_value,
249 sizeof(nsp->ns_nattab_sz));
250 kmemcpy((char *)&nsp->ns_rultab_sz, nat_nlist[4].n_value,
251 sizeof(nsp->ns_rultab_sz));
252 kmemcpy((char *)&nsp->ns_rdrtab_sz, nat_nlist[5].n_value,
253 sizeof(nsp->ns_rdrtab_sz));
254 kmemcpy((char *)&nsp->ns_hostmap_sz, nat_nlist[6].n_value,
255 sizeof(nsp->ns_hostmap_sz));
256 kmemcpy((char *)&nsp->ns_instances, nat_nlist[7].n_value,
257 sizeof(nsp->ns_instances));
258 kmemcpy((char *)&nsp->ns_apslist, nat_nlist[8].n_value,
259 sizeof(nsp->ns_apslist));
264 * Display NAT statistics.
266 void dostats(nsp, opts)
270 nat_t **nt[2], *np, nat;
276 if (opts & OPT_STAT) {
277 printf("mapped\tin\t%lu\tout\t%lu\n",
278 nsp->ns_mapped[0], nsp->ns_mapped[1]);
279 printf("added\t%lu\texpired\t%lu\n",
280 nsp->ns_added, nsp->ns_expire);
281 printf("no memory\t%lu\tbad nat\t%lu\n",
282 nsp->ns_memfail, nsp->ns_badnat);
283 printf("inuse\t%lu\nrules\t%lu\n",
284 nsp->ns_inuse, nsp->ns_rules);
285 printf("wilds\t%u\n", nsp->ns_wilds);
286 if (opts & OPT_VERBOSE)
287 printf("table %p list %p\n",
288 nsp->ns_table, nsp->ns_list);
292 * Show list of NAT rules and NAT sessions ?
294 if (opts & OPT_LIST) {
295 printf("List of active MAP/Redirect filters:\n");
296 while (nsp->ns_list) {
297 if (kmemcpy((char *)&ipn, (long)nsp->ns_list,
303 printf("%d ", ipn.in_hits);
304 printnat(&ipn, opts & (OPT_DEBUG|OPT_VERBOSE));
305 nsp->ns_list = ipn.in_next;
308 nt[0] = (nat_t **)malloc(sizeof(*nt) * NAT_SIZE);
309 if (kmemcpy((char *)nt[0], (long)nsp->ns_table[0],
310 sizeof(**nt) * NAT_SIZE)) {
315 printf("\nList of active sessions:\n");
317 for (np = nsp->ns_instances; np; np = nat.nat_next) {
318 if (kmemcpy((char *)&nat, (long)np, sizeof(nat)))
320 printactivenat(&nat, opts);
323 if (opts & OPT_VERBOSE)
331 * display the active host mapping table.
333 void showhostmap(nsp)
336 hostmap_t hm, *hmp, **maptable;
339 printf("\nList of active host mappings:\n");
341 maptable = (hostmap_t **)malloc(sizeof(hostmap_t *) *
343 if (kmemcpy((char *)maptable, (u_long)nsp->ns_maptable,
344 sizeof(hostmap_t *) * nsp->ns_hostmap_sz)) {
345 perror("kmemcpy (maptable)");
349 for (hv = 0; hv < nsp->ns_hostmap_sz; hv++) {
353 if (kmemcpy((char *)&hm, (u_long)hmp, sizeof(hm))) {
354 perror("kmemcpy (hostmap)");
358 printhostmap(&hm, hv);
367 * Issue an ioctl to flush either the NAT rules table or the active mapping
370 void flushtable(fd, opts)
375 if (opts & OPT_FLUSH) {
377 if (!(opts & OPT_NODO) && ioctl(fd, SIOCIPFFL, &n) == -1)
378 perror("ioctl(SIOCFLNAT)");
380 printf("%d entries flushed from NAT table\n", n);
383 if (opts & OPT_CLEAR) {
385 if (!(opts & OPT_NODO) && ioctl(fd, SIOCIPFFL, &n) == -1)
386 perror("ioctl(SIOCCNATL)");
388 printf("%d entries flushed from NAT list\n", n);