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