man/pt_BR/ifconfig.8: remove untranslated paragraph
[platform/upstream/net-tools.git] / lib / masq_info.c
1 /*
2  * lib/masq_info.c    This file contains a the functio masq_info
3  *                      to print a table of current masquerade connections.
4  *
5  * NET-LIB      A collection of functions used from the base set of the
6  *              NET-3 Networking Distribution for the LINUX operating
7  *              system. (net-tools, net-drivers)
8  *
9  * Version:     $Id: masq_info.c,v 1.8 2009/09/06 22:52:01 vapier Exp $
10  *
11  * Author:      Bernd 'eckes' Eckenfels <net-tools@lina.inka.de>
12  *              Copyright 1999 Bernd Eckenfels, Germany
13  *
14  * Modifications:
15  *
16  *960217 {0.01} Bernd Eckenfels:        creatin from the code of
17  *                                      Jos Vos' ipfwadm 2.0beta1
18  *950218 {0.02} Bernd Eckenfels:        <linux/if.h> added
19  *
20  *980405 {0.03} Arnaldo Carvalho:       i18n CATGETS -> gettext
21  *
22  *              This program is free software; you can redistribute it
23  *              and/or  modify it under  the terms of  the GNU General
24  *              Public  License as  published  by  the  Free  Software
25  *              Foundation;  either  version 2 of the License, or  (at
26  *              your option) any later version.
27  */
28 #include <sys/types.h>
29 #include <sys/socket.h>
30 #include <netinet/in.h>
31 #include <arpa/inet.h>
32 #include <errno.h>
33 #include <stdio.h>
34 #include <malloc.h>
35 #include <string.h>
36 #include <unistd.h>
37 #include "net-support.h"
38 #include "pathnames.h"
39 #include "version.h"
40 #include "config.h"
41 #include "intl.h"
42 #include "net-features.h"
43
44 #if HAVE_FW_MASQUERADE
45
46 struct masq {
47     unsigned long expires;      /* Expiration timer */
48     char *proto;                /* Which protocol are we talking? */
49     struct sockaddr_in src, dst;        /* Source and destination IP addresses */
50     unsigned short sport, dport;        /* Source and destination ports */
51     unsigned short mport;       /* Masqueraded port */
52     unsigned long initseq;      /* Add delta from this seq. on */
53     short delta;                /* Delta in sequence numbers */
54     short pdelta;               /* Delta in sequence numbers before last */
55 };
56
57 static struct aftype *ap;       /* current address family       */
58 static int has_pdelta;
59
60 static void print_masq(struct masq *ms, int numeric_host, int numeric_port,
61                        int ext)
62 {
63     unsigned long minutes, seconds, sec100s;
64
65     printf("%-4s", ms->proto);
66
67     sec100s = ms->expires % 100L;
68     seconds = (ms->expires / 100L) % 60;
69     minutes = ms->expires / 6000L;
70
71     printf("%3ld:%02ld.%02ld ", minutes, seconds, sec100s);
72
73     if (ext > 1) {
74         if (has_pdelta)
75             printf("%10lu %5hd %5hd ", ms->initseq,
76                    ms->delta, ms->pdelta);
77         else
78             printf("%10lu %5hd     - ", ms->initseq,
79                    ms->delta);
80     }
81     printf("%-20s ", ap->sprint((struct sockaddr *) &(ms->src), numeric_host));
82     printf("%-20s ", ap->sprint((struct sockaddr *) &(ms->dst), numeric_host));
83
84     printf("%s -> ", get_sname(ms->sport, ms->proto, numeric_port));
85     printf("%s", get_sname(ms->dport, ms->proto, numeric_port));
86     printf(" (%s)\n", get_sname(ms->mport, ms->proto, numeric_port));
87 }
88
89
90 static int read_masqinfo(FILE * f, struct masq *mslist, int nmslist)
91 {
92     int n, nread = 0;
93     struct masq *ms;
94     char buf[256];
95
96     for (nread = 0; nread < nmslist; nread++) {
97         ms = &mslist[nread];
98         if (has_pdelta) {
99             if ((n = fscanf(f, " %s %lX:%hX %lX:%hX %hX %lX %hd %hd %lu",
100                             buf,
101                   (unsigned long *) &ms->src.sin_addr.s_addr, &ms->sport,
102                   (unsigned long *) &ms->dst.sin_addr.s_addr, &ms->dport,
103                             &ms->mport, &ms->initseq, &ms->delta,
104                             &ms->pdelta, &ms->expires)) == -1)
105                 return nread;
106         } else {
107             if ((n = fscanf(f, " %s %lX:%hX %lX:%hX %hX %lX %hd %lu",
108                             buf,
109                   (unsigned long *) &ms->src.sin_addr.s_addr, &ms->sport,
110                   (unsigned long *) &ms->dst.sin_addr.s_addr, &ms->dport,
111                             &ms->mport, &ms->initseq, &ms->delta,
112                             &ms->expires)) == -1)
113                 return nread;
114         }
115         if ((has_pdelta && (n != 10)) || (!has_pdelta && (n != 9))) {
116             EINTERN("masq_info.c", "ip_masquerade format error");
117             return (-1);
118         }
119         ms->src.sin_family = AF_INET;
120         ms->dst.sin_family = AF_INET;
121
122         if (strcmp("IP", buf) == 0)
123             ms->proto = "ip";
124         else if (strcmp("TCP", buf) == 0)
125             ms->proto = "tcp";
126         else if (strcmp("UDP", buf) == 0)
127             ms->proto = "udp";
128         else if (strcmp("ICMP", buf) == 0)
129             ms->proto = "icmp";
130         else if (strcmp("GRE", buf) == 0)
131             ms->proto = "gre";
132         else if (strcmp("ESP", buf) == 0)
133             ms->proto = "esp";
134         else {
135             EINTERN("masq_info.c", "ip_masquerade unknown type");
136             return (-1);
137         }
138
139         /* we always keep these addresses in network byte order */
140         ms->src.sin_addr.s_addr = htonl(ms->src.sin_addr.s_addr);
141         ms->dst.sin_addr.s_addr = htonl(ms->dst.sin_addr.s_addr);
142         ms->sport = htons(ms->sport);
143         ms->dport = htons(ms->dport);
144         ms->mport = htons(ms->mport);
145     }
146     return nread;
147 }
148
149
150 int ip_masq_info(int numeric_host, int numeric_port, int ext)
151 {
152     FILE *f;
153     int i;
154     char buf[256];
155     struct masq *mslist;
156     int ntotal = 0, nread;
157
158     if (!(f = fopen(_PATH_PROCNET_IP_MASQ, "r"))) {
159         if (errno != ENOENT) {
160             perror(_PATH_PROCNET_IP_MASQ);
161             return (-1);
162         }
163         ESYSNOT("netstat", "ip_masquerade");
164         return (1);
165     }
166     if ((ap = get_aftype("inet")) == NULL) {
167         ENOSUPP("masq_info", "AF INET");
168         fclose(f);
169         return (-1);
170     }
171     fgets(buf, sizeof(buf), f);
172     has_pdelta = strstr(buf, "PDelta") ? 1 : 0;
173
174     mslist = (struct masq *) malloc(16 * sizeof(struct masq));
175     if (!mslist) {
176         EINTERN("masq_info", "malloc() failed");
177         fclose(f);
178         return (-1);
179     }
180     while ((nread = read_masqinfo(f, &(mslist[ntotal]), 16)) == 16) {
181         ntotal += nread;
182         mslist = (struct masq *) realloc(mslist,
183                                     (ntotal + 16) * sizeof(struct masq));
184         if (!mslist) {
185             EINTERN("masq_info", "realloc() failed");
186             fclose(f);
187             return (-1);
188         }
189     }
190     fclose(f);
191
192     if (nread < 0) {
193         if (mslist)
194             free(mslist);
195         return (-1);
196     }
197     ntotal += nread;
198
199     if (ntotal > 0) {
200         printf(_("IP masquerading entries\n"));
201         switch (ext) {
202         case 1:
203             printf(_("prot   expire source               destination          ports\n"));
204             break;
205         default:
206             printf(_("prot   expire    initseq delta prevd source               destination          ports\n"));
207             break;
208         }
209         for (i = 0; i < ntotal; i++)
210             print_masq(&(mslist[i]), numeric_host, numeric_port, ext);
211     }
212
213     free(mslist);
214     return 0;
215 }
216 #endif