nat_cmd.c revision 39395
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.17 1998/08/26 17:39:36 brian Exp $ 6 */ 7 8#include <sys/types.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#include "bundle.h" 48 49 50static int StrToAddr(const char *, struct in_addr *); 51static int StrToPort(const char *, u_short *, const char *); 52static int StrToAddrAndPort(const char *, struct in_addr *, u_short *, const char *); 53 54 55int 56alias_RedirectPort(struct cmdargs const *arg) 57{ 58 if (!arg->bundle->AliasEnabled) { 59 prompt_Printf(arg->prompt, "Alias not enabled\n"); 60 return 1; 61 } else if (arg->argc == arg->argn+3) { 62 char proto_constant; 63 const char *proto; 64 u_short local_port; 65 u_short alias_port; 66 int error; 67 struct in_addr local_addr; 68 struct in_addr null_addr; 69 struct alias_link *link; 70 71 proto = arg->argv[arg->argn]; 72 if (strcmp(proto, "tcp") == 0) { 73 proto_constant = IPPROTO_TCP; 74 } else if (strcmp(proto, "udp") == 0) { 75 proto_constant = IPPROTO_UDP; 76 } else { 77 prompt_Printf(arg->prompt, "port redirect: protocol must be" 78 " tcp or udp\n"); 79 prompt_Printf(arg->prompt, "Usage: alias %s %s\n", arg->cmd->name, 80 arg->cmd->syntax); 81 return 1; 82 } 83 84 error = StrToAddrAndPort(arg->argv[arg->argn+1], &local_addr, &local_port, 85 proto); 86 if (error) { 87 prompt_Printf(arg->prompt, "port redirect: error reading" 88 " local addr:port\n"); 89 prompt_Printf(arg->prompt, "Usage: alias %s %s\n", arg->cmd->name, 90 arg->cmd->syntax); 91 return 1; 92 } 93 error = StrToPort(arg->argv[arg->argn+2], &alias_port, proto); 94 if (error) { 95 prompt_Printf(arg->prompt, "port redirect: error reading alias port\n"); 96 prompt_Printf(arg->prompt, "Usage: alias %s %s\n", arg->cmd->name, 97 arg->cmd->syntax); 98 return 1; 99 } 100 null_addr.s_addr = INADDR_ANY; 101 102 link = PacketAliasRedirectPort(local_addr, local_port, 103 null_addr, 0, 104 null_addr, alias_port, 105 proto_constant); 106 107 if (link == NULL) 108 prompt_Printf(arg->prompt, "port redirect: error returned by packed" 109 " aliasing engine (code=%d)\n", error); 110 } else 111 return -1; 112 113 return 0; 114} 115 116 117int 118alias_RedirectAddr(struct cmdargs const *arg) 119{ 120 if (!arg->bundle->AliasEnabled) { 121 prompt_Printf(arg->prompt, "alias not enabled\n"); 122 return 1; 123 } else if (arg->argc == arg->argn+2) { 124 int error; 125 struct in_addr local_addr; 126 struct in_addr alias_addr; 127 struct alias_link *link; 128 129 error = StrToAddr(arg->argv[arg->argn], &local_addr); 130 if (error) { 131 prompt_Printf(arg->prompt, "address redirect: invalid local address\n"); 132 return 1; 133 } 134 error = StrToAddr(arg->argv[arg->argn+1], &alias_addr); 135 if (error) { 136 prompt_Printf(arg->prompt, "address redirect: invalid alias address\n"); 137 prompt_Printf(arg->prompt, "Usage: alias %s %s\n", arg->cmd->name, 138 arg->cmd->syntax); 139 return 1; 140 } 141 link = PacketAliasRedirectAddr(local_addr, alias_addr); 142 if (link == NULL) { 143 prompt_Printf(arg->prompt, "address redirect: packet aliasing" 144 " engine error\n"); 145 prompt_Printf(arg->prompt, "Usage: alias %s %s\n", arg->cmd->name, 146 arg->cmd->syntax); 147 } 148 } else 149 return -1; 150 151 return 0; 152} 153 154 155static int 156StrToAddr(const char *str, struct in_addr *addr) 157{ 158 struct hostent *hp; 159 160 if (inet_aton(str, addr)) 161 return 0; 162 163 hp = gethostbyname(str); 164 if (!hp) { 165 log_Printf(LogWARN, "StrToAddr: Unknown host %s.\n", str); 166 return -1; 167 } 168 *addr = *((struct in_addr *) hp->h_addr); 169 return 0; 170} 171 172 173static int 174StrToPort(const char *str, u_short *port, const char *proto) 175{ 176 int iport; 177 struct servent *sp; 178 char *end; 179 180 iport = strtol(str, &end, 10); 181 if (end != str) { 182 *port = htons(iport); 183 return 0; 184 } 185 sp = getservbyname(str, proto); 186 if (!sp) { 187 log_Printf(LogWARN, "StrToAddr: Unknown port or service %s/%s.\n", 188 str, proto); 189 return -1; 190 } 191 *port = sp->s_port; 192 return 0; 193} 194 195 196static int 197StrToAddrAndPort(const char *str, struct in_addr *addr, u_short *port, const char *proto) 198{ 199 char *colon; 200 int res; 201 202 colon = strchr(str, ':'); 203 if (!colon) { 204 log_Printf(LogWARN, "StrToAddrAndPort: %s is missing port number.\n", str); 205 return -1; 206 } 207 208 *colon = '\0'; /* Cheat the const-ness ! */ 209 res = StrToAddr(str, addr); 210 *colon = ':'; /* Cheat the const-ness ! */ 211 if (res != 0) 212 return -1; 213 214 return StrToPort(colon+1, port, proto); 215} 216