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