nat_cmd.c revision 26516
1#include <limits.h>
2#include <netdb.h>
3#include <stdlib.h>
4#include <stdio.h>
5#include <string.h>
6
7#include <sys/types.h>
8#include <sys/socket.h>
9#include <netinet/in.h>
10#include <arpa/inet.h>
11
12#include "defs.h"
13#include "command.h"
14#include "loadalias.h"
15#include "vars.h"
16
17static int
18StrToAddr (char *, struct in_addr* addr);
19
20static int
21StrToPort (char *, u_short *port, char *proto);
22
23static int
24StrToAddrAndPort (char *, struct in_addr *addr, u_short *port, char *proto);
25
26
27int
28AliasRedirectPort (struct cmdtab *list,
29                   int argc,
30                   char **argv,
31                   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
69        error = StrToPort(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", list->name, list->syntax);
74	  }
75          return 1;
76        }
77
78        null_addr.s_addr = 0;
79
80        link = VarPacketAliasRedirectPort(local_addr, local_port,
81                                        null_addr,  0,
82                                        null_addr,  alias_port,
83                                        proto_constant);
84
85        if (link == NULL && VarTerm)
86            fprintf(VarTerm, "port redirect: error returned by packed"
87		    " aliasing engine (code=%d)\n", error);
88    } else if (VarTerm)
89        fprintf(VarTerm, "Usage: alias %s %s\n", list->name, list->syntax);
90
91    return 1;
92}
93
94
95int
96AliasRedirectAddr(struct cmdtab *list,
97                  int argc,
98                  char **argv,
99                  void *param)
100{
101    if (!(mode & MODE_ALIAS)) {
102      if (VarTerm)
103        fprintf(VarTerm, "alias not enabled\n");
104    } else if (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(argv[0], &local_addr);
111        if (error) {
112	    if (VarTerm)
113              fprintf(VarTerm, "address redirect: invalid local address\n");
114            return 1;
115        }
116
117        error = StrToAddr(argv[1], &alias_addr);
118        if (error) {
119	  if (VarTerm) {
120            fprintf(VarTerm, "address redirect: invalid alias address\n");
121            fprintf(VarTerm, "Usage: alias %s %s\n", list->name, list->syntax);
122	  }
123          return 1;
124        }
125
126        link = VarPacketAliasRedirectAddr(local_addr, alias_addr);
127        if (link == NULL && VarTerm) {
128          fprintf(VarTerm, "address redirect: packet aliasing engine error\n");
129          fprintf(VarTerm, "Usage: alias %s %s\n", list->name, list->syntax);
130        }
131    } else if (VarTerm)
132        fprintf(VarTerm, "Usage: alias %s %s\n", list->name, list->syntax);
133
134    return 1;
135}
136
137
138static int
139StrToAddr (char* str,
140           struct in_addr* addr)
141{
142    struct hostent* hp;
143
144    if (inet_aton (str, addr))
145        return 0;
146
147    hp = gethostbyname (str);
148    if (!hp)
149    {
150        LogPrintf(LogWARN, "StrToAddr: Unknown host %s.\n", str);
151        return -1;
152    }
153
154    *addr = *((struct in_addr *) hp->h_addr);
155    return 0;
156}
157
158
159static int
160StrToPort (char *str,
161           u_short *port,
162           char *proto)
163{
164    int iport;
165    struct servent* sp;
166    char* end;
167
168    iport = strtol (str, &end, 10);
169    if (end != str)
170    {
171        *port = htons(iport);
172        return 0;
173    }
174
175    sp = getservbyname (str, proto);
176    if (!sp)
177    {
178        LogPrintf(LogWARN, "StrToAddr: Unknown port or service %s/%s.\n",
179                  str, proto);
180        return -1;
181    }
182
183    *port = sp->s_port;
184    return 0;
185}
186
187
188int
189StrToAddrAndPort (char* str,
190                  struct in_addr* addr,
191                  u_short *port,
192                  char *proto)
193{
194    char *ptr;
195
196    ptr = strchr (str, ':');
197    if (!ptr)
198    {
199        LogPrintf(LogWARN, "StrToAddrAndPort: %s is missing port number.\n",
200		  str);
201        return -1;
202    }
203
204    *ptr = '\0';
205    ++ptr;
206
207    if (StrToAddr (str, addr) != 0)
208        return -1;
209
210    return StrToPort (ptr, port, proto);
211}
212
213