nat_cmd.c revision 44557
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.20 1999/03/07 15:02:37 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 StrToPort(const char *, u_short *, const char *); 55static int StrToAddrAndPort(const char *, struct in_addr *, u_short *, const char *); 56 57 58int 59alias_RedirectPort(struct cmdargs const *arg) 60{ 61 if (!arg->bundle->AliasEnabled) { 62 prompt_Printf(arg->prompt, "Alias not enabled\n"); 63 return 1; 64 } else if (arg->argc == arg->argn+3) { 65 char proto_constant; 66 const char *proto; 67 u_short local_port; 68 u_short alias_port; 69 int error; 70 struct in_addr local_addr; 71 struct in_addr null_addr; 72 struct alias_link *link; 73 74 proto = arg->argv[arg->argn]; 75 if (strcmp(proto, "tcp") == 0) { 76 proto_constant = IPPROTO_TCP; 77 } else if (strcmp(proto, "udp") == 0) { 78 proto_constant = IPPROTO_UDP; 79 } else { 80 prompt_Printf(arg->prompt, "port redirect: protocol must be" 81 " tcp or udp\n"); 82 prompt_Printf(arg->prompt, "Usage: alias %s %s\n", arg->cmd->name, 83 arg->cmd->syntax); 84 return 1; 85 } 86 87 error = StrToAddrAndPort(arg->argv[arg->argn+1], &local_addr, &local_port, 88 proto); 89 if (error) { 90 prompt_Printf(arg->prompt, "port redirect: error reading" 91 " local addr:port\n"); 92 prompt_Printf(arg->prompt, "Usage: alias %s %s\n", arg->cmd->name, 93 arg->cmd->syntax); 94 return 1; 95 } 96 error = StrToPort(arg->argv[arg->argn+2], &alias_port, proto); 97 if (error) { 98 prompt_Printf(arg->prompt, "port redirect: error reading alias port\n"); 99 prompt_Printf(arg->prompt, "Usage: alias %s %s\n", arg->cmd->name, 100 arg->cmd->syntax); 101 return 1; 102 } 103 null_addr.s_addr = INADDR_ANY; 104 105 link = PacketAliasRedirectPort(local_addr, local_port, 106 null_addr, 0, 107 null_addr, alias_port, 108 proto_constant); 109 110 if (link == NULL) 111 prompt_Printf(arg->prompt, "port redirect: error returned by packed" 112 " aliasing engine (code=%d)\n", error); 113 } else 114 return -1; 115 116 return 0; 117} 118 119 120int 121alias_RedirectAddr(struct cmdargs const *arg) 122{ 123 if (!arg->bundle->AliasEnabled) { 124 prompt_Printf(arg->prompt, "alias not enabled\n"); 125 return 1; 126 } else if (arg->argc == arg->argn+2) { 127 int error; 128 struct in_addr local_addr; 129 struct in_addr alias_addr; 130 struct alias_link *link; 131 132 error = StrToAddr(arg->argv[arg->argn], &local_addr); 133 if (error) { 134 prompt_Printf(arg->prompt, "address redirect: invalid local address\n"); 135 return 1; 136 } 137 error = StrToAddr(arg->argv[arg->argn+1], &alias_addr); 138 if (error) { 139 prompt_Printf(arg->prompt, "address redirect: invalid alias address\n"); 140 prompt_Printf(arg->prompt, "Usage: alias %s %s\n", arg->cmd->name, 141 arg->cmd->syntax); 142 return 1; 143 } 144 link = PacketAliasRedirectAddr(local_addr, alias_addr); 145 if (link == NULL) { 146 prompt_Printf(arg->prompt, "address redirect: packet aliasing" 147 " engine error\n"); 148 prompt_Printf(arg->prompt, "Usage: alias %s %s\n", arg->cmd->name, 149 arg->cmd->syntax); 150 } 151 } else 152 return -1; 153 154 return 0; 155} 156 157 158static int 159StrToAddr(const char *str, struct in_addr *addr) 160{ 161 struct hostent *hp; 162 163 if (inet_aton(str, addr)) 164 return 0; 165 166 hp = gethostbyname(str); 167 if (!hp) { 168 log_Printf(LogWARN, "StrToAddr: Unknown host %s.\n", str); 169 return -1; 170 } 171 *addr = *((struct in_addr *) hp->h_addr); 172 return 0; 173} 174 175 176static int 177StrToPort(const char *str, u_short *port, const char *proto) 178{ 179 int iport; 180 struct servent *sp; 181 char *end; 182 183 iport = strtol(str, &end, 10); 184 if (end != str) { 185 *port = htons(iport); 186 return 0; 187 } 188 sp = getservbyname(str, proto); 189 if (!sp) { 190 log_Printf(LogWARN, "StrToAddr: Unknown port or service %s/%s.\n", 191 str, proto); 192 return -1; 193 } 194 *port = sp->s_port; 195 return 0; 196} 197 198 199static int 200StrToAddrAndPort(const char *str, struct in_addr *addr, u_short *port, const char *proto) 201{ 202 char *colon; 203 int res; 204 205 colon = strchr(str, ':'); 206 if (!colon) { 207 log_Printf(LogWARN, "StrToAddrAndPort: %s is missing port number.\n", str); 208 return -1; 209 } 210 211 *colon = '\0'; /* Cheat the const-ness ! */ 212 res = StrToAddr(str, addr); 213 *colon = ':'; /* Cheat the const-ness ! */ 214 if (res != 0) 215 return -1; 216 217 return StrToPort(colon+1, port, proto); 218} 219 220int 221alias_ProxyRule(struct cmdargs const *arg) 222{ 223 char cmd[LINE_LEN]; 224 int f, pos; 225 size_t len; 226 227 if (arg->argn >= arg->argc) 228 return -1; 229 230 for (f = arg->argn, pos = 0; f < arg->argc; f++) { 231 len = strlen(arg->argv[f]); 232 if (sizeof cmd - pos < len + (f ? 1 : 0)) 233 break; 234 if (f) 235 cmd[pos++] = ' '; 236 strcpy(cmd + pos, arg->argv[f]); 237 pos += len; 238 } 239 240 return PacketAliasProxyRule(cmd); 241} 242 243int 244alias_Pptp(struct cmdargs const *arg) 245{ 246 struct in_addr addr; 247 248 if (arg->argc == arg->argn) { 249 addr.s_addr = INADDR_NONE; 250 PacketAliasPptp(addr); 251 return 0; 252 } 253 254 if (arg->argc != arg->argn + 1) 255 return -1; 256 257 addr = GetIpAddr(arg->argv[arg->argn]); 258 if (addr.s_addr == INADDR_NONE) { 259 log_Printf(LogWARN, "%s: invalid address\n", arg->argv[arg->argn]); 260 return 1; 261 } 262 263 PacketAliasPptp(addr); 264 return 0; 265} 266