| 501 | } |
| 502 | |
| 503 | static int |
| 504 | ParseFtp227Reply(struct libalias *la, char *sptr, int dlen) |
| 505 | { |
| 506 | char ch; |
| 507 | int i, state; |
| 508 | u_int32_t addr; |
| 509 | u_short port; |
| 510 | u_int8_t octet; |
| 511 | |
| 512 | /* Format: "227 Entering Passive Mode (A,D,D,R,PO,RT)" */ |
| 513 | |
| 514 | /* Return if data length is too short. */ |
| 515 | if (dlen < 17) |
| 516 | return (0); |
| 517 | |
| 518 | if (strncmp("227 ", sptr, 4)) |
| 519 | return (0); |
| 520 | |
| 521 | addr = port = octet = 0; |
| 522 | |
| 523 | state = 0; |
| 524 | for (i = 4; i < dlen; i++) { |
| 525 | ch = sptr[i]; |
| 526 | switch (state) { |
| 527 | case 0: |
| 528 | if (ch == '(') |
| 529 | state++; |
| 530 | break; |
| 531 | case 1: |
| 532 | case 3: |
| 533 | case 5: |
| 534 | case 7: |
| 535 | case 9: |
| 536 | case 11: |
| 537 | if (isdigit(ch)) { |
| 538 | octet = ch - '0'; |
| 539 | state++; |
| 540 | } else |
| 541 | return (0); |
| 542 | break; |
| 543 | case 2: |
| 544 | case 4: |
| 545 | case 6: |
| 546 | case 8: |
| 547 | if (isdigit(ch)) |
| 548 | octet = 10 * octet + ch - '0'; |
| 549 | else if (ch == ',') { |
| 550 | addr = (addr << 8) + octet; |
| 551 | state++; |
| 552 | } else |
| 553 | return (0); |
| 554 | break; |
| 555 | case 10: |
| 556 | case 12: |
| 557 | if (isdigit(ch)) |
| 558 | octet = 10 * octet + ch - '0'; |
| 559 | else if (ch == ',' || (state == 12 && ch == ')')) { |
| 560 | port = (port << 8) + octet; |
no test coverage detected