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 69 error = StrToPort(argv[2], &alias_port, proto); 70 if (error) { 71 if (VarTerm) { 72 fprintf(VarTerm, "port redirect: error reading alias port\n"); 73 fprintf(VarTerm, "Usage: alias %s %s\n", list->name, list->syntax); 74 } 75 return 1; 76 } 77 78 null_addr.s_addr = 0; 79 80 link = VarPacketAliasRedirectPort(local_addr, local_port, 81 null_addr, 0, 82 null_addr, alias_port, 83 proto_constant); 84 85 if (link == NULL && VarTerm) 86 fprintf(VarTerm, "port redirect: error returned by packed" 87 " aliasing engine (code=%d)\n", error); 88 } else if (VarTerm) 89 fprintf(VarTerm, "Usage: alias %s %s\n", list->name, list->syntax); 90 91 return 1; 92 } 93 94 95 int 96 AliasRedirectAddr(struct cmdtab *list, 97 int argc, 98 char **argv, 99 void *param) 100 { 101 if (!(mode & MODE_ALIAS)) { 102 if (VarTerm) 103 fprintf(VarTerm, "alias not enabled\n"); 104 } else if (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(argv[0], &local_addr); 111 if (error) { 112 if (VarTerm) 113 fprintf(VarTerm, "address redirect: invalid local address\n"); 114 return 1; 115 } 116 117 error = StrToAddr(argv[1], &alias_addr); 118 if (error) { 119 if (VarTerm) { 120 fprintf(VarTerm, "address redirect: invalid alias address\n"); 121 fprintf(VarTerm, "Usage: alias %s %s\n", list->name, list->syntax); 122 } 123 return 1; 124 } 125 126 link = VarPacketAliasRedirectAddr(local_addr, alias_addr); 127 if (link == NULL && VarTerm) { 128 fprintf(VarTerm, "address redirect: packet aliasing engine error\n"); 129 fprintf(VarTerm, "Usage: alias %s %s\n", list->name, list->syntax); 130 } 131 } else if (VarTerm) 132 fprintf(VarTerm, "Usage: alias %s %s\n", list->name, list->syntax); 133 134 return 1; 135 } 136 137 138 static int 139 StrToAddr (char* str, 140 struct in_addr* addr) 141 { 142 struct hostent* hp; 143 144 if (inet_aton (str, addr)) 145 return 0; 146 147 hp = gethostbyname (str); 148 if (!hp) 149 { 150 LogPrintf(LogWARN, "StrToAddr: Unknown host %s.\n", str); 151 return -1; 152 } 153 154 *addr = *((struct in_addr *) hp->h_addr); 155 return 0; 156 } 157 158 159 static int 160 StrToPort (char *str, 161 u_short *port, 162 char *proto) 163 { 164 int iport; 165 struct servent* sp; 166 char* end; 167 168 iport = strtol (str, &end, 10); 169 if (end != str) 170 { 171 *port = htons(iport); 172 return 0; 173 } 174 175 sp = getservbyname (str, proto); 176 if (!sp) 177 { 178 LogPrintf(LogWARN, "StrToAddr: Unknown port or service %s/%s.\n", 179 str, proto); 180 return -1; 181 } 182 183 *port = sp->s_port; 184 return 0; 185 } 186 187 188 int 189 StrToAddrAndPort (char* str, 190 struct in_addr* addr, 191 u_short *port, 192 char *proto) 193 { 194 char *ptr; 195 196 ptr = strchr (str, ':'); 197 if (!ptr) 198 { 199 LogPrintf(LogWARN, "StrToAddrAndPort: %s is missing port number.\n", 200 str); 201 return -1; 202 } 203 204 *ptr = '\0'; 205 ++ptr; 206 207 if (StrToAddr (str, addr) != 0) 208 return -1; 209 210 return StrToPort (ptr, port, proto); 211 } 212 213