xref: /freebsd/usr.sbin/ppp/nat_cmd.c (revision ce834215a70ff69e7e222827437116eee2f9ac6f)
1 #include <limits.h>
2 #include <netdb.h>
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <string.h>
6 
7 #include <sys/types.h>
8 #include <sys/socket.h>
9 #include <netinet/in.h>
10 #include <arpa/inet.h>
11 
12 #include "defs.h"
13 #include "command.h"
14 #include "loadalias.h"
15 #include "vars.h"
16 
17 static int
18 StrToAddr (char *, struct in_addr* addr);
19 
20 static int
21 StrToPort (char *, u_short *port, char *proto);
22 
23 static int
24 StrToAddrAndPort (char *, struct in_addr *addr, u_short *port, char *proto);
25 
26 
27 int
28 AliasRedirectPort (struct cmdtab *list,
29                    int argc,
30                    char **argv,
31                    void *param)
32 {
33     if (!(mode & MODE_ALIAS)) {
34 	if (VarTerm)
35           fprintf(VarTerm, "Alias not enabled\n");
36     } else if (argc == 3) {
37         char proto_constant;
38         char *proto;
39         u_short local_port;
40         u_short alias_port;
41         int error;
42         struct in_addr local_addr;
43         struct in_addr null_addr;
44         struct alias_link *link;
45 
46         proto = argv[0];
47         if (strcmp(proto, "tcp") == 0) {
48             proto_constant = IPPROTO_TCP;
49         } else if (strcmp(proto, "udp") == 0) {
50             proto_constant = IPPROTO_UDP;
51         } else {
52 	    if (VarTerm) {
53               fprintf(VarTerm, "port redirect: protocol must be tcp or udp\n");
54               fprintf(VarTerm, "Usage: alias %s %s\n", list->name,
55 		      list->syntax);
56 	    }
57             return 1;
58         }
59 
60         error = StrToAddrAndPort(argv[1], &local_addr, &local_port, proto);
61         if (error) {
62 	  if (VarTerm) {
63             fprintf(VarTerm, "port redirect: error reading local addr:port\n");
64             fprintf(VarTerm, "Usage: alias %s %s\n", list->name, list->syntax);
65 	  }
66           return 1;
67         }
68 
69         error = StrToPort(argv[2], &alias_port, proto);
70         if (error) {
71 	  if (VarTerm) {
72             fprintf(VarTerm, "port redirect: error reading alias port\n");
73             fprintf(VarTerm, "Usage: alias %s %s\n", list->name, list->syntax);
74 	  }
75           return 1;
76         }
77 
78         null_addr.s_addr = 0;
79 
80         link = VarPacketAliasRedirectPort(local_addr, local_port,
81                                         null_addr,  0,
82                                         null_addr,  alias_port,
83                                         proto_constant);
84 
85         if (link == NULL && VarTerm)
86             fprintf(VarTerm, "port redirect: error returned by packed"
87 		    " aliasing engine (code=%d)\n", error);
88     } else if (VarTerm)
89         fprintf(VarTerm, "Usage: alias %s %s\n", list->name, list->syntax);
90 
91     return 1;
92 }
93 
94 
95 int
96 AliasRedirectAddr(struct cmdtab *list,
97                   int argc,
98                   char **argv,
99                   void *param)
100 {
101     if (!(mode & MODE_ALIAS)) {
102       if (VarTerm)
103         fprintf(VarTerm, "alias not enabled\n");
104     } else if (argc == 2) {
105         int error;
106         struct in_addr local_addr;
107         struct in_addr alias_addr;
108         struct alias_link *link;
109 
110         error = StrToAddr(argv[0], &local_addr);
111         if (error) {
112 	    if (VarTerm)
113               fprintf(VarTerm, "address redirect: invalid local address\n");
114             return 1;
115         }
116 
117         error = StrToAddr(argv[1], &alias_addr);
118         if (error) {
119 	  if (VarTerm) {
120             fprintf(VarTerm, "address redirect: invalid alias address\n");
121             fprintf(VarTerm, "Usage: alias %s %s\n", list->name, list->syntax);
122 	  }
123           return 1;
124         }
125 
126         link = VarPacketAliasRedirectAddr(local_addr, alias_addr);
127         if (link == NULL && VarTerm) {
128           fprintf(VarTerm, "address redirect: packet aliasing engine error\n");
129           fprintf(VarTerm, "Usage: alias %s %s\n", list->name, list->syntax);
130         }
131     } else if (VarTerm)
132         fprintf(VarTerm, "Usage: alias %s %s\n", list->name, list->syntax);
133 
134     return 1;
135 }
136 
137 
138 static int
139 StrToAddr (char* str,
140            struct in_addr* addr)
141 {
142     struct hostent* hp;
143 
144     if (inet_aton (str, addr))
145         return 0;
146 
147     hp = gethostbyname (str);
148     if (!hp)
149     {
150         LogPrintf(LogWARN, "StrToAddr: Unknown host %s.\n", str);
151         return -1;
152     }
153 
154     *addr = *((struct in_addr *) hp->h_addr);
155     return 0;
156 }
157 
158 
159 static int
160 StrToPort (char *str,
161            u_short *port,
162            char *proto)
163 {
164     int iport;
165     struct servent* sp;
166     char* end;
167 
168     iport = strtol (str, &end, 10);
169     if (end != str)
170     {
171         *port = htons(iport);
172         return 0;
173     }
174 
175     sp = getservbyname (str, proto);
176     if (!sp)
177     {
178         LogPrintf(LogWARN, "StrToAddr: Unknown port or service %s/%s.\n",
179                   str, proto);
180         return -1;
181     }
182 
183     *port = sp->s_port;
184     return 0;
185 }
186 
187 
188 int
189 StrToAddrAndPort (char* str,
190                   struct in_addr* addr,
191                   u_short *port,
192                   char *proto)
193 {
194     char *ptr;
195 
196     ptr = strchr (str, ':');
197     if (!ptr)
198     {
199         LogPrintf(LogWARN, "StrToAddrAndPort: %s is missing port number.\n",
200 		  str);
201         return -1;
202     }
203 
204     *ptr = '\0';
205     ++ptr;
206 
207     if (StrToAddr (str, addr) != 0)
208         return -1;
209 
210     return StrToPort (ptr, port, proto);
211 }
212 
213