nat_cmd.c revision 45042
1/*- 2 * The code in this file was written by Eivind Eklund <perhaps@yes.no>, 3 * who places it in the public domain without restriction. 4 * 5 * $Id: alias_cmd.c,v 1.21 1999/03/07 18:13:44 brian Exp $ 6 */ 7 8#include <sys/param.h> 9#include <netinet/in.h> 10#include <arpa/inet.h> 11#include <netdb.h> 12#include <netinet/in_systm.h> 13#include <netinet/in.h> 14#include <netinet/ip.h> 15#include <sys/un.h> 16 17#include <stdio.h> 18#include <stdlib.h> 19#include <string.h> 20#include <termios.h> 21 22#ifdef __OpenBSD__ 23#include "alias.h" 24#else 25#include <alias.h> 26#endif 27#include "defs.h" 28#include "command.h" 29#include "log.h" 30#include "alias_cmd.h" 31#include "descriptor.h" 32#include "prompt.h" 33#include "timer.h" 34#include "fsm.h" 35#include "slcompress.h" 36#include "throughput.h" 37#include "iplist.h" 38#include "mbuf.h" 39#include "lqr.h" 40#include "hdlc.h" 41#include "ipcp.h" 42#include "lcp.h" 43#include "ccp.h" 44#include "link.h" 45#include "mp.h" 46#include "filter.h" 47#ifndef NORADIUS 48#include "radius.h" 49#endif 50#include "bundle.h" 51 52 53static int StrToAddr(const char *, struct in_addr *); 54static int StrToPortRange(const char *, u_short *, u_short *, const char *); 55static int StrToAddrAndPort(const char *, struct in_addr *, u_short *, 56 u_short *, const char *); 57 58 59int 60alias_RedirectPort(struct cmdargs const *arg) 61{ 62 if (!arg->bundle->AliasEnabled) { 63 prompt_Printf(arg->prompt, "Alias not enabled\n"); 64 return 1; 65 } else if (arg->argc == arg->argn + 3) { 66 char proto_constant; 67 const char *proto; 68 u_short hlocalport; 69 u_short llocalport; 70 u_short haliasport; 71 u_short laliasport; 72 u_short port; 73 int error; 74 struct in_addr local_addr; 75 struct in_addr null_addr; 76 struct alias_link *link; 77 78 proto = arg->argv[arg->argn]; 79 if (strcmp(proto, "tcp") == 0) { 80 proto_constant = IPPROTO_TCP; 81 } else if (strcmp(proto, "udp") == 0) { 82 proto_constant = IPPROTO_UDP; 83 } else { 84 prompt_Printf(arg->prompt, "port redirect: protocol must be" 85 " tcp or udp\n"); 86 return -1; 87 } 88 89 error = StrToAddrAndPort(arg->argv[arg->argn+1], &local_addr, &llocalport, 90 &hlocalport, proto); 91 if (error) { 92 prompt_Printf(arg->prompt, "alias port: error reading localaddr:port\n"); 93 return -1; 94 } 95 error = StrToPortRange(arg->argv[arg->argn+2], &laliasport, &haliasport, 96 proto); 97 if (error) { 98 prompt_Printf(arg->prompt, "alias port: error reading alias port\n"); 99 return -1; 100 } 101 null_addr.s_addr = INADDR_ANY; 102 103 if (llocalport > hlocalport) { 104 port = llocalport; 105 llocalport = hlocalport; 106 hlocalport = port; 107 } 108 109 if (laliasport > haliasport) { 110 port = laliasport; 111 laliasport = haliasport; 112 haliasport = port; 113 } 114 115 if (haliasport - laliasport != hlocalport - llocalport) { 116 prompt_Printf(arg->prompt, "alias port: Port ranges must be equal\n"); 117 return -1; 118 } 119 120 for (port = laliasport; port <= haliasport; port++) { 121 link = PacketAliasRedirectPort(local_addr, 122 htons(llocalport + (port - laliasport)), 123 null_addr, 0, null_addr, htons(port), 124 proto_constant); 125 126 if (link == NULL) { 127 prompt_Printf(arg->prompt, "alias port: %d: error %d\n", port, error); 128 return 1; 129 } 130 } 131 } else 132 return -1; 133 134 return 0; 135} 136 137 138int 139alias_RedirectAddr(struct cmdargs const *arg) 140{ 141 if (!arg->bundle->AliasEnabled) { 142 prompt_Printf(arg->prompt, "alias not enabled\n"); 143 return 1; 144 } else if (arg->argc == arg->argn+2) { 145 int error; 146 struct in_addr local_addr; 147 struct in_addr alias_addr; 148 struct alias_link *link; 149 150 error = StrToAddr(arg->argv[arg->argn], &local_addr); 151 if (error) { 152 prompt_Printf(arg->prompt, "address redirect: invalid local address\n"); 153 return 1; 154 } 155 error = StrToAddr(arg->argv[arg->argn+1], &alias_addr); 156 if (error) { 157 prompt_Printf(arg->prompt, "address redirect: invalid alias address\n"); 158 prompt_Printf(arg->prompt, "Usage: alias %s %s\n", arg->cmd->name, 159 arg->cmd->syntax); 160 return 1; 161 } 162 link = PacketAliasRedirectAddr(local_addr, alias_addr); 163 if (link == NULL) { 164 prompt_Printf(arg->prompt, "address redirect: packet aliasing" 165 " engine error\n"); 166 prompt_Printf(arg->prompt, "Usage: alias %s %s\n", arg->cmd->name, 167 arg->cmd->syntax); 168 } 169 } else 170 return -1; 171 172 return 0; 173} 174 175 176static int 177StrToAddr(const char *str, struct in_addr *addr) 178{ 179 struct hostent *hp; 180 181 if (inet_aton(str, addr)) 182 return 0; 183 184 hp = gethostbyname(str); 185 if (!hp) { 186 log_Printf(LogWARN, "StrToAddr: Unknown host %s.\n", str); 187 return -1; 188 } 189 *addr = *((struct in_addr *) hp->h_addr); 190 return 0; 191} 192 193 194static int 195StrToPort(const char *str, u_short *port, const char *proto) 196{ 197 struct servent *sp; 198 char *end; 199 200 *port = strtol(str, &end, 10); 201 if (*end != '\0') { 202 sp = getservbyname(str, proto); 203 if (sp == NULL) { 204 log_Printf(LogWARN, "StrToAddr: Unknown port or service %s/%s.\n", 205 str, proto); 206 return -1; 207 } 208 *port = ntohs(sp->s_port); 209 } 210 211 return 0; 212} 213 214static int 215StrToPortRange(const char *str, u_short *low, u_short *high, const char *proto) 216{ 217 char *minus; 218 int res; 219 220 minus = strchr(str, '-'); 221 if (minus) 222 *minus = '\0'; /* Cheat the const-ness ! */ 223 224 res = StrToPort(str, low, proto); 225 226 if (minus) 227 *minus = '-'; /* Cheat the const-ness ! */ 228 229 if (res == 0) { 230 if (minus) 231 res = StrToPort(minus + 1, high, proto); 232 else 233 *high = *low; 234 } 235 236 return res; 237} 238 239static int 240StrToAddrAndPort(const char *str, struct in_addr *addr, u_short *low, 241 u_short *high, const char *proto) 242{ 243 char *colon; 244 int res; 245 246 colon = strchr(str, ':'); 247 if (!colon) { 248 log_Printf(LogWARN, "StrToAddrAndPort: %s is missing port number.\n", str); 249 return -1; 250 } 251 252 *colon = '\0'; /* Cheat the const-ness ! */ 253 res = StrToAddr(str, addr); 254 *colon = ':'; /* Cheat the const-ness ! */ 255 if (res != 0) 256 return -1; 257 258 return StrToPortRange(colon + 1, low, high, proto); 259} 260 261int 262alias_ProxyRule(struct cmdargs const *arg) 263{ 264 char cmd[LINE_LEN]; 265 int f, pos; 266 size_t len; 267 268 if (arg->argn >= arg->argc) 269 return -1; 270 271 for (f = arg->argn, pos = 0; f < arg->argc; f++) { 272 len = strlen(arg->argv[f]); 273 if (sizeof cmd - pos < len + (f ? 1 : 0)) 274 break; 275 if (f) 276 cmd[pos++] = ' '; 277 strcpy(cmd + pos, arg->argv[f]); 278 pos += len; 279 } 280 281 return PacketAliasProxyRule(cmd); 282} 283 284int 285alias_Pptp(struct cmdargs const *arg) 286{ 287 struct in_addr addr; 288 289 if (arg->argc == arg->argn) { 290 addr.s_addr = INADDR_NONE; 291 PacketAliasPptp(addr); 292 return 0; 293 } 294 295 if (arg->argc != arg->argn + 1) 296 return -1; 297 298 addr = GetIpAddr(arg->argv[arg->argn]); 299 if (addr.s_addr == INADDR_NONE) { 300 log_Printf(LogWARN, "%s: invalid address\n", arg->argv[arg->argn]); 301 return 1; 302 } 303 304 PacketAliasPptp(addr); 305 return 0; 306} 307