nat_cmd.c revision 30715
1/*
2 * $Id: $
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 "mbuf.h"
17#include "log.h"
18#include "defs.h"
19#include "command.h"
20#include "loadalias.h"
21#include "vars.h"
22#include "alias_cmd.h"
23
24
25static int StrToAddr(char *, struct in_addr *);
26static int StrToPort(char *, u_short *, char *);
27static int StrToAddrAndPort(char *, struct in_addr *, u_short *, char *);
28
29
30int
31AliasRedirectPort(struct cmdtab *list, int argc, char **argv, void *param)
32{
33  if (!(mode & MODE_ALIAS)) {
34    if (VarTerm)
35      fprintf(VarTerm, "Alias not enabled\n");
36  } else if (argc == 3) {
37    char proto_constant;
38    char *proto;
39    u_short local_port;
40    u_short alias_port;
41    int error;
42    struct in_addr local_addr;
43    struct in_addr null_addr;
44    struct alias_link *link;
45
46    proto = argv[0];
47    if (strcmp(proto, "tcp") == 0) {
48      proto_constant = IPPROTO_TCP;
49    } else if (strcmp(proto, "udp") == 0) {
50      proto_constant = IPPROTO_UDP;
51    } else {
52      if (VarTerm) {
53	fprintf(VarTerm, "port redirect: protocol must be tcp or udp\n");
54	fprintf(VarTerm, "Usage: alias %s %s\n", list->name,
55		list->syntax);
56      }
57      return 1;
58    }
59
60    error = StrToAddrAndPort(argv[1], &local_addr, &local_port, proto);
61    if (error) {
62      if (VarTerm) {
63	fprintf(VarTerm, "port redirect: error reading local addr:port\n");
64	fprintf(VarTerm, "Usage: alias %s %s\n", list->name, list->syntax);
65      }
66      return 1;
67    }
68    error = StrToPort(argv[2], &alias_port, proto);
69    if (error) {
70      if (VarTerm) {
71	fprintf(VarTerm, "port redirect: error reading alias port\n");
72	fprintf(VarTerm, "Usage: alias %s %s\n", list->name, list->syntax);
73      }
74      return 1;
75    }
76    null_addr.s_addr = 0;
77
78    link = VarPacketAliasRedirectPort(local_addr, local_port,
79				      null_addr, 0,
80				      null_addr, alias_port,
81				      proto_constant);
82
83    if (link == NULL && VarTerm)
84      fprintf(VarTerm, "port redirect: error returned by packed"
85	      " aliasing engine (code=%d)\n", error);
86  } else if (VarTerm)
87    fprintf(VarTerm, "Usage: alias %s %s\n", list->name, list->syntax);
88
89  return 1;
90}
91
92
93int
94AliasRedirectAddr(struct cmdtab *list, int argc, char **argv, void *param)
95{
96  if (!(mode & MODE_ALIAS)) {
97    if (VarTerm)
98      fprintf(VarTerm, "alias not enabled\n");
99  } else if (argc == 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(argv[0], &local_addr);
106    if (error) {
107      if (VarTerm)
108	fprintf(VarTerm, "address redirect: invalid local address\n");
109      return 1;
110    }
111    error = StrToAddr(argv[1], &alias_addr);
112    if (error) {
113      if (VarTerm) {
114	fprintf(VarTerm, "address redirect: invalid alias address\n");
115	fprintf(VarTerm, "Usage: alias %s %s\n", list->name, list->syntax);
116      }
117      return 1;
118    }
119    link = VarPacketAliasRedirectAddr(local_addr, alias_addr);
120    if (link == NULL && VarTerm) {
121      fprintf(VarTerm, "address redirect: packet aliasing engine error\n");
122      fprintf(VarTerm, "Usage: alias %s %s\n", list->name, list->syntax);
123    }
124  } else if (VarTerm)
125    fprintf(VarTerm, "Usage: alias %s %s\n", list->name, list->syntax);
126
127  return 1;
128}
129
130
131static int
132StrToAddr(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    LogPrintf(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(char *str, u_short *port, 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    LogPrintf(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
172int
173StrToAddrAndPort(char *str, struct in_addr *addr, u_short *port, char *proto)
174{
175  char *ptr;
176
177  ptr = strchr(str, ':');
178  if (!ptr) {
179    LogPrintf(LogWARN, "StrToAddrAndPort: %s is missing port number.\n",
180	      str);
181    return -1;
182  }
183  *ptr = '\0';
184  ++ptr;
185
186  if (StrToAddr(str, addr) != 0)
187    return -1;
188
189  return StrToPort(ptr, port, proto);
190}
191