| 287 | } |
| 288 | |
| 289 | static void |
| 290 | AliasHandleFtpIn(struct libalias *la, |
| 291 | struct ip *pip, /* IP packet to examine/patch */ |
| 292 | struct alias_link *lnk) /* The link to go through (aliased port) */ |
| 293 | { |
| 294 | int hlen, tlen, dlen, pflags; |
| 295 | char *sptr; |
| 296 | struct tcphdr *tc; |
| 297 | |
| 298 | /* Calculate data length of TCP packet */ |
| 299 | tc = (struct tcphdr *)ip_next(pip); |
| 300 | hlen = (pip->ip_hl + tc->th_off) << 2; |
| 301 | tlen = ntohs(pip->ip_len); |
| 302 | dlen = tlen - hlen; |
| 303 | |
| 304 | /* Place string pointer and beginning of data */ |
| 305 | sptr = (char *)pip; |
| 306 | sptr += hlen; |
| 307 | |
| 308 | /* |
| 309 | * Check that data length is not too long and previous message was |
| 310 | * properly terminated with CRLF. |
| 311 | */ |
| 312 | pflags = GetProtocolFlags(lnk); |
| 313 | if (dlen <= MAX_MESSAGE_SIZE && (pflags & WAIT_CRLF) == 0 && |
| 314 | ntohs(tc->th_dport) == FTP_CONTROL_PORT_NUMBER && |
| 315 | (ParseFtpPortCommand(la, sptr, dlen) != 0 || |
| 316 | ParseFtpEprtCommand(la, sptr, dlen) != 0)) { |
| 317 | /* |
| 318 | * Alias active mode client requesting data from server |
| 319 | * behind NAT. We need to alias server->client connection |
| 320 | * to external address client is connecting to. |
| 321 | */ |
| 322 | AddLink(la, GetOriginalAddress(lnk), la->true_addr, |
| 323 | GetAliasAddress(lnk), htons(FTP_CONTROL_PORT_NUMBER - 1), |
| 324 | htons(la->true_port), GET_ALIAS_PORT, IPPROTO_TCP); |
| 325 | } |
| 326 | /* Track the msgs which are CRLF term'd for PORT/PASV FW breach */ |
| 327 | if (dlen) { |
| 328 | sptr = (char *)pip; /* start over at beginning */ |
| 329 | tlen = ntohs(pip->ip_len); /* recalc tlen, pkt may |
| 330 | * have grown. |
| 331 | */ |
| 332 | if (sptr[tlen - 2] == '\r' && sptr[tlen - 1] == '\n') |
| 333 | pflags &= ~WAIT_CRLF; |
| 334 | else |
| 335 | pflags |= WAIT_CRLF; |
| 336 | SetProtocolFlags(lnk, pflags); |
| 337 | } |
| 338 | } |
| 339 | |
| 340 | static int |
| 341 | ParseFtpPortCommand(struct libalias *la, char *sptr, int dlen) |
no test coverage detected