nat_cmd.c revision 31923
1/*-
2 * Copyright (c) 1997 Charles Mott <cmott@srv.net>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 *	$Id: alias_cmd.c,v 1.9 1997/12/21 12:11:04 brian Exp $
27 */
28
29#include <sys/param.h>
30#include <sys/socket.h>
31#include <netinet/in.h>
32#include <arpa/inet.h>
33#include <netdb.h>
34
35#include <limits.h>
36#include <stdio.h>
37#include <stdlib.h>
38#include <string.h>
39
40#include "defs.h"
41#include "command.h"
42#include "mbuf.h"
43#include "log.h"
44#include "loadalias.h"
45#include "vars.h"
46#include "alias_cmd.h"
47
48
49static int StrToAddr(const char *, struct in_addr *);
50static int StrToPort(const char *, u_short *, const char *);
51static int StrToAddrAndPort(const char *, struct in_addr *, u_short *, const char *);
52
53
54int
55AliasRedirectPort(struct cmdargs const *arg)
56{
57  if (!(mode & MODE_ALIAS)) {
58    if (VarTerm)
59      fprintf(VarTerm, "Alias not enabled\n");
60    return 1;
61  } else if (arg->argc == 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[0];
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      if (VarTerm) {
78	fprintf(VarTerm, "port redirect: protocol must be tcp or udp\n");
79	fprintf(VarTerm, "Usage: alias %s %s\n", arg->cmd->name,
80		arg->cmd->syntax);
81      }
82      return 1;
83    }
84
85    error = StrToAddrAndPort(arg->argv[1], &local_addr, &local_port, proto);
86    if (error) {
87      if (VarTerm) {
88	fprintf(VarTerm, "port redirect: error reading local addr:port\n");
89	fprintf(VarTerm, "Usage: alias %s %s\n", arg->cmd->name, arg->cmd->syntax);
90      }
91      return 1;
92    }
93    error = StrToPort(arg->argv[2], &alias_port, proto);
94    if (error) {
95      if (VarTerm) {
96	fprintf(VarTerm, "port redirect: error reading alias port\n");
97	fprintf(VarTerm, "Usage: alias %s %s\n", arg->cmd->name, arg->cmd->syntax);
98      }
99      return 1;
100    }
101    null_addr.s_addr = 0;
102
103    link = VarPacketAliasRedirectPort(local_addr, local_port,
104				      null_addr, 0,
105				      null_addr, alias_port,
106				      proto_constant);
107
108    if (link == NULL && VarTerm)
109      fprintf(VarTerm, "port redirect: error returned by packed"
110	      " aliasing engine (code=%d)\n", error);
111  } else
112    return -1;
113
114  return 0;
115}
116
117
118int
119AliasRedirectAddr(struct cmdargs const *arg)
120{
121  if (!(mode & MODE_ALIAS)) {
122    if (VarTerm)
123      fprintf(VarTerm, "alias not enabled\n");
124    return 1;
125  } else if (arg->argc == 2) {
126    int error;
127    struct in_addr local_addr;
128    struct in_addr alias_addr;
129    struct alias_link *link;
130
131    error = StrToAddr(arg->argv[0], &local_addr);
132    if (error) {
133      if (VarTerm)
134	fprintf(VarTerm, "address redirect: invalid local address\n");
135      return 1;
136    }
137    error = StrToAddr(arg->argv[1], &alias_addr);
138    if (error) {
139      if (VarTerm) {
140	fprintf(VarTerm, "address redirect: invalid alias address\n");
141	fprintf(VarTerm, "Usage: alias %s %s\n", arg->cmd->name, arg->cmd->syntax);
142      }
143      return 1;
144    }
145    link = VarPacketAliasRedirectAddr(local_addr, alias_addr);
146    if (link == NULL && VarTerm) {
147      fprintf(VarTerm, "address redirect: packet aliasing engine error\n");
148      fprintf(VarTerm, "Usage: alias %s %s\n", arg->cmd->name, arg->cmd->syntax);
149    }
150  } else
151    return -1;
152
153  return 0;
154}
155
156
157static int
158StrToAddr(const char *str, struct in_addr *addr)
159{
160  struct hostent *hp;
161
162  if (inet_aton(str, addr))
163    return 0;
164
165  hp = gethostbyname(str);
166  if (!hp) {
167    LogPrintf(LogWARN, "StrToAddr: Unknown host %s.\n", str);
168    return -1;
169  }
170  *addr = *((struct in_addr *) hp->h_addr);
171  return 0;
172}
173
174
175static int
176StrToPort(const char *str, u_short *port, const char *proto)
177{
178  int iport;
179  struct servent *sp;
180  char *end;
181
182  iport = strtol(str, &end, 10);
183  if (end != str) {
184    *port = htons(iport);
185    return 0;
186  }
187  sp = getservbyname(str, proto);
188  if (!sp) {
189    LogPrintf(LogWARN, "StrToAddr: Unknown port or service %s/%s.\n",
190	      str, proto);
191    return -1;
192  }
193  *port = sp->s_port;
194  return 0;
195}
196
197
198static int
199StrToAddrAndPort(const char *str, struct in_addr *addr, u_short *port, const char *proto)
200{
201  char *colon;
202  int res;
203
204  colon = strchr(str, ':');
205  if (!colon) {
206    LogPrintf(LogWARN, "StrToAddrAndPort: %s is missing port number.\n", str);
207    return -1;
208  }
209
210  *colon = '\0';		/* Cheat the const-ness ! */
211  res = StrToAddr(str, addr);
212  *colon = ':';			/* Cheat the const-ness ! */
213  if (res != 0)
214    return -1;
215
216  return StrToPort(colon+1, port, proto);
217}
218