ΠΡΠΈ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΠΈ Π·Π°ΠΏΡΠΎΡΠ° Π΄Π»Ρ ΡΡΠ΅Π½ΠΈΡ tftp-ΡΠ΅ΡΠ²Π΅Ρ ΠΏΠΎΡΡΠ»Π°Π΅Ρ ΡΠ°ΠΉΠ» (512 Π±Π°ΠΉΡ Π·Π° ΠΎΠ΄ΠΈΠ½ ΡΠ°Π·). ΠΠ°ΠΆΠ΄Π°Ρ Π΄Π΅ΠΉΡΠ°Π³ΡΠ°ΠΌΠΌΠ° ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ Π½ΠΎΠΌΠ΅Ρ Π±Π»ΠΎΠΊΠ° (Π½ΡΠΌΠ΅ΡΠ°ΡΠΈΡ Π½Π°ΡΠΈΠ½Π°Π΅ΡΡΡ Ρ Π΅Π΄ΠΈΠ½ΠΈΡΡ). ΠΠΎΠ³Π΄Π° ΠΊΠ»ΠΈΠ΅Π½Ρ ΠΏΠΎΠ»ΡΡΠ°Π΅Ρ Π±Π»ΠΎΠΊ Π΄Π°Π½Π½ΡΡ , ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΠΈΠΉ ΠΌΠ΅Π½Π΅Π΅ 512 Π±Π°ΠΉΡΠΎΠ², ΠΎΠ½ Π·Π½Π°Π΅Ρ, ΡΡΠΎ ΡΠ°ΠΉΠ» ΠΏΠΎΠ»ΡΡΠ΅Π½ Π΄ΠΎΠ»ΠΆΠ½ΡΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ. ΠΠΎΡΠ»Π΅ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ Π΄Π΅ΠΉΡΠ°Π³ΡΠ°ΠΌΠΌΡ ΠΊΠ»ΠΈΠ΅Π½Ρ ΠΏΠΎΡΡΠ»Π°Π΅Ρ ΠΎΡΠ²Π΅ΡΠ½ΡΡ Π΄Π΅ΠΉΡΠ°Π³ΡΠ°ΠΌΠΌΡ Ρ Π½ΠΎΠΌΠ΅ΡΠΎΠΌ Π±Π»ΠΎΠΊΠ°, ΠΏΠΎΠ΄ΡΠ²Π΅ΡΠΆΠ΄Π°ΡΡΡΡ, ΡΡΠΎ Π΄Π°Π½Π½ΡΠΉ Π±Π»ΠΎΠΊ ΡΡΠΏΠ΅ΡΠ½ΠΎ ΠΏΠΎΠ»ΡΡΠ΅Π½. ΠΠ°ΠΊ ΡΠΎΠ»ΡΠΊΠΎ ΡΠ΅ΡΠ²Π΅Ρ Π²ΠΈΠ΄ΠΈΡ ΠΏΠΎΠ΄ΡΠ²Π΅ΡΠΆΠ΄Π΅Π½ΠΈΠ΅, ΠΎΠ½ ΠΎΡΠΏΡΠ°Π²Π»ΡΠ΅Ρ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΉ Π±Π»ΠΎΠΊ Π΄Π°Π½Π½ΡΡ .
ΠΡΠ½ΠΎΠ²Π½ΠΎΠΉ ΡΠΎΡΠΌΠ°Ρ Π΄Π΅ΠΉΡΠ°Π³ΡΠ°ΠΌΠΌΡ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ Π² ΡΡΡΠΎΠΊΠ°Ρ 17-46. ΠΠ΅ΠΊΠΎΡΠΎΡΡΠ΅ ΠΊΠΎΠ½ΡΡΠ°Π½ΡΡ ΡΠΊΠ°Π·ΡΠ²Π°ΡΡ ΡΠΈΠΏ ΠΏΠΎΡΡΠ»Π°Π΅ΠΌΠΎΠΉ Π΄Π΅ΠΉΡΠ°Π³ΡΠ°ΠΌΠΌΡ, Π° ΡΠ°ΠΊΠΆΠ΅ ΠΊΠΎΠ΄ ΠΎΡΠΈΠ±ΠΊΠΈ, ΠΎΡΠΏΡΠ°Π²Π»ΡΠ΅ΠΌΠΎΠΉ Π² ΡΠΎΠΌ ΡΠ»ΡΡΠ°Π΅, Π΅ΡΠ»ΠΈ Π·Π°ΠΏΡΠ°ΡΠΈΠ²Π°Π΅ΠΌΡΠΉ ΡΠ°ΠΉΠ» Π½Π΅ ΡΡΡΠ΅ΡΡΠ²ΡΠ΅Ρ (Π²ΡΠ΅ ΠΎΡΡΠ°Π»ΡΠ½ΡΠ΅ ΠΎΡΠΈΠ±ΠΊΠΈ ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°ΡΡΡΡ Π½Π΅ΠΏΠΎΡΡΠ΅Π΄ΡΡΠ²Π΅Π½Π½ΠΎ ΡΠ΅ΡΠ²Π΅ΡΠΎΠΌ). Π‘ΡΡΡΠΊΡΡΡΠ° struct tftpPacket ΠΎΠΏΠΈΡΡΠ²Π°Π΅Ρ Π²Π½Π΅ΡΠ½ΠΈΠΉ Π²ΠΈΠ΄ Π΄Π΅ΠΉΡΠ°Π³ΡΠ°ΠΌΠΌΡ ΠΈ ΠΊΠΎΠ΄ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ, ΡΠ»Π΅Π΄ΡΡΡΠ΅ΠΉ Π·Π° Π΄Π°Π½Π½ΡΠΌΠΈ, ΠΊΠΎΡΠΎΡΠ°Ρ Π·Π°Π²ΠΈΡΠΈΡ ΠΎΡ ΡΠΈΠΏΠ° Π΄Π΅ΠΉΡΠ°Π³ΡΠ°ΠΌΠΌΡ. ΠΠ°ΡΠ΅ΠΌ Π»ΠΎΠ³ΠΈΡΠ΅ΡΠΊΠΎΠ΅ ΠΎΠ±ΡΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠ΅, Π²Π»ΠΎΠΆΠ΅Π½Π½ΠΎΠ΅ Π² ΡΡΡΡΠΊΡΡΡΡ, ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅Ρ ΠΎΡΡΠ°Π»ΡΠ½ΡΠ΅ ΡΠΎΡΠΌΠ°ΡΡ Π΄Π΅ΠΉΡΠ°Π³ΡΠ°ΠΌΠΌ Π΄Π»Ρ ΠΎΡΠΈΠ±ΠΎΠΊ, Π΄Π°Π½Π½ΡΡ ΠΈ ΠΏΠ°ΠΊΠ΅ΡΠΎΠ² ΠΏΠΎΠ΄ΡΠ²Π΅ΡΠΆΠ΄Π΅Π½ΠΈΡ.
ΠΠ΅ΡΠ²Π°Ρ ΡΠ°ΡΡΡ main() (ΡΡΡΠΎΠΊΠΈ 156β169) ΡΠΎΠ·Π΄Π°Π΅Ρ UDP-ΡΠΎΠΊΠ΅Ρ ΠΈ ΡΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅Ρ Π½ΠΎΠΌΠ΅Ρ Π»ΠΎΠΊΠ°Π»ΡΠ½ΠΎΠ³ΠΎ ΠΏΠΎΡΡΠ° Ρ ΠΏΠΎΠΌΠΎΡΡΡ Π²ΡΠ·ΠΎΠ²Π° bind(). ΠΠΎΡΠ»Π΅Π΄Π½ΠΈΠΉ ΡΠ²Π»ΡΠ΅ΡΡΡ Π»ΠΈΠ±ΠΎ ΠΎΡΠΈΡΠΈΠ°Π»ΡΠ½ΠΎΠΉ tftp-ΡΠ»ΡΠΆΠ±ΠΎΠΉ, Π»ΠΈΠ±ΠΎ ΠΏΠΎΡΡΠΎΠΌ, ΡΠΊΠ°Π·Π°Π½Π½ΡΠΌ Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ Π΅Π΄ΠΈΠ½ΡΡΠ²Π΅Π½Π½ΠΎΠ³ΠΎ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠ° ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ ΡΡΡΠΎΠΊΠΈ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ. Π ΠΎΡΠ»ΠΈΡΠΈΠ΅ ΠΎΡ Π½Π°ΡΠ΅Π³ΠΎ ΠΏΡΠΈΠΌΠ΅ΡΠ° TCP-ΡΠ΅ΡΠ²Π΅ΡΠ° Π·Π΄Π΅ΡΡ Π½Π΅Ρ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΡΡΠΈ Π²ΡΠ·ΡΠ²Π°ΡΡ Π½ΠΈ listen(), Π½ΠΈ accept(), ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ UDP ΡΠ°Π±ΠΎΡΠ°Π΅Ρ Π±Π΅Π· ΡΡΡΠ°Π½ΠΎΠ²ΠΊΠΈ ΡΠΎΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠΉ.
ΠΠΎΡΠ»Π΅ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΡΠΎΠΊΠ΅ΡΠ° ΡΠ΅ΡΠ²Π΅Ρ ΠΎΠΆΠΈΠ΄Π°Π΅Ρ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΠ΅ Π΄Π΅ΠΉΡΠ°Π³ΡΠ°ΠΌΠΌΡ ΠΏΡΡΠ΅ΠΌ Π²ΡΠ·ΠΎΠ²Π° recvfrom(). Π€ΡΠ½ΠΊΡΠΈΡ handleRequest(), ΠΊΠΎΡΠΎΡΠ°Ρ Π°ΠΊΡΠΈΠ²ΠΈΠ·ΠΈΡΡΠ΅ΡΡΡ Π² ΡΡΡΠΎΠΊΠ΅ 181, ΠΏΡΠ΅ΠΎΠ±ΡΠ°Π·ΡΠ΅Ρ Π·Π°ΠΏΡΠ°ΡΠΈΠ²Π°Π΅ΠΌΡΠΉ ΡΠ°ΠΉΠ» ΠΈ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ Π΅Π³ΠΎ. ΠΠΎΡΠ»Π΅ ΡΡΠΎΠ³ΠΎ Π²ΡΠ·ΠΎΠ²Π° ΡΠ΅ΡΠ²Π΅Ρ Π΅ΡΠ΅ ΡΠ°Π· Π°ΠΊΡΠΈΠ²ΠΈΠ·ΠΈΡΡΠ΅Ρ recvfrom() ΠΈ ΠΎΠΆΠΈΠ΄Π°Π΅Ρ Π·Π°ΠΏΡΠΎΡ ΠΎΡ ΡΠ»Π΅Π΄ΡΡΡΠ΅Π³ΠΎ ΠΊΠ»ΠΈΠ΅Π½ΡΠ°.
ΠΠΎΠΌΠΌΠ΅Π½ΡΠ°ΡΠΈΠΉ, ΡΠ°ΡΠΏΠΎΠ»ΠΎΠΆΠ΅Π½Π½ΡΠΉ ΠΏΠ΅ΡΠ΅Π΄ Π²ΡΠ·ΠΎΠ²ΠΎΠΌ handleRequest(), ΡΠΎΠΎΠ±ΡΠ°Π΅Ρ, ΡΡΠΎ Π΄Π°Π½Π½ΡΠΉ ΡΠ΅ΡΠ²Π΅Ρ ΠΌΠΎΠΆΠ½ΠΎ Π»Π΅Π³ΠΊΠΎ ΠΏΠ΅ΡΠ΅ΠΊΠ»ΡΡΠΈΡΡ Ρ ΠΈΡΠ΅ΡΠ°ΡΠΈΠ²Π½ΠΎΠ³ΠΎ ΡΠ΅ΡΠ²Π΅ΡΠ° Π½Π° ΠΏΠ°ΡΠ°Π»Π»Π΅Π»ΡΠ½ΡΠΉ, ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΠ² ΠΊΠ°ΠΆΠ΄ΠΎΠΌΡ Π²ΡΠ·ΠΎΠ²Ρ handleRequest() ΡΠ°Π±ΠΎΡΠ°ΡΡ ΠΊΠ°ΠΊ ΡΠ°ΠΌΠΎΡΡΠΎΡΡΠ΅Π»ΡΠ½ΠΎΠΌΡ ΠΏΡΠΎΡΠ΅ΡΡΡ.
Π ΡΠΎ Π²ΡΠ΅ΠΌΡ ΠΊΠ°ΠΊ Π³Π»Π°Π²Π½Π°Ρ ΡΠ°ΡΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅Ρ Π½Π΅ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½Π½ΡΠΉ UDP-ΡΠΎΠΊΠ΅Ρ (ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡΡΠΈΠΉ Π»ΡΠ±ΠΎΠΌΡ ΠΊΠ»ΠΈΠ΅Π½ΡΡ ΡΠΎΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠ΅ Ρ Π½ΠΈΠΌ), handleSocket() ΠΏΡΠΈΠΌΠ΅Π½ΡΠ΅Ρ Π΄Π»Ρ ΠΏΡΠ΅ΠΎΠ±ΡΠ°Π·ΠΎΠ²Π°Π½ΠΈΡ ΡΠ°ΠΉΠ»Π° ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½Π½ΡΠΉ UDP-ΡΠΎΠΊΠ΅Ρ[144]. ΠΠΎΡΠ»Π΅ Π°Π½Π°Π»ΠΈΠ·Π° ΠΈΠΌΠ΅Π½ΠΈ ΡΠ°ΠΉΠ»Π°, ΠΊΠΎΡΠΎΡΡΠΉ Π½ΡΠΆΠ½ΠΎ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡ, ΠΈ ΠΏΡΠΎΠ²Π΅ΡΠΊΠΈ ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½ΠΎΡΡΠΈ ΡΠ΅ΠΆΠΈΠΌΠ° ΠΏΡΠ΅ΠΎΠ±ΡΠ°Π·ΠΎΠ²Π°Π½ΠΈΡ Π² ΡΡΡΠΎΠΊΠ΅ 93 ΡΠΎΠ·Π΄Π°Π΅ΡΡΡ ΡΠΎΠΊΠ΅Ρ Ρ ΡΠ΅ΠΌ ΠΆΠ΅ ΡΠ°ΠΌΡΠΌ ΡΠ΅ΠΌΠ΅ΠΉΡΡΠ²ΠΎΠΌ, ΡΠΈΠΏΠΎΠΌ ΠΈ ΠΏΡΠΎΡΠΎΠΊΠΎΠ»ΠΎΠΌ, Ρ ΠΊΠΎΡΠΎΡΡΠΌΠΈ ΠΊΠΎΠ½ΡΠ°ΠΊΡΠΈΡΠΎΠ²Π°Π» ΡΠ΅ΡΠ²Π΅Ρ. ΠΠ°ΡΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ connect() Π΄Π»Ρ ΡΡΡΠ°Π½ΠΎΠ²ΠΊΠΈ ΡΠ΄Π°Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΠΊΠΎΠ½ΡΠ° ΡΠΎΠΊΠ΅ΡΠ° Π½Π° ΡΠΎΠΌ Π°Π΄ΡΠ΅ΡΠ΅, ΠΎΡ ΠΊΠΎΡΠΎΡΠΎΠ³ΠΎ ΠΏΠΎΡΡΡΠΏΠΈΠ» Π·Π°ΠΏΡΠΎΡ Π½Π° ΡΠ°ΠΉΠ», ΠΈ Π½Π°ΡΠΈΠ½Π°Π΅ΡΡΡ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠ° ΡΠ°ΠΉΠ»Π°. ΠΠΎΡΠ»Π΅ ΠΎΡΠΏΡΠ°Π²ΠΊΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Π±Π»ΠΎΠΊΠ° ΡΠ΅ΡΠ²Π΅Ρ ΠΎΠΆΠΈΠ΄Π°Π΅Ρ ΠΏΠ°ΠΊΠ΅Ρ ΠΏΠΎΠ΄ΡΠ²Π΅ΡΠΆΠ΄Π΅Π½ΠΈΡ, ΠΏΡΠ΅ΠΆΠ΄Π΅ ΡΠ΅ΠΌ ΠΏΡΠΎΠ΄ΠΎΠ»ΠΆΠΈΡΡ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡ. ΠΠΎΠ³Π΄Π° ΠΏΡΠΈΡ ΠΎΠ΄ΠΈΡ ΠΏΠΎΡΠ»Π΅Π΄Π½ΠΈΠΉ ΠΏΠ°ΠΊΠ΅Ρ ΠΏΠΎΠ΄ΡΠ²Π΅ΡΠΆΠ΄Π΅Π½ΠΈΡ, ΡΠ΅ΡΠ²Π΅Ρ Π·Π°ΠΊΡΡΠ²Π°Π΅Ρ ΡΠΎΠΊΠ΅Ρ ΠΈ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅ΡΡΡ ΠΊ Π³Π»Π°Π²Π½ΠΎΠΌΡ ΡΠΈΠΊΠ»Ρ.
ΠΠ°Π½Π½ΡΠΉ ΡΠ΅ΡΠ²Π΅Ρ, ΠΊΠ°ΠΊ ΠΏΡΠ°Π²ΠΈΠ»ΠΎ, Π·Π°ΠΏΡΡΠΊΠ°Π΅ΡΡΡ Ρ Π΅Π΄ΠΈΠ½ΡΡΠ²Π΅Π½Π½ΡΠΌ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠΎΠΌ β Π½ΠΎΠΌΠ΅ΡΠΎΠΌ ΠΏΠΎΡΡΠ°. ΠΠ»Ρ ΠΏΡΠΎΠ²Π΅ΡΠΊΠΈ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡΠΈΠΌΠ΅Π½ΠΈΡΡ ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΡΡ ΠΊΠ»ΠΈΠ΅Π½ΡΡΠΊΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ tftp, Π³Π΄Π΅ ΠΏΠ΅ΡΠ²ΡΠΉ Π°ΡΠ³ΡΠΌΠ΅Π½Ρ ΡΠ²Π»ΡΠ΅ΡΡΡ ΠΈΠΌΠ΅Π½Π΅ΠΌ Ρ ΠΎΡΡΠ° Π΄Π»Ρ ΡΠΎΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΡ (Π½Π΅ΠΏΠ»ΠΎΡ ΠΈΠΌ Π²ΡΠ±ΠΎΡΠΎΠΌ Π±ΡΠ΄Π΅Ρ localhost), Π° Π²ΡΠΎΡΠΎΠΉ β Π½ΠΎΠΌΠ΅ΡΠΎΠΌ ΠΏΠΎΡΡΠ°, Π½Π° ΠΊΠΎΡΠΎΡΠΎΠΌ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ ΡΠ΅ΡΠ²Π΅Ρ. ΠΠΎΡΠ»Π΅ Π·Π°ΠΏΡΡΠΊΠ° ΠΊΠ»ΠΈΠ΅Π½ΡΠ° Π½ΡΠΆΠ½ΠΎ Π°ΠΊΡΠΈΠ²ΠΈΠ·ΠΈΡΠΎΠ²Π°ΡΡ ΠΊΠΎΠΌΠ°Π½Π΄Ρ bin, ΠΏΡΠΈ ΡΡΠΎΠΌ ΡΠ°ΠΉΠ»Ρ Π±ΡΠ΄ΡΡ Π·Π°ΠΏΡΠ°ΡΠΈΠ²Π°ΡΡΡΡ Π² ΡΠ΅ΠΆΠΈΠΌΠ΅ octet, Π° Π½Π΅ Π² ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΠΎΠΌ ΡΠ΅ΠΆΠΈΠΌΠ΅ netascii. ΠΠ°ΠΊ ΡΠΎΠ»ΡΠΊΠΎ ΡΡΠΎ ΡΠ΄Π΅Π»Π°Π½ΠΎ, ΠΊΠΎΠΌΠ°Π½Π΄Π° get ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡ Π»ΡΠ±ΠΎΠΉ ΡΠ°ΠΉΠ» ΠΎΡ ΡΠ΅ΡΠ²Π΅ΡΠ° ΠΊΠ»ΠΈΠ΅Π½ΡΡ.
1: /* tftpserver.c */
2:
3: /* ΠΡΠΎ ΡΠ°ΡΡΠΈΡΠ½Π°Ρ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ tftp. ΠΠ½Π° Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅Ρ Π΄Π°ΠΆΠ΅ ΡΠ°ΠΉΠΌ-Π°ΡΡΡ
4: ΠΈΠ»ΠΈ ΠΏΠΎΠ²ΡΠΎΡΠ½ΡΡ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡ ΠΏΠ°ΠΊΠ΅ΡΠΎΠ², ΠΈ ΠΎΠ½Π° Π½Π΅ ΠΎΡΠ΅Π½Ρ Ρ ΠΎΡΠΎΡΠΎ
5: ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°Π΅Ρ Π½Π΅ΠΏΡΠ΅Π΄Π²ΠΈΠ΄Π΅Π½Π½ΡΠ΅ ΡΠΎΠ±ΡΡΠΈΡ.*/
6:
7: #include <netdb.h>
8: #include <stdio.h>
9: #include <stdlib.h>
10: #include <string.h>
11: #include <sys/socket.h>
12: #include <unistd.h>
13: #include <fcntl.h>
14:
15: #include "sockutil.h" /* Π½Π΅ΠΊΠΎΡΠΎΡΡΠ΅ ΡΠ»ΡΠΆΠ΅Π±Π½ΡΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ */
16:
17: #define RRQ 1 /* Π·Π°ΠΏΡΠΎΡ Π½Π° ΡΡΠ΅Π½ΠΈΠ΅ */
18: #define DATA 3 /* Π±Π»ΠΎΠΊ Π΄Π°Π½Π½ΡΡ */
19: #define ACK 4 /* ΠΏΠΎΠ΄ΡΠ²Π΅ΡΠΆΠ΄Π΅Π½ΠΈΠ΅ */
20: #define ERROR 5 /* Π²ΠΎΠ·Π½ΠΈΠΊΠ»Π° ΠΎΡΠΈΠ±ΠΊΠ° */
21:
22: /* ΠΊΠΎΠ΄Ρ ΠΎΡΠΈΠ±ΠΎΠΊ tftp */
23: #define FILE_NOT_FOUND 1
24:
25: struct tftpPacket {
26: short opcode;
27:
28: union {
29: char bytes[514]; /* ΡΠ°ΠΌΡΠΉ Π±ΠΎΠ»ΡΡΠΎΠΉ Π±Π»ΠΎΠΊ, ΠΊΠΎΡΠΎΡΡΠΉ ΠΌΡ
30: ΠΌΠΎΠΆΠ΅ΠΌ ΠΎΠ±ΡΠ°Π±ΠΎΡΠ°ΡΡ, ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ 2 Π±Π°ΠΉΡΠ°
31: Π΄Π»Ρ Π½ΠΎΠΌΠ΅ΡΠ° Π±Π»ΠΎΠΊΠ° ΠΈ 512 Π΄Π»Ρ Π΄Π°Π½Π½ΡΡ */
32: struct {
33: short code;
34: char message[200];
35: } error;
36:
37: struct {
38: short block;
39: char bytes[512];
40: } data;
41:
42: struct {
43: short block;
44: } ack;
45: } u;
46: };
47:
48: void sendError(int s, int errorCode) {
49: struct tftpPacket err;
50: int size;
51:
52: err.opcode = htons(ERROR);
53:
54: err.u.error.code = htons(errorCode); /* ΡΠ°ΠΉΠ» Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½ */
55: switch (errorCode) {
56: case FILE_NOT_FOUND:
57: strcpy(err.u.error.message, "ΡΠ°ΠΉΠ» Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½");
58: break;
59: }
60:
61: /* 2 Π±Π°ΠΉΡΠ° ΠΊΠΎΠ΄Π° ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ, 2 Π±Π°ΠΉΡΠ° ΠΊΠΎΠ΄Π° ΠΎΡΠΈΠ±ΠΊΠΈ, ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ ΠΈ '\0' */
62: size = 2 + 2 + strlen(err.u.error.message) + 1;
63: if (send(s, &err, size, 0) != size)
64: die("erarorsend");
65: }
66:
67: void handleRequest(struct addrinfo tftpAddr,
68: struct sockaddr remote, int remoteLen,
69: struct tftpPacket request) {
70: char * fileName;
71: char * mode;
72: int fd;
73: int s;
74: int size;
75: int sizeRead;
76: struct tftpPacket data, response;
77: int blockNum = 0;
78:
79: request.opcode = ntohs(request.opcode);
80: if (request.opcode != RRQ) die("Π½Π΅Π²Π΅ΡΠ½ΡΠΉ ΠΊΠΎΠ΄ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ");
81:
82: fileName = request.u.bytes;
83: mode = fileName + strlen(fileName) + 1;
84:
85: /* Π·Π΄Π΅ΡΡ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅ΡΡΡ ΡΠΎΠ»ΡΠΊΠΎ ΡΠ΅ΠΆΠΈΠΌ bin */
86: if (strcmp(mode, "octet")) {
87: fprintf(stderr, "Π½Π΅Π²Π΅ΡΠ½ΡΠΉ ΡΠ΅ΠΆΠΈΠΌ %s\n", mode);
88: exit(1);
89: }
90:
91: /* ΡΡΠ΅Π±ΡΠ΅ΡΡΡ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠ° ΠΏΡΠΈ ΠΏΠΎΠΌΠΎΡΠΈ ΡΠΎΠΊΠ΅ΡΠ° ΡΠΎΠ³ΠΎ ΠΆΠ΅ ΡΠ΅ΠΌΠ΅ΠΉΡΡΠ²Π° ΠΈ ΡΠΈΠΏΠ°,
92: Ρ ΠΊΠΎΡΠΎΡΡΠΌ ΠΌΡ Π½Π°ΡΠΈΠ½Π°Π»ΠΈ */
93: if ((s = socket(tftpAddr.ai_family, tftpAddr.ai_socktype,
94: tftpAddr.ai_protocol)) < 0)
95: die("send socket");
96:
97: /* ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ ΡΠ΄Π°Π»Π΅Π½Π½ΡΠΉ ΠΊΠΎΠ½Π΅Ρ ΡΠΎΠΊΠ΅ΡΠ° Π½Π° Π°Π΄ΡΠ΅Ρ, ΠΊΠΎΡΠΎΡΡΠΉ
98: ΠΈΠ½ΠΈΡΠΈΠΈΡΡΠ΅Ρ Π΄Π°Π½Π½ΠΎΠ΅ ΡΠΎΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠ΅ */
99: if (connect(s, &remote, remoteLen))
100: die("connect");
101:
102: if ((fd = open(fileName, O_RDONLY)) < 0) {
103: sendError(s, FILE_NOT_FOUND);
104: close(s);
105: return;
106: }
107:
108: data.opcode = htons(DATA);
109: while ((size = read(fd, data.u.data.bytes, 512)) > 0) {
110: data.u.data.block = htons(++blockNum);
111:
112: /* ΡΠ°Π·ΠΌΠ΅Ρ ΡΠΎΡΡΠ°Π²Π»ΡΡΡ 2 Π±Π°ΠΉΡΠ° (ΠΊΠΎΠ΄ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ), 2 Π±Π°ΠΉΡΠ° (Π½ΠΎΠΌΠ΅Ρ Π±Π»ΠΎΠΊΠ°) ΠΈ Π΄Π°Π½Π½ΡΠ΅*/
113: size += 4;
114: if (send(s, &data, size, 0) != size)
115: die("data send");
116:
117: sizeRead = recv(s, &response, sizeof(response), 0);
118: if (sizeRead < 0) die("recv ack");
119:
120: response.opcode = ntohs(response.opcode);
121: if (response.opcode != ACK) {
122: fprintf(stderr, "Π½Π΅ΠΏΡΠ΅Π΄Π²ΠΈΠ΄Π΅Π½Π½ΡΠΉ ΠΊΠΎΠ΄ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ Π² ΠΎΡΠΊΠ»ΠΈΠΊΠ΅\n");
123: exit(1);
124: }
125:
126: response.u.ack.block = ntohs(response.u.ack.block);
127: if (response.u.ack.block != blockNum) {
128: fprintf(stderr, "ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΎ ΠΏΠΎΠ΄ΡΠ²Π΅ΡΠΆΠ΄Π΅Π½ΠΈΠ΅ Π½Π΅Π²Π΅ΡΠ½ΠΎΠ³ΠΎ Π±Π»ΠΎΠΊΠ°\n");
129: exit(1);
130: }
131:
132: /* Π΅ΡΠ»ΠΈ Π±Π»ΠΎΠΊ, ΠΊΠΎΡΠΎΡΡΠΉ ΠΌΡ ΡΠΎΠ»ΡΠΊΠΎ ΡΡΠΎ ΠΎΡΠΏΡΠ°Π²ΠΈΠ»ΠΈ, ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ
133: ΠΌΠ΅Π½ΡΡΠ΅ 512 Π±Π°ΠΉΡ, ΡΠΎ Π·Π°Π΄Π°ΡΠ° Π²ΡΠΏΠΎΠ»Π½Π΅Π½Π° */
134: if (size < 516) break;
135: }
136:
137: close(s);
138: }
139:
140: int main(int argc, char ** argv) {
141: struct addrinfo hints, * addr;
142: char * portAddress = "tftp";
143: int s;
144: int rc;
145: int bytes, fromLen;
146: struct sockaddr from;
147: struct tftpPacket packet;
148:
149: if (argc > 2) {
150: fprintf(stderr, "ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅: tftpserver [ΠΏΠΎΡΡ]\n");
151: exit(1);
152: }
153:
154: if (argv[1]) portAddress = argv[1];
155:
156: memset(&hints, 0, sizeof (hints));
157:
158: hints.ai_socktype = SOCK_DGRAM;
159: hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
160: if ((rc = getaddrinfo(NULL, portAddress, &hints, &addr)))