xref: /freebsd/usr.sbin/ppp/nat_cmd.c (revision a8445737e740901f5f2c8d24c12ef7fc8b00134e)
1 /*-
2  * The code in this file was written by Eivind Eklund <perhaps@yes.no>,
3  * who places it in the public domain without restriction.
4  *
5  *	$Id: alias_cmd.c,v 1.16 1998/06/27 14:17:59 brian Exp $
6  */
7 
8 #include <sys/types.h>
9 #include <netinet/in.h>
10 #include <arpa/inet.h>
11 #include <netdb.h>
12 #include <netinet/in_systm.h>
13 #include <netinet/in.h>
14 #include <netinet/ip.h>
15 #include <sys/un.h>
16 
17 #include <alias.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <termios.h>
22 
23 #include "defs.h"
24 #include "command.h"
25 #include "log.h"
26 #include "alias_cmd.h"
27 #include "descriptor.h"
28 #include "prompt.h"
29 #include "timer.h"
30 #include "fsm.h"
31 #include "slcompress.h"
32 #include "throughput.h"
33 #include "iplist.h"
34 #include "mbuf.h"
35 #include "lqr.h"
36 #include "hdlc.h"
37 #include "ipcp.h"
38 #include "lcp.h"
39 #include "ccp.h"
40 #include "link.h"
41 #include "mp.h"
42 #include "filter.h"
43 #include "bundle.h"
44 
45 
46 static int StrToAddr(const char *, struct in_addr *);
47 static int StrToPort(const char *, u_short *, const char *);
48 static int StrToAddrAndPort(const char *, struct in_addr *, u_short *, const char *);
49 
50 
51 int
52 alias_RedirectPort(struct cmdargs const *arg)
53 {
54   if (!arg->bundle->AliasEnabled) {
55     prompt_Printf(arg->prompt, "Alias not enabled\n");
56     return 1;
57   } else if (arg->argc == arg->argn+3) {
58     char proto_constant;
59     const char *proto;
60     u_short local_port;
61     u_short alias_port;
62     int error;
63     struct in_addr local_addr;
64     struct in_addr null_addr;
65     struct alias_link *link;
66 
67     proto = arg->argv[arg->argn];
68     if (strcmp(proto, "tcp") == 0) {
69       proto_constant = IPPROTO_TCP;
70     } else if (strcmp(proto, "udp") == 0) {
71       proto_constant = IPPROTO_UDP;
72     } else {
73       prompt_Printf(arg->prompt, "port redirect: protocol must be"
74                     " tcp or udp\n");
75       prompt_Printf(arg->prompt, "Usage: alias %s %s\n", arg->cmd->name,
76 		    arg->cmd->syntax);
77       return 1;
78     }
79 
80     error = StrToAddrAndPort(arg->argv[arg->argn+1], &local_addr, &local_port,
81                              proto);
82     if (error) {
83       prompt_Printf(arg->prompt, "port redirect: error reading"
84                     " local addr:port\n");
85       prompt_Printf(arg->prompt, "Usage: alias %s %s\n", arg->cmd->name,
86                     arg->cmd->syntax);
87       return 1;
88     }
89     error = StrToPort(arg->argv[arg->argn+2], &alias_port, proto);
90     if (error) {
91       prompt_Printf(arg->prompt, "port redirect: error reading alias port\n");
92       prompt_Printf(arg->prompt, "Usage: alias %s %s\n", arg->cmd->name,
93                     arg->cmd->syntax);
94       return 1;
95     }
96     null_addr.s_addr = INADDR_ANY;
97 
98     link = PacketAliasRedirectPort(local_addr, local_port,
99 				   null_addr, 0,
100 				   null_addr, alias_port,
101 				   proto_constant);
102 
103     if (link == NULL)
104       prompt_Printf(arg->prompt, "port redirect: error returned by packed"
105 	      " aliasing engine (code=%d)\n", error);
106   } else
107     return -1;
108 
109   return 0;
110 }
111 
112 
113 int
114 alias_RedirectAddr(struct cmdargs const *arg)
115 {
116   if (!arg->bundle->AliasEnabled) {
117     prompt_Printf(arg->prompt, "alias not enabled\n");
118     return 1;
119   } else if (arg->argc == arg->argn+2) {
120     int error;
121     struct in_addr local_addr;
122     struct in_addr alias_addr;
123     struct alias_link *link;
124 
125     error = StrToAddr(arg->argv[arg->argn], &local_addr);
126     if (error) {
127       prompt_Printf(arg->prompt, "address redirect: invalid local address\n");
128       return 1;
129     }
130     error = StrToAddr(arg->argv[arg->argn+1], &alias_addr);
131     if (error) {
132       prompt_Printf(arg->prompt, "address redirect: invalid alias address\n");
133       prompt_Printf(arg->prompt, "Usage: alias %s %s\n", arg->cmd->name,
134                     arg->cmd->syntax);
135       return 1;
136     }
137     link = PacketAliasRedirectAddr(local_addr, alias_addr);
138     if (link == NULL) {
139       prompt_Printf(arg->prompt, "address redirect: packet aliasing"
140                     " engine error\n");
141       prompt_Printf(arg->prompt, "Usage: alias %s %s\n", arg->cmd->name,
142                     arg->cmd->syntax);
143     }
144   } else
145     return -1;
146 
147   return 0;
148 }
149 
150 
151 static int
152 StrToAddr(const char *str, struct in_addr *addr)
153 {
154   struct hostent *hp;
155 
156   if (inet_aton(str, addr))
157     return 0;
158 
159   hp = gethostbyname(str);
160   if (!hp) {
161     log_Printf(LogWARN, "StrToAddr: Unknown host %s.\n", str);
162     return -1;
163   }
164   *addr = *((struct in_addr *) hp->h_addr);
165   return 0;
166 }
167 
168 
169 static int
170 StrToPort(const char *str, u_short *port, const char *proto)
171 {
172   int iport;
173   struct servent *sp;
174   char *end;
175 
176   iport = strtol(str, &end, 10);
177   if (end != str) {
178     *port = htons(iport);
179     return 0;
180   }
181   sp = getservbyname(str, proto);
182   if (!sp) {
183     log_Printf(LogWARN, "StrToAddr: Unknown port or service %s/%s.\n",
184 	      str, proto);
185     return -1;
186   }
187   *port = sp->s_port;
188   return 0;
189 }
190 
191 
192 static int
193 StrToAddrAndPort(const char *str, struct in_addr *addr, u_short *port, const char *proto)
194 {
195   char *colon;
196   int res;
197 
198   colon = strchr(str, ':');
199   if (!colon) {
200     log_Printf(LogWARN, "StrToAddrAndPort: %s is missing port number.\n", str);
201     return -1;
202   }
203 
204   *colon = '\0';		/* Cheat the const-ness ! */
205   res = StrToAddr(str, addr);
206   *colon = ':';			/* Cheat the const-ness ! */
207   if (res != 0)
208     return -1;
209 
210   return StrToPort(colon+1, port, proto);
211 }
212