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