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