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