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