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