nat_cmd.c revision 31923
1/*- 2 * Copyright (c) 1997 Charles Mott <cmott@srv.net> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $Id: alias_cmd.c,v 1.9 1997/12/21 12:11:04 brian Exp $ 27 */ 28 29#include <sys/param.h> 30#include <sys/socket.h> 31#include <netinet/in.h> 32#include <arpa/inet.h> 33#include <netdb.h> 34 35#include <limits.h> 36#include <stdio.h> 37#include <stdlib.h> 38#include <string.h> 39 40#include "defs.h" 41#include "command.h" 42#include "mbuf.h" 43#include "log.h" 44#include "loadalias.h" 45#include "vars.h" 46#include "alias_cmd.h" 47 48 49static int StrToAddr(const char *, struct in_addr *); 50static int StrToPort(const char *, u_short *, const char *); 51static int StrToAddrAndPort(const char *, struct in_addr *, u_short *, const char *); 52 53 54int 55AliasRedirectPort(struct cmdargs const *arg) 56{ 57 if (!(mode & MODE_ALIAS)) { 58 if (VarTerm) 59 fprintf(VarTerm, "Alias not enabled\n"); 60 return 1; 61 } else if (arg->argc == 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[0]; 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 if (VarTerm) { 78 fprintf(VarTerm, "port redirect: protocol must be tcp or udp\n"); 79 fprintf(VarTerm, "Usage: alias %s %s\n", arg->cmd->name, 80 arg->cmd->syntax); 81 } 82 return 1; 83 } 84 85 error = StrToAddrAndPort(arg->argv[1], &local_addr, &local_port, proto); 86 if (error) { 87 if (VarTerm) { 88 fprintf(VarTerm, "port redirect: error reading local addr:port\n"); 89 fprintf(VarTerm, "Usage: alias %s %s\n", arg->cmd->name, arg->cmd->syntax); 90 } 91 return 1; 92 } 93 error = StrToPort(arg->argv[2], &alias_port, proto); 94 if (error) { 95 if (VarTerm) { 96 fprintf(VarTerm, "port redirect: error reading alias port\n"); 97 fprintf(VarTerm, "Usage: alias %s %s\n", arg->cmd->name, arg->cmd->syntax); 98 } 99 return 1; 100 } 101 null_addr.s_addr = 0; 102 103 link = VarPacketAliasRedirectPort(local_addr, local_port, 104 null_addr, 0, 105 null_addr, alias_port, 106 proto_constant); 107 108 if (link == NULL && VarTerm) 109 fprintf(VarTerm, "port redirect: error returned by packed" 110 " aliasing engine (code=%d)\n", error); 111 } else 112 return -1; 113 114 return 0; 115} 116 117 118int 119AliasRedirectAddr(struct cmdargs const *arg) 120{ 121 if (!(mode & MODE_ALIAS)) { 122 if (VarTerm) 123 fprintf(VarTerm, "alias not enabled\n"); 124 return 1; 125 } else if (arg->argc == 2) { 126 int error; 127 struct in_addr local_addr; 128 struct in_addr alias_addr; 129 struct alias_link *link; 130 131 error = StrToAddr(arg->argv[0], &local_addr); 132 if (error) { 133 if (VarTerm) 134 fprintf(VarTerm, "address redirect: invalid local address\n"); 135 return 1; 136 } 137 error = StrToAddr(arg->argv[1], &alias_addr); 138 if (error) { 139 if (VarTerm) { 140 fprintf(VarTerm, "address redirect: invalid alias address\n"); 141 fprintf(VarTerm, "Usage: alias %s %s\n", arg->cmd->name, arg->cmd->syntax); 142 } 143 return 1; 144 } 145 link = VarPacketAliasRedirectAddr(local_addr, alias_addr); 146 if (link == NULL && VarTerm) { 147 fprintf(VarTerm, "address redirect: packet aliasing engine error\n"); 148 fprintf(VarTerm, "Usage: alias %s %s\n", arg->cmd->name, arg->cmd->syntax); 149 } 150 } else 151 return -1; 152 153 return 0; 154} 155 156 157static int 158StrToAddr(const char *str, struct in_addr *addr) 159{ 160 struct hostent *hp; 161 162 if (inet_aton(str, addr)) 163 return 0; 164 165 hp = gethostbyname(str); 166 if (!hp) { 167 LogPrintf(LogWARN, "StrToAddr: Unknown host %s.\n", str); 168 return -1; 169 } 170 *addr = *((struct in_addr *) hp->h_addr); 171 return 0; 172} 173 174 175static int 176StrToPort(const char *str, u_short *port, const char *proto) 177{ 178 int iport; 179 struct servent *sp; 180 char *end; 181 182 iport = strtol(str, &end, 10); 183 if (end != str) { 184 *port = htons(iport); 185 return 0; 186 } 187 sp = getservbyname(str, proto); 188 if (!sp) { 189 LogPrintf(LogWARN, "StrToAddr: Unknown port or service %s/%s.\n", 190 str, proto); 191 return -1; 192 } 193 *port = sp->s_port; 194 return 0; 195} 196 197 198static int 199StrToAddrAndPort(const char *str, struct in_addr *addr, u_short *port, const char *proto) 200{ 201 char *colon; 202 int res; 203 204 colon = strchr(str, ':'); 205 if (!colon) { 206 LogPrintf(LogWARN, "StrToAddrAndPort: %s is missing port number.\n", str); 207 return -1; 208 } 209 210 *colon = '\0'; /* Cheat the const-ness ! */ 211 res = StrToAddr(str, addr); 212 *colon = ':'; /* Cheat the const-ness ! */ 213 if (res != 0) 214 return -1; 215 216 return StrToPort(colon+1, port, proto); 217} 218