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