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