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