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