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