nat_cmd.c revision 37192
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.15 1998/06/27 14:17:23 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 "ipcp.h"
35#include "lqr.h"
36#include "hdlc.h"
37#include "mbuf.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
46static int StrToAddr(const char *, struct in_addr *);
47static int StrToPort(const char *, u_short *, const char *);
48static int StrToAddrAndPort(const char *, struct in_addr *, u_short *, const char *);
49
50
51int
52alias_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
113int
114alias_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
151static int
152StrToAddr(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
169static int
170StrToPort(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
192static int
193StrToAddrAndPort(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