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