xref: /freebsd/usr.sbin/ppp/nat_cmd.c (revision 0de89efe5c443f213c7ea28773ef2dc6cf3af2ed)
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 
17 static int
18     StrToAddr(char *, struct in_addr * addr);
19 
20 static int
21     StrToPort(char *, u_short * port, char *proto);
22 
23 static int
24     StrToAddrAndPort(char *, struct in_addr * addr, u_short * port, char *proto);
25 
26 
27 int
28 AliasRedirectPort(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     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 
93 int
94 AliasRedirectAddr(struct cmdtab * list,
95 		  int argc,
96 		  char **argv,
97 		  void *param)
98 {
99   if (!(mode & MODE_ALIAS)) {
100     if (VarTerm)
101       fprintf(VarTerm, "alias not enabled\n");
102   } else if (argc == 2) {
103     int error;
104     struct in_addr local_addr;
105     struct in_addr alias_addr;
106     struct alias_link *link;
107 
108     error = StrToAddr(argv[0], &local_addr);
109     if (error) {
110       if (VarTerm)
111 	fprintf(VarTerm, "address redirect: invalid local address\n");
112       return 1;
113     }
114     error = StrToAddr(argv[1], &alias_addr);
115     if (error) {
116       if (VarTerm) {
117 	fprintf(VarTerm, "address redirect: invalid alias address\n");
118 	fprintf(VarTerm, "Usage: alias %s %s\n", list->name, list->syntax);
119       }
120       return 1;
121     }
122     link = VarPacketAliasRedirectAddr(local_addr, alias_addr);
123     if (link == NULL && VarTerm) {
124       fprintf(VarTerm, "address redirect: packet aliasing engine error\n");
125       fprintf(VarTerm, "Usage: alias %s %s\n", list->name, list->syntax);
126     }
127   } else if (VarTerm)
128     fprintf(VarTerm, "Usage: alias %s %s\n", list->name, list->syntax);
129 
130   return 1;
131 }
132 
133 
134 static int
135 StrToAddr(char *str,
136 	  struct in_addr * addr)
137 {
138   struct hostent *hp;
139 
140   if (inet_aton(str, addr))
141     return 0;
142 
143   hp = gethostbyname(str);
144   if (!hp) {
145     LogPrintf(LogWARN, "StrToAddr: Unknown host %s.\n", str);
146     return -1;
147   }
148   *addr = *((struct in_addr *) hp->h_addr);
149   return 0;
150 }
151 
152 
153 static int
154 StrToPort(char *str,
155 	  u_short * port,
156 	  char *proto)
157 {
158   int iport;
159   struct servent *sp;
160   char *end;
161 
162   iport = strtol(str, &end, 10);
163   if (end != str) {
164     *port = htons(iport);
165     return 0;
166   }
167   sp = getservbyname(str, proto);
168   if (!sp) {
169     LogPrintf(LogWARN, "StrToAddr: Unknown port or service %s/%s.\n",
170 	      str, proto);
171     return -1;
172   }
173   *port = sp->s_port;
174   return 0;
175 }
176 
177 
178 int
179 StrToAddrAndPort(char *str,
180 		 struct in_addr * addr,
181 		 u_short * port,
182 		 char *proto)
183 {
184   char *ptr;
185 
186   ptr = strchr(str, ':');
187   if (!ptr) {
188     LogPrintf(LogWARN, "StrToAddrAndPort: %s is missing port number.\n",
189 	      str);
190     return -1;
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