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