1/*
2 * Frontend command-line utility for Linux network configuration layer
3 * Toy ifconfig/route/iptables implementations
4 *
5 * Copyright 2004, Broadcom Corporation
6 * All Rights Reserved.
7 *
8 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
9 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
10 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
11 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
12 *
13 * $Id: main.c,v 1.1.1.1 2008/10/15 03:30:09 james26_jang Exp $
14 */
15
16#include <stdio.h>
17#include <stdlib.h>
18#include <errno.h>
19#include <error.h>
20#include <string.h>
21#include <sys/socket.h>
22#include <netinet/in.h>
23#include <arpa/inet.h>
24#include <assert.h>
25
26#include <netconf.h>
27
28#define valid_ports(min, max) ( \
29	!((min) == 0 && (max) == 0) && \
30	!((min) == 0 && (max) == 0xffff) \
31)
32
33static void
34print_fw(netconf_fw_t *fw)
35{
36	netconf_filter_t *filter;
37	netconf_nat_t *nat;
38	netconf_app_t *app;
39	const char *target_name[] = { "DROP", "ACCEPT", "logdrop", "logaccept", "SNAT", "DNAT", "MASQUERADE", "autofw" };
40	const char *filter_dir_name[] = { "IN", "FORWARD", "OUT" };
41
42	/* Target name */
43	printf("%s", target_name[fw->target]);
44
45	/* Filter direction */
46	if (netconf_valid_filter(fw->target)) {
47		filter = (netconf_filter_t *) fw;
48		printf(" %s", filter_dir_name[filter->dir]);
49	}
50
51	/* IP protocol */
52	if (fw->match.ipproto == IPPROTO_TCP)
53		printf(" tcp");
54	else if (fw->match.ipproto == IPPROTO_UDP)
55		printf(" udp");
56
57	/* Match source IP address */
58	if (fw->match.src.ipaddr.s_addr & fw->match.src.netmask.s_addr) {
59		printf(" src %s%s",
60		       (fw->match.flags & NETCONF_INV_SRCIP) ? "!" : "",
61		       inet_ntoa(fw->match.src.ipaddr));
62		if (fw->match.src.netmask.s_addr != 0xffffffff)
63			printf("/%s", inet_ntoa(fw->match.src.netmask));
64	} else
65		printf(" src anywhere");
66
67	/* Match source TCP/UDP port range */
68	if (fw->match.ipproto && valid_ports(fw->match.src.ports[0], fw->match.src.ports[1])) {
69		printf(":%s%d",
70		       (fw->match.flags & NETCONF_INV_SRCPT) ? "!" : "",
71		       ntohs(fw->match.src.ports[0]));
72		if (fw->match.src.ports[1] != fw->match.src.ports[0])
73			printf("-%d", ntohs(fw->match.src.ports[1]));
74	}
75
76	/* Match destination IP address */
77	if (fw->match.dst.ipaddr.s_addr & fw->match.dst.netmask.s_addr) {
78		printf(" dst %s%s",
79		       (fw->match.flags & NETCONF_INV_DSTIP) ? "!" : "",
80		       inet_ntoa(fw->match.dst.ipaddr));
81		if (fw->match.dst.netmask.s_addr != 0xffffffff)
82			printf("/%s", inet_ntoa(fw->match.dst.netmask));
83	} else
84		printf(" dst anywhere");
85
86	/* Match destination TCP/UDP port range */
87	if (fw->match.ipproto && valid_ports(fw->match.dst.ports[0], fw->match.dst.ports[1] != 0xffff)) {
88		printf(":%s%d",
89		       (fw->match.flags & NETCONF_INV_DSTPT) ? "!" : "",
90		       ntohs(fw->match.dst.ports[0]));
91		if (fw->match.dst.ports[1] != fw->match.dst.ports[0])
92			printf("-%d", ntohs(fw->match.dst.ports[1]));
93	}
94
95	/* Match MAC address */
96	if (!ETHER_ISNULLADDR(fw->match.mac.octet)) {
97		printf(" mac %s%02X:%02X:%02X:%02X:%02X:%02X",
98		       (fw->match.flags & NETCONF_INV_MAC) ? "! " : "",
99		       fw->match.mac.octet[0] & 0xff,
100		       fw->match.mac.octet[1] & 0xff,
101		       fw->match.mac.octet[2] & 0xff,
102		       fw->match.mac.octet[3] & 0xff,
103		       fw->match.mac.octet[4] & 0xff,
104		       fw->match.mac.octet[5] & 0xff);
105	}
106
107	/* Match packet state */
108	if (fw->match.state) {
109		char *sep = "";
110		printf(" state ");
111		if (fw->match.state & NETCONF_INVALID) {
112			printf("%sINVALID", sep);
113			sep = ",";
114		}
115		if (fw->match.state & NETCONF_ESTABLISHED) {
116			printf("%sESTABLISHED", sep);
117			sep = ",";
118		}
119		if (fw->match.state & NETCONF_RELATED) {
120			printf("%sRELATED", sep);
121			sep = ",";
122		}
123		if (fw->match.state & NETCONF_NEW) {
124			printf("%sNEW", sep);
125			sep = ",";
126		}
127	}
128
129	/* Match local time */
130	if (fw->match.secs[0] || fw->match.secs[1]) {
131		char *days[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
132		if (fw->match.days[0] < 7 && fw->match.days[1] < 7)
133			printf(" %s-%s",
134			       days[fw->match.days[0]], days[fw->match.days[1]]);
135		if (fw->match.secs[0] < (24 * 60 * 60) && fw->match.days[1] < (24 * 60 * 60))
136			printf(" %02d:%02d:%02d-%02d:%02d:%02d",
137			       fw->match.secs[0] / (60 * 60), (fw->match.secs[0] / 60) % 60, fw->match.secs[0] % 60,
138			       fw->match.secs[1] / (60 * 60), (fw->match.secs[1] / 60) % 60, fw->match.secs[1] % 60);
139	}
140
141	/* Match interface name */
142	if (strlen(fw->match.in.name))
143		printf(" in %s%s",
144		       (fw->match.flags & NETCONF_INV_IN) ? "!" : "",
145		       fw->match.in.name);
146	if (strlen(fw->match.out.name))
147		printf(" out %s%s",
148		       (fw->match.flags & NETCONF_INV_OUT) ? "!" : "",
149		       fw->match.out.name);
150
151	/* NAT target parameters */
152	if (fw->target == NETCONF_SNAT || fw->target == NETCONF_DNAT) {
153		nat = (netconf_nat_t *) fw;
154		printf(" to %s", inet_ntoa(nat->ipaddr));
155		if (valid_ports(nat->ports[0], nat->ports[1])) {
156			printf(":%d", ntohs(nat->ports[0]));
157			if (nat->ports[1] != nat->ports[0])
158				printf("-%d", ntohs(nat->ports[1]));
159		}
160	}
161
162	/* Application specific port forward parameters */
163	if (fw->target == NETCONF_APP) {
164		app = (netconf_app_t *) fw;
165		printf(" autofw ");
166		if (app->proto == IPPROTO_TCP)
167			printf("tcp ");
168		else if (app->proto == IPPROTO_UDP)
169			printf("udp ");
170		printf("dpt:%hu", ntohs(app->dport[0]));
171		if (ntohs(app->dport[1]) > ntohs(app->dport[0]))
172			printf("-%hu", ntohs(app->dport[1]));
173		printf(" ");
174		printf("to:%hu", ntohs(app->to[0]));
175		if (ntohs(app->to[1]) > ntohs(app->to[0]))
176			printf("-%hu", ntohs(app->to[1]));
177		printf(" ");
178	}
179
180	printf("\n");
181}
182
183int
184main(int argc, char **argv)
185{
186	netconf_fw_t *fw, fw_list;
187	int ret;
188
189	if ((ret = netconf_get_fw(&fw_list)))
190		return ret;
191
192	netconf_list_for_each(fw, &fw_list) {
193		assert(netconf_fw_exists(fw));
194		print_fw(fw);
195	}
196
197	netconf_list_free(&fw_list);
198
199	return 0;
200}
201