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