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