home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / MISC / NETWORK / PDCLK102.ZIP / PDCLKSET.ASM < prev    next >
Encoding:
Assembly Source File  |  1991-04-13  |  54.7 KB  |  2,360 lines

  1.  
  2. PAGE  44,132
  3.  
  4. ;*************************************************************************
  5. ;**                                                                     **
  6. ;**                     PDCLKSET                                        **
  7. ;**                                                                     **
  8. ;**                                                                     **
  9. ;**             Copyright (C) 1991 Jan.Engvald @ LDC.lu.se        **
  10. ;**                                                                     **
  11. ;** This program is free software; you can redistribute it and/or modify**
  12. ;** it under the terms of the GNU General Public License as published by**
  13. ;** the Free Software Foundation, version 1.                **
  14. ;**                                    **
  15. ;** This program is distributed in the hope that it will be useful,    **
  16. ;** but WITHOUT ANY WARRANTY; without even the implied warranty of    **
  17. ;** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    **
  18. ;** GNU General Public License for more details.            **
  19. ;**                                    **
  20. ;** You should have received a copy of the GNU General Public License    **
  21. ;** along with this program; if not, write to the Free Software        **
  22. ;** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.        **
  23. ;**                                                                     **
  24. ;*************************************************************************
  25. ;**                                                                     **
  26. ;** PDCLKSET sets the time and date of the PC clock using a TIME server.**
  27. ;** To do so, the following information is required:            **
  28. ;**                                     **
  29. ;** - This clients unique IP number.                    **
  30. ;** - The IP number of a UDP/IP time server.                **
  31. ;** - The time offset from UTC (GMT) at this place.            **
  32. ;** - If daylight saving (summer) time is used, which algorithm to use.    **
  33. ;**                                     **
  34. ;** All the above info can be supplied as arguments to PDCLKSET. If any    **
  35. ;** of the first three are missing, it will send a BOOTP request to try    **
  36. ;** to find the missing info. Except for client IP number, arguments to    **
  37. ;** PDCLKSET overrides BOOTP info.                    **
  38. ;**                                     **
  39. ;** BOOTP can not supply which dst algorithm to use; also, time offset    **
  40. ;** can't always be trusted. So, in practice, time offset and dst algo-    **
  41. ;** rithm (if applicable) are required arguments.            **
  42. ;**                                     **
  43. ;** If PDCLKSET finds more than one time server (sum of arguments and    **
  44. ;** BOOTP fields) and the first one does not answer, it will try the    **
  45. ;** second server.                            **
  46. ;**                                     **
  47. ;** It is very hard to get accurate info on all the dst algorithms used    **
  48. ;** all over the world, so the one you choose, you should test out. Use    **
  49. ;** the alter argument to add or subtract time and days, and check that    **
  50. ;** the dst switch occurs correctly. When using the alter argument, the    **
  51. ;** date and time is displayed as usual, but the PC clock is not set.    **
  52. ;** If you find any errors, mail me the correct info to my mail address    **
  53. ;** below. If you want to, you can customize your own dst algorithm, see**
  54. ;** detailed info below.                        **
  55. ;**                                     **
  56. ;** PDCLKSET talks to the network card via a packet driver. If you have    **
  57. ;** more than one packet driver, it will use the first one (lowest     **
  58. ;** packet interrupt number) unless you use the pktintno argument.    **
  59. ;** In AUTOEXEC.BAT you should first load the packet driver, then call    **
  60. ;** PDCLKSET. It is very small (6 kbyte) and executes fast, so you will    **
  61. ;** not notice any delay. PDCLKSET is not a TSR and does not require any**
  62. ;** CONFIG.SYS files, so no memory is wasted. Use TERMIN.COM if you want**
  63. ;** to unload the packet driver.                    **
  64. ;** Note: If you always log into a Novell server after a boot, you     **
  65. ;** don't need this program, the PC clock will be set from the server.    **
  66. ;**                                     **
  67. ;** Call syntax:                            **
  68. ;**                                     **
  69. ;**   (time is [- | +]{<hours>h | <minutes>m | <seconds>[s]})        **
  70. ;**                                    **
  71. ;** pdclkset b[ootp]         or                        **
  72. ;**                                    **
  73. ;** pdclkset [o[ffset]=time]                        **
  74. ;**                                     **
  75. ;**          [d[aylightsave]=PAC | USA | CUB | CHIL | BRZ | GBR |    **
  76. ;**                          W_EU | M_EU | E_EU | LIBY | EGY | TURK |    **
  77. ;**                          ISR | IRAN | PRC | ROK | AUS | TASM |    **
  78. ;**                  NSW | LHI | NZE |                **
  79. ;**                          FrTime,FrWeekDay,FrDayOfYear,        **
  80. ;**                          ToTime,ToWday,ToDayOfYr,AddTime]        **
  81. ;**                                     **
  82. ;**          [i[pnr]=n.n.n.n]  [t[imserver]=n.n.n.n[,n.n.n.n]]        **
  83. ;**                                     **
  84. ;**          [m[ask]=n.n.n.n]  [g[ateway]=n.n.n.n[,n.n.n.n]]        **
  85. ;**                                     **
  86. ;**          [a[lter]=days,time]  [p[ktintno]=decimalnr]        **
  87. ;**                                     **
  88. ;**                                     **
  89. ;** Examples:                                **
  90. ;**                                     **
  91. ;** pdclkset offs= -60m dst=M_EU (my IP nr and timeserver(s) from BOOTP)**
  92. ;**                                     **
  93. ;** pdclkset o=5h  d=USA  ip=123.45.6.7  ts=123.45.6.8  (BOOTP not used)**
  94. ;**                                     **
  95. ;*************************************************************************
  96. ;**                                     **
  97. ;** Acknowledgments:                            **
  98. ;**                                     **
  99. ;** The checksum routine used is a modified NCSA Telnet version.    **
  100. ;** The dst algorithm was modelled after PCIP SETCLOCK (thanks Drew!),    **
  101. ;** but enhanced to use parameters from a table.            **
  102. ;** The dst algorithm table was derived from a comp.sources.unix 1989    **
  103. ;** posting by ado@ncifcrf.gov of localtime.c and related routines    **
  104. ;** and tables, and a later update (very useful data, thanks!).        **
  105. ;** The packet driver interface routines were copied from the Clarkson    **
  106. ;** packet driver distribution, without which this project would not    **
  107. ;** have been possible (thanks Russ!).                    **
  108. ;** The small UDP/IP library was written by me, and can probably be    **
  109. ;** used in other small assembler applications.                **
  110. ;*                                      *
  111. ;* Jan Engvald, Lund University Computing Center             *
  112. ;* ____________________________________________________________________     *
  113. ;*   Address: Box 783               E-mail: Jan.Engvald@ldc.lu.se     *
  114. ;*            S-220 07 LUND    Earn/Bitnet: xjeldc@seldc52         *
  115. ;*            SWEDEN          (Span/Hepnet: Sweden::Gemini::xjeldc)     *
  116. ;*    Office: Soelvegatan 18        VAXPSI: psi%2403732202020::xjeldc     *
  117. ;* Telephone: +46 46 107458         (X.400: C=se; A=TeDe; P=Sunet; O=lu; *
  118. ;*   Telefax: +46 46 138225                 OU=ldc; S=Engvald; G=Jan)     *
  119. ;*     Telex: 33533 LUNIVER S                         *
  120. ;*                                      *
  121. ;*************************************************************************
  122.  
  123. ;************************************************************************
  124. ;*        Compile time constants                                  *
  125. ;************************************************************************
  126.  
  127. DEBUG        equ    0
  128. IDSTRING    equ    'PDCLKSET ver 1.02'
  129.  
  130. MN        equ    60            ; seconds in a minute
  131. HR        equ    60*MN            ; seconds in an hour
  132.  
  133. SUN        equ    0            ; Sunday
  134. SAT        equ    6            ; Saturday
  135. DAT        equ    0ffh            ; Specific date follows
  136.  
  137. JANLW        equ    31                ; Jan last week
  138. FEB2W        equ    31+2*7                ; Feb 2nd week
  139. MAR1W        equ    31+28+1*7            ; Mar 1st week
  140. MAR2W        equ    31+28+2*7            ; Mar 2nd week
  141. MAR3W        equ    31+28+3*7            ; Mar 2rd week
  142. MARLW        equ    31+28+31            ; Mar last week
  143. APR01        equ    31+28+31+1            ; Apr 1
  144. APR03        equ    31+28+31+3            ; Apr 3
  145. APR07        equ    31+28+31+7            ; Apr 7
  146. APR1W        equ    31+28+31+1*7            ; Apr 1st week
  147. APR12        equ    31+28+31+12            ; Apr 12
  148. APR14        equ    31+28+31+14            ; Apr 14
  149. APR2W        equ    31+28+31+2*7            ; Apr 2nd week
  150. APR18        equ    31+28+31+18            ; Apr 18
  151. APR3W        equ    31+28+31+3*7            ; Apr 3rd week
  152. APR22        equ    31+28+31+22            ; Apr 22
  153. APR23        equ    31+28+31+23            ; Apr 23
  154. APRNL        equ    31+28+31+30-7            ; Apr next last week
  155. APR26        equ    31+28+31+26            ; Apr 26
  156. APRLW        equ    31+28+31+30            ; Apr last week
  157. MAY01        equ    31+28+31+30+1            ; May 1
  158. MAY04        equ    31+28+31+30+4            ; May 4
  159. MAY1W        equ    31+28+31+30+1*7            ; May 1st week
  160. MAY2W        equ    31+28+31+30+2*7            ; May 2nd week
  161. AUG28        equ    31+28+31+30+31+30+31+28        ; Aug 28
  162. AUG4W        equ    31+28+31+30+31+30+31+4*7    ; Aug 4th week
  163. SEP01        equ    31+28+31+30+31+30+31+31+1    ; Sep 1
  164. SEP1W        equ    31+28+31+30+31+30+31+31+1*7    ; Sep 1st week
  165. SEP08        equ    31+28+31+30+31+30+31+31+8    ; Sep 8
  166. SEP12        equ    31+28+31+30+31+30+31+31+12    ; Sep 12
  167. SEP2W        equ    31+28+31+30+31+30+31+31+2*7    ; Sep 2nd week
  168. SEP16        equ    31+28+31+30+31+30+31+31+16    ; Sep 16
  169. SEP17        equ    31+28+31+30+31+30+31+31+17    ; Sep 17
  170. SEP20        equ    31+28+31+30+31+30+31+31+20    ; Sep 20
  171. SEP3W        equ    31+28+31+30+31+30+31+31+3*7    ; Sep 3rd week
  172. SEP28        equ    31+28+31+30+31+30+31+31+28    ; Sep 28
  173. SEP30        equ    31+28+31+30+31+30+31+31+30    ; Sep 30
  174. SEPLW        equ    31+28+31+30+31+30+31+31+30    ; Sep last week
  175. OCT01        equ    31+28+31+30+31+30+31+31+30+1    ; Oct 1
  176. OCT1W        equ    31+28+31+30+31+30+31+31+30+1*7    ; Oct 1st week
  177. OCT2W        equ    31+28+31+30+31+30+31+31+30+2*7    ; Oct 2nd week
  178. OCT3W        equ    31+28+31+30+31+30+31+31+30+3*7    ; Oct 3rd week
  179. OCT24        equ    31+28+31+30+31+30+31+31+30+24    ; Oct 18 - 24
  180. OCT4W        equ    31+28+31+30+31+30+31+31+30+4*7    ; Oct 4th week
  181. OCT29        equ    31+28+31+30+31+30+31+31+30+29    ; Oct 23 - 29
  182. OCTLW        equ    31+28+31+30+31+30+31+31+30+31        ; Oct last week
  183. NOV13        equ    31+28+31+30+31+30+31+31+30+31+13    ; Nov 5 - 13
  184. DEC01        equ    31+28+31+30+31+30+31+31+30+31+30+1    ; Dec 1
  185. DEC2W        equ    31+28+31+30+31+30+31+31+30+31+30+2*7    ; Dec 2nd week
  186.  
  187. AlgE        struc
  188. AlgName        db    "EUR "            ; Name of dst algorithm
  189. AlgFromTime    dw    2*HR            ; local standard time dst start
  190. AlgFromWeekDay    dw    SUN            ; weekday dst start
  191. AlgFromWeek    dw    MARLW            ; last day-of-year dst start
  192. AlgUntilTime    dw    2*HR            ; local standard time dst end
  193. AlgUntilWeekDay    dw    SUN            ; weekday dst end
  194. AlgUntilWeek    dw    SEPLW            ; last day-of-year dst end
  195. AlgAddAmount    dw    1*HR            ; dst advance amount
  196. AlgEntryLen    =    $-AlgName
  197. AlgE        ends
  198.  
  199. AlgData        struc
  200. AUSA AlgE <"USA ", 2*HR,SUN,APR1W, 1*HR,SUN,OCTLW, HR>    ; USA Canada Mexico
  201. ACub AlgE <"CUB ", 0*HR,SUN,MAY2W,-1*HR,SUN,OCT2W, HR>    ; Cuba
  202. AChl AlgE <"CHIL", 0*HR,SUN,OCT2W,-1*HR,SUN,MAR2W, HR>    ; Chile
  203. ABrz AlgE <"BRZ ", 2*HR,SAT,OCT4W, 1*HR,SAT,FEB2W, HR>    ; Brazil
  204. AGBR AlgE <"GBR ", 1*HR,SUN,MARLW, 1*HR,SUN,OCT29, HR>    ; United Kingdom
  205. AWEu AlgE <"W_EU", 1*HR,SUN,MARLW, 1*HR,SUN,SEPLW, HR>    ; West Europe
  206. AMEu AlgE <"M_EU", 2*HR,SUN,MARLW, 2*HR,SUN,SEPLW, HR>    ; Central Europe + SU
  207. AEEu AlgE <"E_EU", 3*HR,SUN,MARLW, 3*HR,SUN,SEPLW, HR>    ; East Europe
  208. ALby AlgE <"LIBY", 2*HR,DAT,APR01, 1*HR,DAT,SEP30, HR>    ; Libya
  209. AEgy AlgE <"EGY ", 2*HR,DAT,MAY01, 1*HR,DAT,OCT01, HR>    ; Egypt
  210. ATur AlgE <"TURK", 1*HR,SUN,MARLW, 0*HR,SUN,SEPLW, HR>    ; Turkey
  211. AIra AlgE <"IRAN", 2*HR,SUN,MARLW, 1*HR,SUN,SEP3W, HR>    ; Iran
  212. APRC AlgE <"PRC ", 2*HR,SUN,APR2W, 2*HR,SUN,SEP2W, HR>    ; People Rep of China
  213. AROK AlgE <"ROK ", 2*HR,SUN,MAY2W, 2*HR,SUN,OCT2W, HR>    ; Rep of Korea
  214. AAus AlgE <"AUS ", 2*HR,SUN,OCTLW, 2*HR,SUN,MAR3W, HR>    ; South Australia
  215. ATas AlgE <"TASM", 2*HR,SUN,OCT24, 2*HR,SUN,MAR3W, HR>    ; Tasmania
  216. ANSW AlgE <"NSW ", 2*HR,SUN,OCTLW, 2*HR,SUN,MAR1W, HR>    ; New South Wales
  217. ALHI AlgE <"LHI ", 2*HR,SUN,OCTLW, 2*HR,SUN,MAR1W, 30*MN> ; LHI (Australia) 
  218. ANZe AlgE <"NZE ", 2*HR,SUN,OCTLW, 2*HR,SUN,MAR1W, HR>    ; New Zealand
  219.  
  220. ; All entries below this line are indexed by year modulo 4
  221.  
  222. APa0 AlgE <"PAC ", 2*HR,SUN,APR1W, 1*HR,SUN,NOV13, HR>    ; Pacific presidential
  223. APa1 AlgE <"PAC ", 2*HR,SUN,APR1W, 1*HR,SUN,OCTLW, HR>    ; Pacific non-pres
  224. APa2 AlgE <"PAC ", 2*HR,SUN,APR1W, 1*HR,SUN,OCTLW, HR>    ; Pacific non-pres
  225. APa3 AlgE <"PAC ", 2*HR,SUN,APR1W, 1*HR,SUN,OCTLW, HR>    ; Pacific non-pres
  226.  
  227. ; All entries above this line are cyclic and will last forever
  228. ; All entries below this line are non-cyclic, they only last 4 years
  229.  
  230. AIs0 AlgE <"ISR ", 0*HR,DAT,APR26,-1*HR,DAT,SEP20, HR>    ; Israel 1992
  231. AIs1 AlgE <"ISR ", 0*HR,DAT,APR18,-1*HR,DAT,SEP12, HR>    ; Israel 1993
  232. AIs2 AlgE <"ISR ", 0*HR,DAT,APR03,-1*HR,DAT,AUG28, HR>    ; Israel 1994
  233. AIs3 AlgE <"ISR ", 0*HR,DAT,APR07,-1*HR,DAT,SEP01, HR>    ; Israel 1991
  234.  
  235. if    0    ; as years go by, replace entries above from below
  236. AIs3 AlgE <"ISR ", 0*HR,DAT,APR23,-1*HR,DAT,SEP17, HR>    ; Israel 1995
  237. AIs0 AlgE <"ISR ", 0*HR,DAT,APR14,-1*HR,DAT,SEP08, HR>    ; Israel 1996
  238. AIs1 AlgE <"ISR ", 0*HR,DAT,MAY04,-1*HR,DAT,SEP28, HR>    ; Israel 1997
  239. AIs2 AlgE <"ISR ", 0*HR,DAT,APR19,-1*HR,DAT,SEP13, HR>    ; Israel 1998
  240. AIs3 AlgE <"ISR ", 0*HR,DAT,APR11,-1*HR,DAT,SEP05, HR>    ; Israel 1999
  241. AIs0 AlgE <"ISR ", 0*HR,DAT,APR30,-1*HR,DAT,SEP24, HR>    ; Israel 2000
  242. AIs1 AlgE <"ISR ", 0*HR,DAT,APR15,-1*HR,DAT,SEP09, HR>    ; Israel 2001
  243. AIs2 AlgE <"ISR ", 0*HR,DAT,APR07,-1*HR,DAT,SEP01, HR>    ; Israel 2002
  244. AIs3 AlgE <"ISR ", 0*HR,DAT,APR27,-1*HR,DAT,SEP21, HR>    ; Israel 2003
  245. AIs0 AlgE <"ISR ", 0*HR,DAT,APR18,-1*HR,DAT,SEP12, HR>    ; Israel 2004
  246. AIs1 AlgE <"ISR ", 0*HR,DAT,MAY01,-1*HR,DAT,SEP25, HR>    ; Israel 2005
  247. AIs2 AlgE <"ISR ", 0*HR,DAT,APR23,-1*HR,DAT,SEP17, HR>    ; Israel 2006
  248. AIs3 AlgE <"ISR ", 0*HR,DAT,APR15,-1*HR,DAT,SEP09, HR>    ; Israel 2007
  249. AIs0 AlgE <"ISR ", 0*HR,DAT,APR27,-1*HR,DAT,SEP21, HR>    ; Israel 2008
  250. AIs1 AlgE <"ISR ", 0*HR,DAT,APR19,-1*HR,DAT,SEP13, HR>    ; Israel 2009
  251. endif
  252. AlgData        ends
  253.  
  254. WARNYEAR    equ    1995            ; acyclic data invalid year
  255.  
  256. ;************************************************************************
  257.  
  258.         .386        ; (to avoid masm expression overflow)
  259.         .lfcond  
  260.  
  261.         include    defs.asm
  262.  
  263. ;************************************************************************
  264. ;*        Start of segment (PSP data)                *
  265. ;************************************************************************
  266.   
  267. code_s        segment use16
  268.         assume    cs:code_s, ds:code_s, es:code_s
  269.  
  270.         org    5Ch        ; PSP reused for data
  271.  
  272.         org    80h        ; PSP command parameter area  
  273. phd_dioa    db    ?
  274.         db    ?        ; always a space
  275. phd_string    db    ?
  276.  
  277.  
  278. ;************************************************************************
  279. ;*        Start of segment (code)                    *
  280. ;************************************************************************
  281.  
  282.           org    100h
  283. start:        jmp    start1        ; jump over data area
  284.  
  285. id_label    db    IDSTRING
  286.  
  287.   
  288. ;************************************************************************
  289. ;*                                    *
  290. ;*              Data area                        *
  291. ;*                                    *
  292. ;************************************************************************
  293.  
  294. NotEnoughMsg    db    "Need to know at least IP nr, Offset and Timeserver", CR, LF, '$'
  295. NoArpReplyMsg    db    "No ARP reply from Time Server", CR, LF, '$'
  296. NoBotReplyMsg    db    "No BOOTP reply", CR, LF, '$'
  297. NoTimeServMsg    db    "No reply from time server.", CR, LF, '$'
  298. usage_msg    db    LF
  299.   db  "Copyright (C) 1991 by Jan.Engvald@ldc.lu.se, see file COPYING.", CR, LF
  300.   db  IDSTRING, " usage to set the PC clock from an UDP/IP TIME server:", CR, LF, LF
  301.   db  "pdclkset b[ootp]       or", CR, LF, LF, LF
  302.   db  "pdclkset [o[ffset]=time]      (time is [-|+]{<hours>h|<minutes>m|<seconds>[s]})", CR, LF, LF
  303.   db  "         [d[aylightsave]=PAC | USA | CUB | CHIL | BRZ | GBR |", CR, LF
  304.   db  "                         W_EU | M_EU | E_EU | LIBY | EGY | TURK | ISR |", CR, LF
  305.   db  "                         IRAN | PRC | ROK | AUS | TASM | NSW | LHI | NZE |", CR, LF
  306.   db  "                  FrTime,FrWeekDay,FrDayOfYear,ToTime,ToWday,ToDayOfYr,AddTime]", CR, LF, LF
  307.   db  "         [i[pnr]=n.n.n.n]  [t[imserver]=n.n.n.n[,n.n.n.n]]", CR, LF, LF
  308.   db  "         [m[ask]=n.n.n.n]  [g[ateway]=n.n.n.n[,n.n.n.n]]", CR, LF, LF
  309.   db  "         [a[lter]=days,time]  [p[ktintno]=decimalnr]", CR, LF, LF, LF
  310.   db  "Example: pdclkset offs= -60m  dst=M_EU  (my IP nr and timeserver(s) from BOOTP)", CR, LF
  311.   db  "         pdclkset o=5h  d=USA  ip=123.45.6.7  ts=123.45.6.8    (BOOTP not used)"
  312. crlf_msg    db    CR, LF, '$'
  313.  
  314.  
  315. MsgNotSet    db    "***************************************", CR, LF, 7
  316.          db    "*                                     *", CR, LF, 7
  317.         db    "* Could not set correct date and time *", CR, LF
  318.          db    "*                                     *", CR, LF
  319.         db    "***************************************", CR, LF, "$"
  320. MsgTerm        db    "End of ", IDSTRING, " (error="
  321. MsgTermNr    db    255, ")", CR, LF
  322. MsgTermStop    db    "$", 7, Cr, LF, 7
  323.         db    "Dst entries too old, update and reassemble PDCLKSET", CR, LF, '$'
  324.  
  325.  
  326.         even
  327. Flagword    dw    DEBUG
  328. DONT_SETTIME    equ    1
  329. HAVE_MYIPNR    equ    2
  330. HAVE_TIMEOFFSET    equ    4
  331. HAVE_TIMESERVER    equ    8
  332.  
  333. TimeServIpNr    dw    0, 0
  334.         dw    0, 0
  335.  
  336. Sday        equ    3600*24
  337.  
  338. days        macro    incval
  339.         dd    x*Sday
  340. x        =    x+incval
  341.         endm
  342.  
  343. Ytab:
  344. x        =    15*366 + 49*365        ; start at 1964
  345.         rept    16
  346.         days    366
  347.         days    365
  348.         days    365
  349.         days    365
  350.         endm                ; ends on year 2027
  351.  
  352. Motab:                        ; normal year
  353. x        =    0
  354.         days    31    jan
  355.         days    28    feb
  356.         days    31    mar
  357.         days    30    apr
  358.         days    31    may
  359.         days    30    jun
  360.         days    31    jul
  361.         days    31    aug
  362.         days    30    sep
  363.         days    31    oct
  364.         days    30    nov
  365.         days    31    dec
  366.         days    1
  367.  
  368. Mltab:                        ; leap yer 
  369. x        =    0
  370.         days    31    jan
  371.         days    29    feb
  372.         days    31    mar
  373.         days    30    apr
  374.         days    31    may
  375.         days    30    jun
  376.         days    31    jul
  377.         days    31    aug
  378.         days    30    sep
  379.         days    31    oct
  380.         days    30    nov
  381.         days    31    dec
  382.         days    1
  383.  
  384. Weekdays    db    "   Sun"
  385.         db    "   Mon"
  386.         db    "  Tues"
  387.         db    "Wednes"
  388.         db    " Thurs"
  389.         db    "   Fri"
  390.         db    " Satur"
  391.  
  392.  
  393. AlgTab        AlgData    <>
  394. AlgTabEnd    equ    $
  395.  
  396. AlgIndex    dw    0
  397.  
  398. m6hour        dw    6*3600
  399. m12hour        dw    12*3600
  400. mhour        dw    3600
  401. m60b        db    60,0
  402. m7        dw    7
  403. m6        db    6
  404. m1        dw    1
  405. mindigits    dw    2
  406.  
  407. cWday        dw    0
  408. cYear        dw    0
  409. cMonth        dw    0
  410. cDay        dw    0
  411. cHour        dw    0
  412. cMinute        dw    0
  413. cSecond        dw    0
  414. tsipnr        dw    0, 0, 0, 0
  415.  
  416. cNonLeapYear    db    0, 0
  417. cDayOfYear    dw    0
  418. cTime        dw    0, 0
  419. AlterTime    dw    0, 0, 0
  420. tzoffset    dw    0, 0
  421.  
  422. msgweek        =    $+13
  423. msgyear        =    $+23
  424. msghour        =    $+37
  425. msgset        db    'Clock set to Wednesday 1989-10-21 at 18:21:15'
  426. msgts        =    $+11
  427.         db    ' from host 1.2.3.4       ', CR, LF, '$'
  428.  
  429.         .8086    ; ensure no 386-only instructions
  430.  
  431. ;************************************************************************
  432. ;************************************************************************
  433. ;*
  434. ;*        Packet interface routines
  435. ;*
  436. ;************************************************************************
  437. ;************************************************************************
  438.  
  439.  
  440. int_pkt        macro
  441.         pushf
  442.         cli
  443.         call    their_isr
  444.         endm
  445.  
  446. their_isr    dd    ?
  447. packet_int_no    db    60h,?,?,?
  448. signature    db    'PKT DRVR',0
  449. signature_len    equ    $-signature
  450. no_signature    db    "No packet driver at that address",'$'
  451.  
  452.  
  453.  
  454. ;************************************************************************
  455. ;*        FindPktint
  456. ;************************************************************************
  457.  
  458. FindPktint    proc    near
  459.   FindLoop:
  460.         call    TestPktInt
  461.         je    FindRet
  462.         inc    packet_int_no
  463.         cmp    packet_int_no,80h
  464.         jb    FindLoop
  465.  
  466.         mov    dx,offset no_signature
  467.         mov    ah,9
  468.         int    21h
  469.         mov    ax,4c02h
  470.         int    21h
  471.   FindRet:
  472.         ret
  473. Findpktint    endp
  474.  
  475.  
  476.  
  477. ;************************************************************************
  478. ;*        TestPktInt
  479. ;************************************************************************
  480.  
  481. TestPktInt    proc    near
  482.         mov    ah,35h            ; get their packet interrupt.
  483.         mov    al,packet_int_no
  484.         int    21h
  485.         mov    their_isr.offs,bx
  486.         mov    their_isr.segm,es
  487.         lea    di,3[bx]
  488.         mov    si,offset signature
  489.         mov    cx,signature_len
  490.         repe    cmpsb
  491.         ret
  492. TestPktInt    endp
  493.  
  494.  
  495.  
  496.         include    pkterr.asm
  497.  
  498. ;************************************************************************
  499. ;*
  500. ;* Note! The code from here to the end will be changed a lot in august
  501. ;* 1991. I will separate the PDCLKSET application and the UDP/IP library,
  502. ;* rename variables and some routines, maybe moving code between normal
  503. ;* and interrupt code. Also note that PDCLKSET only sends two or three
  504. ;* packets, so currently there is no ICMP handling. In most cases it is
  505. ;* needed, though, and has to be added on. Some other things to make the
  506. ;* library RFC-compliant will also be added.
  507. ;*                            / Jan E LDC
  508. ;************************************************************************
  509.  
  510.  
  511.  
  512.  
  513. ARPSLOTS    equ    5
  514. ROUTESLOTS    equ    5
  515. MAXDEFGWYS    equ    5
  516.  
  517.  
  518. Something2Do    proc    near
  519.         test    Events,GOT_ARPREQ
  520.         jz    SomethingRet
  521.         call    SendArpReply
  522.   SomethingRet:
  523.         ret
  524. Something2Do    endp
  525.  
  526.  
  527.  
  528. ;************************************************************************
  529. ;************************************************************************
  530. ;*
  531. ;*        UDP/IP library
  532. ;*
  533. ;************************************************************************
  534. ;************************************************************************
  535.  
  536.  
  537.  
  538. Descriptor    struc
  539. fIOCB        iocb    <>
  540. fPtrPhys    dw    0
  541. fPtrIp        dw    0
  542. fPtrUdp        dw    0
  543. fDesFrameLen    dw    0
  544. fDesEvent    dw    0
  545. fDesTimOutMsg    dw    0
  546. fTickResend    dw    18
  547. fTickTimeout    dw    73
  548. Descriptor    ends
  549.  
  550. HwStruc        struc
  551. hEthDst        db    6 dup (0ffh)    ; Ether broadcast
  552. hEthSrc        db    6 dup (0)    ; my Ether addr (filled in)
  553. hProtType    dw    0008        ; 0800 = IP
  554. HwStruc        ends
  555.  
  556. SnapStruc    struc
  557. sDSAP        db    170
  558. sSSAP        db    170
  559. sContr        db    3
  560. sOrgCode    db    0,0,0
  561. sProt        db    08, 00
  562. SnapStruc    ends
  563.  
  564. IpStruc        struc
  565. iIpVerHlen    db    45h        ; ver 4, 5 32-bit header words
  566. iIpTos        db    0        ; type of service
  567. iIpLen        dw    0        ; IP packet length
  568. iIpId        dw    0100h        ; id 0001
  569. iIpFlFra    dw    0        ; no flags or fragments
  570. iIpTtl        db    0        ; time to live
  571. iIpProt        db    0        ; 17 = udp
  572. iIpXsum        dw    0        ; header checksum
  573. iIpSrc        dw    0, 0        ; Don't know my IP nmbr
  574. iIpDst        dw    0ffffh, 0ffffh    ; local net broadcast IP
  575. iIpOptions    equ    $-iIpVerHlen
  576. IpStruc        ends
  577.  
  578. UdpStruc    struc
  579. uUdpSrc        dw    4400h        ; source port 44h = 68
  580. uUdpDst        dw    4300h        ; dest port 43h = 67
  581. uUdpLen        dw    0        ; 134h
  582. uUdpXsum    dw    0        ; udp checksum
  583. uUdpData    equ    $-uUdpSrc
  584. UdpStruc    ends
  585.  
  586. BootpStruc    struc
  587. uUdpStruc    UdpStruc    <>
  588. uBotOp        db    1        ; bootp request
  589. uBotHtype    db    0        ; hardware type
  590. uBotHlen    db    0        ; hardware addr lenght
  591. uBotHops    db    0        ; hops
  592. uBotXid        dw    0, 0        ; transaction id
  593. uBotSecs    dw    0001        ; 0100h seconds since boot
  594. uBotUnused    dw    0        ; not defined
  595. uBotCliIp    dw    0, 0        ; Client IP unknown
  596. uBotYourIp    dw    0, 0        ; my IP yet unknown
  597. uBotServIp    dw    0, 0        ; Server IP
  598. uBotGwyIp    dw    0, 0        ; Gateway IP
  599. uBotCliHwAd    db    16 dup (0)    ; My Hardware address
  600. uBotSname    db    64 dup (0)    ; server name
  601. uBotFilNam    db    128 dup (0)    ; file name
  602. uBotMagNum    dw    8263h, 6353h    ; Magic number  * test *
  603. uBotVend    db    64-4 dup (0)    ; Vendor specific area
  604. BpDataLen    =    $-uBotOp
  605. BootpStruc    ends
  606.  
  607. BootpFrame    struc
  608. fDescriptor    Descriptor    <>
  609. fHwStruc    HwStruc        <>
  610. fIpStruc    IpStruc        <>
  611. fBotStruc    BootpStruc    <>
  612. BpLen        =    $-fHwStruc
  613. BootpFrame    ends
  614.  
  615. ArpFrame    struc
  616. fArpDescr    Descriptor    <>
  617. fArpHwDst    db    6 dup (0ffh)    ; Ether broadcast
  618. fArpHwSrc    db    6 dup (0)    ; my Ether addr
  619. fArpType    dw    0608h        ; 0806 = ARP
  620. fArpHtype    dw    0        ; 0001 = Ether
  621. fArpProt    dw    0008h        ; 0800 = IP
  622. fArpHlen    db    0        ; Hw addr length
  623. fArpPlen    db    4        ; IP addr length
  624. fArpOp        dw    0100h        ; 0001 = request
  625. fArpMyHwAd    db    38 dup (0)
  626. ArpLen        =    $-fArpHwDst
  627. ArpFrame    ends
  628.  
  629.  
  630.         even
  631. Events        dw    1
  632. DONT_WAIT    equ    1
  633. GOT_BOOTP    equ    2
  634. GOT_ARPREPLY    equ    4
  635. GOT_TIMEREPLY    equ    8
  636. GOT_ARPREQ    equ    16
  637.  
  638. MySegm        dw    0
  639. Hlen        dw    0
  640. MyMask        dw    2 dup (0ffffh)
  641. MyNet        dw    2 dup (0ffffh)
  642. IpHandle    dw    0
  643. ArpHandle    dw    0
  644.  
  645. ifndef        MAXDEFGWYS
  646. MAXDEFGWYS    equ    5
  647. endif
  648.  
  649. DefGwys        dw    MAXDEFGWYS*2 dup (0)
  650. DefGwyIndex    dw    0
  651.  
  652. ifndef        ROUTESLOTS
  653. ROUTESLOTS    equ    5
  654. endif
  655.  
  656. RouteTabIp2    dw    ROUTESLOTS dup (0ffffh)
  657. RouteTabIp1    dw    ROUTESLOTS dup (0ffffh)
  658. RouteTabIp4    dw    ROUTESLOTS dup (0ffffh)
  659. RouteTabIp3    dw    ROUTESLOTS dup (0ffffh)
  660. RouteTabTos    dw    ROUTESLOTS dup (0)
  661. RouteTabTr    dw    ROUTESLOTS dup (0)
  662. RoutePutSlot    dw    0
  663.  
  664. ifndef        ARPSLOTS
  665. ARPSLOTS    equ    5
  666. endif
  667.  
  668. ArpTabIp2    dw    ARPSLOTS dup (0ffffh)
  669. ArpTabIp1    dw    ARPSLOTS dup (0ffffh)
  670. ArpTabSnap    dw    ARPSLOTS dup (0)
  671. ArpTabTr    dw    ARPSLOTS dup (0)
  672. ArpTabHwAdr    db    ARPSLOTS*16 dup (0ffh)
  673. ArpPutSlot    dw    0
  674.  
  675.  
  676.  
  677. SndFrame    BootpFrame    <>
  678. ArpPkt        ArpFrame    <>
  679.  
  680.  
  681.  
  682. ;************************************************************************
  683. ;*        SendUdpPkt
  684. ;*
  685. ;*    Input:        AX = UDP data length (AX destroyed)
  686. ;*            BX = packet ptr (BX saved)
  687. ;*    Output:        Non-zero if OK; zero if timeout
  688. ;*    Destroys:    AX, CX, DX, SI, DI, BP and flags
  689. ;************************************************************************
  690.  
  691. SendUdpPkt    proc    near
  692.         add    ax,8
  693.         mov    [bx].fDesFrameLen,ax
  694.         push    ax
  695.         xchg    ah,al
  696.         mov    di,[bx].fPtrUdp
  697.         mov    [di].uUdpLen,ax
  698.         mov    [di].uUdpXsum,1
  699.         mov    di,[bx].fPtrIp
  700.         mov    [di].iIpProt,17
  701.         call    UdpChkSum
  702.         pop    ax
  703.         call    SendIpPkt
  704.         ret
  705. SendUdpPkt    endp
  706.  
  707.  
  708.  
  709. ;************************************************************************
  710. ;*        SendIpPkt
  711. ;*
  712. ;*    Input:        AX = IP data length (AX destroyed)
  713. ;*            BX = packet ptr (BX saved)
  714. ;*    Output:        Non-zero if OK; zero if timeout
  715. ;*    Destroys:    AX, CX, DX, SI, DI, BP and flags
  716. ;************************************************************************
  717.  
  718. SendIpPkt    proc    near
  719.         mov    di,[bx].fPtrIp
  720.         mov    [di].iIpTtl,64h
  721.         mov    [di].iIpXsum,1
  722.         call    IPHdrLength
  723.         add    [bx].fDesFrameLen,cx
  724.         add    ax,cx
  725.         xchg    ah,al
  726.         mov    [di].iIpLen,ax
  727.         call    IpChkSum
  728.         call    PutPhysHdr
  729.         jz    SendIpRet
  730.         call    SendAndWait
  731.   SendIpRet:
  732.         ret
  733. SendIpPkt    endp
  734.  
  735.  
  736.  
  737. ;************************************************************************
  738. ;*        PutPhysHdr
  739. ;*    Output:        Non-zero if OK; zero if timeout
  740. ;************************************************************************
  741.  
  742. PutPhysHdr    proc    near
  743.         mov    si,offset ArpPkt.fArpMyHwAd
  744.         mov    di,[bx].fPtrPhys
  745.         mov    cx,Hlen
  746.         add    di,cx
  747.         mov    es,MySegm
  748.         push    cx
  749.         rep    movsb
  750.         pop    cx
  751.         shl    cx,1
  752.         add    cx,2
  753.         add    [bx].fDesFrameLen,cx
  754.         mov    word ptr [di],0008h
  755.         call    PutPhysDest
  756.         ret
  757. PutPhysHdr    endp
  758.  
  759.  
  760.  
  761. ;************************************************************************
  762. ;*        ArpPutNew
  763. ;************************************************************************
  764.  
  765. ArpPutNew        proc    near
  766.         call    ArpFind
  767.         jz    ArpPut
  768.   ArpPutWrap:
  769.         add    ArpPutSlot,2
  770.         mov    di,ArpPutSlot
  771.         cmp    di,2*ARPSLOTS
  772.         jl    ArpPut
  773.         mov    ArpPutSlot,0
  774.         jmp    short ArpPutWrap
  775. ArpPut:
  776.         push    si
  777.         mov    ArpTabIp1[di],dx
  778.         mov    ArpTabIp2[di],ax
  779.         mov    cl,3
  780.         shl    di,cl
  781.         lea    di,ArpTabHwAdr[di]
  782.         mov    cx,Hlen
  783.         rep    movsb
  784.         pop    si
  785.         ret
  786. ArpPutNew    endp
  787.  
  788.  
  789.  
  790. ;************************************************************************
  791. ;*        ArpFind
  792. ;************************************************************************
  793.  
  794. ArpFind        proc    near
  795.         mov    es,MySegm
  796.         cld
  797.         mov    di,offset ArpTabIp2
  798.         mov    cx,ARPSLOTS
  799.   ArpFindNext:                    ; look for matching slot
  800.         repne    scasw
  801.         jz    ArpFound2nd
  802.   ArpNotFound:
  803.         jmp    short ArpFindRet    ; non zero
  804.   ArpFound2nd:
  805.         cmp    dx,2*ARPSLOTS-2[di]
  806.         jne    ArpFindNext
  807.         sub    di,offset ArpTabIp2+2
  808.         cmp    di,di            ; set zero flag
  809.   ArpFindRet:
  810.         ret
  811. ArpFind        endp
  812.  
  813.  
  814.  
  815. ;************************************************************************
  816. ;*        RouteFind
  817. ;************************************************************************
  818.  
  819. RouteFind    proc    near
  820.         mov    es,MySegm
  821.         cld
  822.         mov    di,offset RouteTabIp2
  823.         mov    cx,ROUTESLOTS
  824.   RouteFindNext:                ; look for matching slot
  825.         repne    scasw
  826.         jz    RouteFound2nd
  827.   RouteNotFound:
  828.         jmp    short RouteFindRet    ; non zero
  829.   RouteFound2nd:
  830.         cmp    dx,2*RouteSLOTS-2[di]
  831.         jne    RouteFindNext
  832.         sub    di,offset RouteTabIp2+2
  833.         cmp    di,di            ; set zero flag
  834.   RouteFindRet:
  835.         ret
  836. RouteFind        endp
  837.  
  838.  
  839.  
  840. ;************************************************************************
  841. ;*        MyNetChk
  842. ;************************************************************************
  843.  
  844. MyNetChk    proc    near
  845.         push    ax
  846.         push    dx
  847.         and    dx,MyMask
  848.         cmp    dx,MyNet
  849.         jne    MyNetRet
  850.         and    ax,MyMask+2
  851.         cmp    ax,MyNet+2
  852.   MyNetRet:
  853.         pop    dx
  854.         pop    ax
  855.         ret
  856. MyNetChk    endp
  857.  
  858.  
  859.  
  860. ;************************************************************************
  861. ;*        PutPhysDest
  862. ;*    Output:        Non-zero if OK; zero if timeout
  863. ;************************************************************************
  864.  
  865. PutPhysDest    proc    near
  866.         mov    di,[bx].fPtrIp
  867.         mov    dx,[di].iIpDst
  868.         mov    ax,[di].iIpDst+2
  869.         call    MyNetChk
  870.         jz    PutArp
  871.         call    RouteFind
  872.         jz    PutArp
  873.  
  874.         mov    di,RoutePutSlot
  875.         mov    RouteTabIp1[di],dx
  876.         mov    RouteTabIp2[di],ax
  877.         mov    si,DefGwyIndex
  878.         mov    dx,DefGwys[si]
  879.         mov    ax,DefGwys+2[si]
  880.         mov    RouteTabIp3[di],dx
  881.         mov    RouteTabIp4[di],ax
  882.         inc    di
  883.         cmp    di,ROUTESLOTS
  884.         jb    PutRouteSlot
  885.         xor    di,di
  886.   PutRouteSlot:
  887.         mov    RoutePutSlot,di
  888.   PutArp:
  889.         call    ArpFind
  890.         jnz    NeedArpReq
  891.   FoundArpEntry:
  892.         mov    cl,3
  893.         shl    di,cl
  894.         lea    si,ArpTabHwAdr[di]
  895.         mov    di,[bx].fPtrPhys
  896.         mov    cx,Hlen
  897.         mov    es,MySegm
  898.         rep    movsb
  899.         dec    cx
  900.         ret
  901.  
  902.   NeedArpReq:
  903.         push    bx
  904.         mov    di,[bx].fPtrIp
  905.         mov    ax,[di].iIpSrc
  906.         mov    word ptr ArpPkt.fArpMyHwAd+6,ax
  907.         mov    ax,[di].iIpSrc+2
  908.         mov    word ptr ArpPkt.fArpMyHwAd+8,ax
  909.         mov    ax,[di].iIpDst
  910.         mov    cx,[di].iIpDst+2
  911.         mov    dx,[bx].fDesTimOutMsg
  912.         mov    bx,offset ArpPkt
  913.         mov    word ptr [bx].fArpMyHwAd+6+4+6,ax
  914.         mov    word ptr [bx].fArpMyHwAd+6+4+6+2,cx
  915.         mov    [bx].fDesTimOutMsg,dx
  916.         mov    [bx].fTickResend,5
  917.         mov    [bx].fTickTimeout,20
  918.         mov    [bx].fPtrPhys,offset ArpPkt.fHwStruc
  919.         mov    [bx].fDesFrameLen,ArpLen
  920.         mov    [bx].fDesEvent,GOT_ARPREPLY
  921.         call    SendAndWait
  922.         pop    bx
  923.         jz    PutPhysRet
  924.         jmp    PutPhysDest
  925.   PutPhysRet:
  926.         ret
  927. PutPhysDest    endp
  928.  
  929.  
  930.  
  931. ;************************************************************************
  932. ;*        SendAndWait
  933. ;*    Output:        Non-zero if OK; zero if timeout
  934. ;************************************************************************
  935.  
  936. SendAndWait    proc    near
  937.         mov    si,[bx].fDesEvent
  938.         not    si
  939.         and    Events,si
  940.         not    si
  941.         call    SendRawPkt
  942.  
  943.         mov    ax,40h
  944.         mov    es,ax
  945.         mov    bp,es:6ch        ; get current ticks value
  946.         mov    di,[bx].fTickResend    ; first resend time
  947.         lea    ax,[bp+di]
  948.         add    bp,[bx].fTickTimeout    ; time out
  949.   WaitLoop:
  950.         test    Events,si        ; got what we want?
  951.         jnz    SendWaitRet
  952.         call    Something2Do        ; anything else to do?
  953.         cmp    ax,es:6ch        ; time to resend?
  954.         jg    ChkTimeout
  955.         shl    di,1            ; double resend time    
  956.         cmp    di,30*18
  957.         jbe    SendDouble
  958.         mov    di,30*18        ; max 30 seconds
  959.   SendDouble:
  960.         add    ax,di            ; next resend time
  961.         call    SendRawPkt
  962.   ChkTimeout:
  963.         cmp    bp,es:6ch        ; time out?
  964.         jg    WaitLoop
  965.  
  966.         mov    dx,[bx].fDesTimOutMsg
  967.         or    dx,dx
  968.         jz    SendWaitRet
  969.         mov    ah,9            ; print error msg in dx
  970.         int    21h
  971.         mov    al,04            ; error code
  972.         call    Terminate
  973.   SendWaitRet:
  974.         ret
  975. SendAndWait    endp
  976.  
  977.  
  978.  
  979. ;************************************************************************
  980. ;*        SendRawPkt
  981. ;*
  982. ;* (The saving of all registers below is not needed for the Clarkson
  983. ;* collection of packet drivers, but as far as I understand the packet
  984. ;* driver specification other drivers may need it.)
  985. ;************************************************************************
  986.  
  987. SendRawPkt    proc    near
  988.         push    dx
  989.         push    cx
  990.         push    bx
  991.         push    ax
  992.         push    si
  993.         push    di
  994.         push    bp
  995.         push    es
  996.         mov    si,[bx].fPtrPhys
  997.         mov    cx,[bx].fDesFrameLen
  998.         mov    ah,4
  999.         push    ds
  1000.         int_pkt
  1001.         pop    ds
  1002.         pop    es
  1003.         pop    bp
  1004.         pop    di
  1005.         pop    si
  1006.         pop    ax
  1007.         pop    bx
  1008.         pop    cx
  1009.         jc    BadPkt
  1010.         pop    dx
  1011.         ret
  1012.   BadPkt:
  1013.         call    print_error
  1014.         mov    al,03            ; error code
  1015.         call    Terminate
  1016. SendRawPkt    endp
  1017.  
  1018.  
  1019.  
  1020. ;************************************************************************
  1021. ;*        ChkSum
  1022. ;*    Input:        SI = start addr
  1023. ;*            CX = # of bytes
  1024. ;*    Output:        AX = 1-complement checksum
  1025. ;*            CX = partial checksum
  1026. ;*            SI = addr of next byte
  1027. ;*            Non-zero
  1028. ;*    Destroys:    Flags
  1029. ;************************************************************************
  1030.  
  1031. ChkSum        proc    near
  1032.         push    dx
  1033.         shr    cx,1            ; divide by two, round down
  1034.         pushf                ; keep odd bit in carry
  1035.         xor    dx,dx            ; clear dx and carry
  1036.   ChkLoop:
  1037.         lodsw
  1038.         adc    dx,ax            ; add to previous running sum
  1039.         loop    ChkLoop
  1040.  
  1041.         adc    dx,0            ; add the last carry in again
  1042.         popf                ; odd # of bytes?
  1043.         jnc    NotOdd
  1044.         lodsb                ; get that last byte
  1045.         xor    ah,ah            ; clear carry and the high portion
  1046.         add    dx,ax            ; add the last one in
  1047.         adc    dx,0            ; add the carry in, too
  1048.   NotOdd:
  1049.         mov    ax,dx
  1050.         mov    cx,dx
  1051.         pop    dx
  1052.         not    ax            ; take one more 1-complement
  1053.         jz    AllOnes
  1054.         ret
  1055.   AllOnes:
  1056.         not    ax
  1057.         ret
  1058. ChkSum        endp
  1059.  
  1060.  
  1061.  
  1062. ;************************************************************************
  1063. ;*        UdpChkSum (both for generate and check!)
  1064. ;************************************************************************
  1065.  
  1066. UdpChkSum    proc    near
  1067.         mov    si,[bx].fPtrIp
  1068.         mov    di,[bx].fPtrUdp
  1069.         xor    dx,dx
  1070.         mov    [si].iIpTtl,dl        ; Note: Time To Live destroyed!
  1071.         xchg    dx,[di].uUdpXsum
  1072.         or    dx,dx
  1073.         jz    NoUdpSum
  1074.         mov    cx,[di].uUdpLen        ; checksum pseudo hdr
  1075.         mov    [si].iIpXsum,cx
  1076.         xchg    ch,cl
  1077.         push    cx
  1078.         mov    cx,12
  1079.         add    si,iIpTtl
  1080.         call    ChkSum
  1081.         mov    [di].uUdpXsum,cx    ; move partial checksum
  1082.         pop    cx            ;   into udp hdr
  1083.         mov    si,[bx].fPtrUdp        ; checksum udp hdr+data
  1084.         call    ChkSum
  1085.         mov    [di].uUdpXsum,ax
  1086.         cmp    ax,dx
  1087.   NoUdpSum:
  1088.         ret
  1089. UdpChkSum    endp
  1090.  
  1091.  
  1092.  
  1093. ;************************************************************************
  1094. ;*        IpHdrLength
  1095. ;************************************************************************
  1096.  
  1097. IpHdrLength    proc    near
  1098.         mov    si,[bx].fPtrIp
  1099.         mov    cx,[si]
  1100.         and    cx,0fh
  1101.         shl    cx,1
  1102.         shl    cx,1
  1103.         ret
  1104. IpHdrLength    endp
  1105.  
  1106.  
  1107.  
  1108. ;************************************************************************
  1109. ;*        IpChkSum (both for generate and check!)
  1110. ;************************************************************************
  1111.  
  1112. IpChkSum    proc    near
  1113.         xor    dx,dx
  1114.         mov    di,[bx].fPtrIp
  1115.         xchg    dx,[di].iIpXsum
  1116.         call    IpHdrLength
  1117.         call    ChkSum
  1118.         mov    [di].iIpXsum,ax
  1119.         cmp    ax,dx
  1120.         ret
  1121. IpChkSum    endp
  1122.  
  1123.  
  1124.  
  1125. ;************************************************************************
  1126. ;*        SendArpReply
  1127. ;************************************************************************
  1128.  
  1129. SendArpReply    proc    near
  1130.         ret
  1131. SendArpReply    endp
  1132.  
  1133.  
  1134.  
  1135. ;************************************************************************
  1136. ;*        EndProtocol
  1137. ;************************************************************************
  1138.  
  1139. EndProtocol    proc    near
  1140.         mov    ah,3            ; release handle in bx
  1141.         push    ds
  1142.         int_pkt
  1143.         pop    ds
  1144.         call    print_error
  1145.         ret
  1146. EndProtocol    endp
  1147.  
  1148.  
  1149.  
  1150. ;************************************************************************
  1151. ;*        Terminate
  1152. ;************************************************************************
  1153.  
  1154. Terminate    proc    near
  1155.         pop    bx            ; remove return addr fr stack
  1156.         push    ax
  1157.         mov    bx,IpHandle
  1158.         call    EndProtocol
  1159.         mov    bx,ArpHandle
  1160.         call    EndProtocol
  1161.  
  1162.         pop    ax
  1163.         push    ax
  1164.         cmp    al,0
  1165.         jz    termnorm
  1166.         mov    dx,offset MsgNotSet
  1167.         mov    ah,9
  1168.         int    21h
  1169.   termnorm:
  1170.         pop    ax
  1171.         push    ax
  1172.         add    al,'0'
  1173.         mov    MsgTermNr,al
  1174.         mov    dx,offset MsgTerm
  1175.         mov    ah,9
  1176.         int    21h
  1177.  
  1178.         pop    ax
  1179.         mov    ah,4ch
  1180.         int    21h
  1181. Terminate    endp
  1182.  
  1183.  
  1184.  
  1185. ;************************************************************************
  1186. ;************************************************************************
  1187. ;*
  1188. ;*        Input and Output routines
  1189. ;*
  1190. ;************************************************************************
  1191. ;************************************************************************
  1192.  
  1193.  
  1194.  
  1195. ;************************************************************************
  1196. ;*        SkipPastEq
  1197. ;************************************************************************
  1198.  
  1199. SkipPastEq    proc    near
  1200.         mov    cx,30
  1201.   SkipLook4Eq:
  1202.         cmp    al,'='
  1203.         je    SkipFoundEq
  1204.         lodsb
  1205.         loop    SkipLook4Eq
  1206.   SkipFoundEq:
  1207.         call    skip_blanks
  1208.         ret
  1209. SkipPastEq    endp
  1210.  
  1211.  
  1212.  
  1213. ;************************************************************************
  1214. ;*        GetNums
  1215. ;************************************************************************
  1216.  
  1217. GetNums        proc    near
  1218.         mov    bh,','
  1219.         jmp    short GetSkipBlanks
  1220. GetNumsDot:
  1221.         mov    bh,'.'
  1222.   GetSkipBlanks:
  1223.         call    skip_blanks
  1224.   GetNextNum:
  1225.         call    GetDec
  1226.         stosw
  1227.         dec    bl
  1228.         jz    GetNumsRet
  1229.         lodsb
  1230.         cmp    al,bh
  1231.         jne    GetNumsRet
  1232.         jmp    short GetNextNum
  1233.   GetNumsRet:
  1234.         ret
  1235. GetNums        endp
  1236.  
  1237.  
  1238.  
  1239. ;************************************************************************
  1240. ;*        GetDec
  1241. ;************************************************************************
  1242.  
  1243. GetDec        proc    near
  1244.         xor    dx,dx
  1245.         lodsb
  1246.         cmp    al,'-'
  1247.         pushf
  1248.         je    GetDecSign
  1249.         cmp    al,'+'
  1250.         jne    GetNextDig
  1251.   GetDecSign:
  1252.         lodsb
  1253.   GetNextDig:
  1254.         cmp    al,'0'
  1255.         jb    GetDecEnd
  1256.         cmp    al,'9'
  1257.         ja    GetDecEnd
  1258.         sub    al,'0'
  1259.         cbw
  1260.         add    ax,dx
  1261.         mov    cx,ax
  1262.         mul    k10
  1263.         mov    dx,ax
  1264.         lodsb
  1265.         jmp    short GetNextDig
  1266.   GetDecEnd:
  1267.         mov    dx,60*60
  1268.         cmp    al,'h'
  1269.         je    GetDecScale
  1270.         mov    dx,60
  1271.         cmp    al,'m'
  1272.         je    GetDecScale
  1273.         mov    dx,1
  1274.         cmp    al,'s'
  1275.         je    GetDecScale
  1276.         dec    si
  1277.   GetDecScale:
  1278.         mov    ax,cx
  1279.         mul    dx
  1280.         popf
  1281.         jne    GetDecRet
  1282.         not    dx
  1283.         not    ax
  1284.         add    ax,1
  1285.         adc    dx,0 
  1286.  GetDecRet:
  1287.         ret
  1288. GetDec        endp
  1289.  
  1290.  
  1291.  
  1292. k10        dw    10
  1293. TmpIpNr        dw    0, 0, 0, 0
  1294.  
  1295.  
  1296.  
  1297. ;************************************************************************
  1298. ;*        GetIpNr
  1299. ;************************************************************************
  1300.  
  1301. GetIpNr        proc    near
  1302.         push    di
  1303.         mov    bl,4
  1304.         mov    di,offset TmpIpNr
  1305.         call    GetNumsDot
  1306.         jnz    GetIpNrRet
  1307.         mov    cx,4
  1308.         pop    di
  1309.         push    si
  1310.         mov    si,offset TmpIpNr
  1311.   GetIpNrLoop:
  1312.         lodsw
  1313.         stosb
  1314.         loop    GetIpNrLoop
  1315.  
  1316.         pop    si
  1317.         xor    ax,ax
  1318.   GetIpNrRet:
  1319.         ret
  1320. GetIpNr        endp
  1321.  
  1322.  
  1323.  
  1324. ;************************************************************************
  1325. ;*        PutNums
  1326. ;************************************************************************
  1327.  
  1328. PutNums    proc    near
  1329.   NextNum:
  1330.         lodsw
  1331.         call    PutDec
  1332.         dec    bl
  1333.         jz    PutNumsRet
  1334.         mov    al,bh
  1335.         stosb
  1336.         jmp    short NextNum
  1337.   PutNumsRet:
  1338.         ret
  1339. PutNums        endp
  1340.  
  1341.  
  1342.  
  1343. ;************************************************************************
  1344. ;*        PutDec
  1345. ;************************************************************************
  1346.  
  1347. PutDec        proc    near
  1348.         xor    cx,cx
  1349.   NextDec:
  1350.         xor    dx,dx
  1351.         div    k10
  1352.         add    dx,'0'
  1353.         push    dx
  1354.         inc    cx
  1355.         or    ax,ax
  1356.         jnz    NextDec
  1357.         mov    ax,'0'
  1358.   ZeroFill:
  1359.         cmp    cx,mindigits
  1360.         jae    putdigs
  1361.         push    ax
  1362.         inc    cx
  1363.         jmp    short ZeroFill
  1364.   PutDigs:
  1365.         pop    ax
  1366.         stosb
  1367.         loop    PutDigs
  1368.         ret
  1369. PutDec        endp
  1370.  
  1371.  
  1372.  
  1373.         include    skipblk.asm
  1374.         include chrout.asm
  1375.  
  1376.  
  1377.  
  1378. ;************************************************************************
  1379. ;************************************************************************
  1380. ;*                                    *
  1381. ;*        Program begins                        *
  1382. ;*                                    *
  1383. ;************************************************************************
  1384. ;************************************************************************
  1385.  
  1386.  
  1387. start1:
  1388.         mov    ax,cs
  1389.         mov    ds,ax
  1390.         mov    es,ax
  1391.         mov    MySegm,ax
  1392.         cld
  1393.  
  1394.         call    DoArgs
  1395.         call    FindPktint
  1396.         call    InitArp
  1397.         call    InitIp
  1398.  
  1399.   HAVE_ENOUGH    equ    HAVE_MYIPNR + HAVE_TIMEOFFSET + HAVE_TIMESERVER
  1400.         mov    dx,Flagword
  1401.         and    dx,HAVE_ENOUGH
  1402.         cmp    dx,HAVE_ENOUGH
  1403.         je    SkipBootp
  1404.  
  1405.         call    DoBootpPkt
  1406.         call    InterpBootp
  1407.   SkipBootp:
  1408.         mov    dx,Flagword
  1409.         and    dx,HAVE_ENOUGH
  1410.         cmp    dx,HAVE_ENOUGH
  1411.         je    DoTime
  1412.  
  1413.         mov    dx,offset NotEnoughMsg
  1414.         mov    ah,9
  1415.         int    21h
  1416.         mov    al,7            ; error code 7
  1417.         jmp    short SkipTime
  1418.   DoTime:
  1419.         or    Events,GOT_BOOTP
  1420.         call    GetTime
  1421.         call    SetTime
  1422.         mov    al,0            ; error code = 0
  1423.   SkipTime:
  1424.         call    terminate
  1425.  
  1426. ;************************************************************************
  1427. ;************************************************************************
  1428. ;*        End of program                        *
  1429. ;************************************************************************
  1430. ;************************************************************************
  1431.  
  1432.  
  1433.  
  1434. ;************************************************************************
  1435. ;*        DoArgs
  1436. ;************************************************************************
  1437.  
  1438. DoArgs        proc    near
  1439.         mov    si,offset phd_dioa
  1440.         lodsb
  1441.         xor    ah,ah
  1442.         mov    bp,ax
  1443.         add    bp,si
  1444.         call    skip_blanks
  1445.         cmp    al,CR            ;end of line?
  1446.         je    ArgError
  1447.  
  1448.   NextArg:
  1449.         call    skip_blanks
  1450.         cmp    si,bp
  1451.         jbe    ArgFound
  1452.         jmp    DoArgRet
  1453.   ArgFound:
  1454.         or    al,020h            ; conv to lower case
  1455.  
  1456.         cmp    al,'m'            ; net mask
  1457.         jne    ArgNotMask
  1458.         call    SkipPastEq
  1459.         mov    di,offset MyMask
  1460.         call    GetIpNr
  1461.         jz    NextArg
  1462.   ArgError:    jmp    usage_error
  1463.   ArgNotMask:
  1464.         cmp    al,'i'            ; my ip nr
  1465.         jne    ArgNotMyIp
  1466.         call    SkipPastEq
  1467.         mov    di,offset SndFrame.fIpStruc.iIpSrc
  1468.         call    GetIpNr
  1469.         jnz    ArgError
  1470.         or    Flagword,HAVE_MYIPNR
  1471.         jmp    short NextArg
  1472.   ArgNotMyIp:
  1473.         cmp    al,'a'            ; alter time
  1474.         jne    ArgNotAlter
  1475.         call    SkipPastEq
  1476.         mov    di,offset AlterTime
  1477.         mov    bl,2
  1478.         call    GetNums
  1479.         mov    AlterTime+4,dx
  1480.         jnz    ArgError
  1481.         or    word ptr Flagword,DONT_SETTIME
  1482.         jmp    short NextArg
  1483.   ArgNotAlter:
  1484.         cmp    al,'p'            ; Packet int number
  1485.         jne    NotPktIntNr
  1486.         call    SkipPastEq
  1487.         call    GetDec
  1488.         mov    word ptr packet_int_no,ax
  1489.         jmp    short NextArg
  1490.   NotPktIntNr:
  1491.         cmp    al,'o'            ; time offset
  1492.         jne    ArgNotOffset
  1493.         call    SkipPastEq
  1494.         call    GetDec
  1495.         xchg    ah,al
  1496.         xchg    dh,dl
  1497.         mov    tzoffset,dx
  1498.         mov    tzoffset+2,ax
  1499.         or    Flagword,HAVE_TIMEOFFSET
  1500.         jmp    NextArg
  1501.   ArgNotOffset:
  1502.         cmp    al,'t'            ; time server
  1503.         jne    ArgNotTimServ
  1504.         call    SkipPastEq
  1505.         mov    di,offset TimeServIpNr
  1506.         call    GetIpNr
  1507.         jnz    usage_error
  1508.         or    Flagword,HAVE_TIMESERVER
  1509.         lodsb
  1510.         cmp    al,','
  1511.         jne    ArgNextArg
  1512.         call    GetIpNr
  1513.         jnz    usage_error
  1514.         jmp    NextArg
  1515.   ArgNotTimServ:
  1516.         cmp    al,'g'            ; defult gateways
  1517.         jne    ArgNotGwys
  1518.         call    SkipPastEq
  1519.         mov    di,offset DefGwys
  1520.         call    GetIpNr
  1521.         jnz    usage_error
  1522.         lodsb
  1523.         cmp    al,','
  1524.         jne    ArgNextArg
  1525.         call    GetIpNr
  1526.         jne    usage_error
  1527.   ArgNextArg:
  1528.         jmp    NextArg
  1529.   ArgNotGwys:
  1530.         cmp    al,'d'            ; daylight saving algorithm
  1531.         jne    ArgNotDlsAlg
  1532.         call    SkipPastEq
  1533.         cmp    al,'9'
  1534.         jbe    ArgGetAlgPar
  1535.         lodsw
  1536.         mov    dx,ax
  1537.         lodsw
  1538.         mov    di,offset AlgTab-AlgEntryLen
  1539.         cmp    ah,CR
  1540.         jne    ArgNextDls
  1541.         mov    ah,' '
  1542.         dec    si
  1543.   ArgNextDls:
  1544.         add    di,AlgEntryLen
  1545.         cmp    di,offset AlgTabEnd
  1546.         jae    usage_error
  1547.         cmp    dx,[di]
  1548.         jne    ArgNextDls
  1549.         cmp    ax,[di+2]
  1550.         jne    ArgNextDls        
  1551.         mov    AlgIndex,di
  1552.         jmp    NextArg
  1553.   ArgGetAlgPar:
  1554.         mov    di,offset AlgTab
  1555.         mov    AlgIndex,di
  1556.         add    di,4
  1557.         mov    bl,5
  1558.         call    GetNums
  1559.         jnz    usage_error
  1560.         jmp    NextArg
  1561.   ArgNotDlsAlg:
  1562.         cmp    al,'b'            ; bootp
  1563.         je    DoArgRet
  1564.  
  1565.         cmp    al,CR+020h
  1566.         jne    usage_error
  1567.   DoArgRet:
  1568.         ret
  1569.  
  1570.   usage_error:
  1571.         mov    dx,offset usage_msg
  1572.   error:
  1573.         mov    ah,9
  1574.         int    21h
  1575.         mov    ax,4c01h
  1576.         int    21h
  1577. DoArgs        endp
  1578.  
  1579.  
  1580.  
  1581. ;************************************************************************
  1582. ;*        InitArp
  1583. ;************************************************************************
  1584.  
  1585. InitArp        proc    near
  1586.         push    ds
  1587.         mov    ax,1ffh            ; driver_info
  1588.         int_pkt
  1589.         pop    ds
  1590.         call    fatal_error
  1591.  
  1592.         mov    ah,2            ; access all packets.
  1593.         mov    al,ch            ; their class from driver_info().
  1594.         mov    byte ptr ArpPkt.fArpHtype+1,al
  1595.         mov    bx,dx            ; their type from driver_info().
  1596.         mov    dl,cl            ;their number from driver_info().
  1597.         mov    cx,2            ;type length of zero.
  1598.         mov    si,offset ArpPkt.fArpType
  1599.         push    cs            ;es:di -> our receiver.
  1600.         pop    es
  1601.         mov    di,offset ArpRecv
  1602.         push    ds
  1603.         int_pkt
  1604.         pop    ds
  1605.         call    fatal_error
  1606.         mov    ArpHandle,ax
  1607.  
  1608.         mov    ArpPkt.fPtrPhys,offset ArpPkt.fArpHwDst
  1609.  
  1610.         mov    bx,ax
  1611.         push    cs
  1612.         pop    es
  1613.         mov    di,offset ArpPkt.fArpMyHwAd
  1614.         mov    cx,15
  1615.         mov    ah,6            ; get my Hw addr
  1616.         push    ds
  1617.         int_pkt
  1618.         pop    ds
  1619.         call    fatal_error
  1620.         mov    ArpPkt.fArpHlen,cl
  1621.         mov    Hlen,cx
  1622.  
  1623.         mov    si,offset ArpPkt.fArpMyHwAd
  1624.         mov    di,offset ArpPkt.fArpHwSrc
  1625.         mov    es,MySegm
  1626.         mov    cx,Hlen
  1627.         rep    movsb
  1628.         ret
  1629. InitArp        endp
  1630.  
  1631.  
  1632.  
  1633. ;************************************************************************
  1634. ;*        InitIp
  1635. ;************************************************************************
  1636.  
  1637. InitIp        proc    near
  1638.         push    ds
  1639.  
  1640.         mov    SndFrame.fPtrPhys,offset SndFrame.fHwStruc
  1641.         mov    SndFrame.fPtrIp,offset SndFrame.fIpStruc
  1642.         mov    SndFrame.fPtrUdp,offset SndFrame.fBotStruc
  1643.  
  1644.         mov    ax,1ffh            ;driver_info
  1645.         int_pkt
  1646.         pop    ds
  1647.         call    fatal_error
  1648.  
  1649.         mov    ah,2            ;access all packets.
  1650.         mov    al,ch            ;their class from driver_info().
  1651.         mov    bx,dx            ;their type from driver_info().
  1652.         mov    dl,cl            ;their number from driver_info().
  1653.         mov    cx,2            ;type length of zero.
  1654.         mov    si,offset SndFrame.fHwStruc.hProtType
  1655.         push    cs            ;es:di -> our receiver.
  1656.         pop    es
  1657.         mov    di,offset IpRecv
  1658.         push    ds
  1659.         int_pkt
  1660.         pop    ds
  1661.         call    fatal_error
  1662.         mov    IpHandle,ax
  1663.  
  1664.         mov    si,offset ArpPkt.fArpMyHwAd
  1665.         mov    di,offset SndFrame.fHwStruc.hEthSrc
  1666.         mov    es,MySegm
  1667.         mov    cx,Hlen
  1668.         rep    movsb
  1669.         ret
  1670. InitIp        endp
  1671.  
  1672.  
  1673.  
  1674. ;************************************************************************
  1675. ;*        DoBootpPkt
  1676. ;************************************************************************
  1677.  
  1678. DoBootpPkt        proc    near
  1679.         mov    ax,40h
  1680.         mov    es,ax
  1681.         mov    ax,es:6ch
  1682.         mov    SndFrame.fBotStruc.uBotXid,ax
  1683.  
  1684.         mov    al,byte ptr ArpPkt.fArpHtype+1
  1685.         mov    SndFrame.fBotStruc.uBotHtype,al
  1686.         mov    si,offset ArpPkt.fArpMyHwAd
  1687.         mov    di,offset SndFrame.fBotStruc.uBotCliHwAd
  1688.         mov    es,MySegm
  1689.         mov    cx,Hlen
  1690.         mov    SndFrame.fBotStruc.uBotHlen,cl
  1691.         rep    movsb
  1692.  
  1693.  
  1694.         mov    bx,offset SndFrame        ; frame to send
  1695.         mov    [bx].fDesEvent,GOT_BOOTP    ; event to wait for
  1696.         mov    [bx].fDesTimOutMsg,offset NoBotReplyMsg ; error msg
  1697.         mov    ax,BpDataLen
  1698.         call    SendUdpPkt
  1699.         ret
  1700. DoBootpPkt    endp
  1701.  
  1702.  
  1703.  
  1704. ;************************************************************************
  1705. ;*        InterpBootp
  1706. ;************************************************************************
  1707.  
  1708. InterpBootp    proc    near
  1709.         mov    bx,offset IpBuf
  1710.         mov    di,[bx].fPtrUdp
  1711.         mov    ax,[di].uBotYourIp
  1712.         mov    SndFrame.fIpStruc.iIpSrc,ax
  1713.         mov    word ptr ArpPkt.fArpMyHwAd+6,ax
  1714.         mov    ax,[di].uBotYourIp+2
  1715.         mov    SndFrame.fIpStruc.iIpSrc+2,ax
  1716.         mov    word ptr ArpPkt.fArpMyHwAd+8,ax
  1717.         or    Flagword,HAVE_MYIPNR
  1718.  
  1719.         cmp    word ptr [di].uBotMagNum,8263h
  1720.         jne    VendEnd
  1721.         cmp    word ptr [di].uBotMagNum+2,6353h
  1722.         jne    VendEnd
  1723.  
  1724.         lea    si,[di].uBotVend
  1725.         lea    bx,[si]+64-4
  1726.         mov    es,MySegm
  1727.   VendLoop:
  1728.         cmp    si,bx
  1729.         jb    VendNext
  1730.  
  1731.   VendEnd:
  1732.         ret
  1733.  
  1734.   VendNext:
  1735.         lodsb
  1736.  
  1737.         cmp    al,0
  1738.         je    VendLoop
  1739.  
  1740.         cmp    al,1
  1741.         jne    NotMask
  1742.         mov    di,offset MyMask
  1743.         call    Xtract4Bytes
  1744.         jmp    short VendLoop
  1745.   NotMask:
  1746.         cmp    al,2
  1747.         jne    NotTimeOffs
  1748.         test    Flagword,HAVE_TIMEOFFSET
  1749.         jnz    VendDefault
  1750.         mov    di,offset tzoffset
  1751.         call    Xtract4Bytes
  1752.         or    Flagword,HAVE_TIMEOFFSET
  1753.         jmp    short VendLoop
  1754.   NotTimeOffs:
  1755.         cmp    al,3
  1756.         jne    NotDefGwys
  1757.         mov    di,offset DefGwys
  1758.         mov    cx,4*MAXDEFGWYS
  1759.         call    XtractNBytes
  1760.         jmp    short VendLoop
  1761.   NotDefGwys:
  1762.         cmp    al,4
  1763.         jne    NotTimeserv
  1764.         or    Flagword,HAVE_TIMESERVER
  1765.         cmp    TimeServIpNr+4,0
  1766.         jne    VendDefault
  1767.         cmp    TimeServIpNr,0
  1768.         jne    OneServer
  1769.         mov    di,offset TimeServIpNr
  1770.         call    Xtract8Bytes
  1771.         jmp    short VendLoop
  1772.   OneServer:
  1773.         mov    di,offset TimeServIpNr+4
  1774.         call    Xtract4Bytes
  1775.         jmp    short VendLoop
  1776.   NotTimeserv:
  1777.         cmp    al,0ffh
  1778.         je    VendEnd
  1779.   VendDefault:
  1780.         lodsb
  1781.         xor    ah,ah
  1782.         add    si,ax
  1783.         jmp    Vendloop
  1784.  
  1785. InterpBootp    endp
  1786.  
  1787.  
  1788.  
  1789. ;************************************************************************
  1790. ;*        Xtract4Bytes
  1791. ;************************************************************************
  1792.  
  1793. Xtract4Bytes    proc    near
  1794.         mov    cl,4
  1795.         jmp    short XtractNBytes
  1796. Xtract8Bytes:
  1797.         mov    cl,8
  1798. XtractNBytes:
  1799.         lodsb
  1800.         cmp    cl,al
  1801.         jbe    XtractOkLen
  1802.         mov    cl,al
  1803.   XtractOkLen:
  1804.         xor    ch,ch
  1805.         xor    ah,ah
  1806.         push    ax
  1807.         push    si
  1808.         rep    movsb
  1809.         pop    si
  1810.         pop    ax
  1811.         add    si,ax
  1812.         ret
  1813. Xtract4Bytes    endp
  1814.  
  1815.  
  1816.  
  1817. ;************************************************************************
  1818. ;*        GetTime
  1819. ;************************************************************************
  1820.  
  1821. GetTime        proc    near
  1822.         mov    bx,offset SndFrame
  1823.         mov    [bx].fBotStruc.uUdpDst,2500h    ; 37 = time
  1824.         mov    [bx].fBotStruc.uUdpSrc,1234
  1825.         mov    ax,TimeServIpNr
  1826.         mov    [bx].fIpStruc.iIpDst,ax
  1827.         mov    ax,TimeServIpNr+2
  1828.         mov    [bx].fIpStruc.iIpDst+2,ax
  1829.         mov    [bx].fDesEvent,GOT_TIMEREPLY
  1830.         mov    dx,offset NoTimeServMsg
  1831.         cmp    TimeServIpNr+4,0
  1832.         je    No2ndServ
  1833.         xor    dx,dx
  1834.   No2ndServ:
  1835.         mov    [bx].fDesTimOutMsg,dx
  1836.         xor    ax,ax            ; No data! (length=0)
  1837.         call    SendUdpPkt
  1838.         jnz    DoneServ
  1839.  
  1840.         mov    ax,TimeServIpNr+4
  1841.         mov    TimeServIpNr,ax
  1842.         mov    ax,TimeServIpNr+6
  1843.         mov    TimeServIpNr+2,ax
  1844.         mov    TimeServIpNr+4,0
  1845.  
  1846.         mov    ax,TimeServIpNr
  1847.         mov    [bx].fIpStruc.iIpDst,ax
  1848.         mov    ax,TimeServIpNr+2
  1849.         mov    [bx].fIpStruc.iIpDst+2,ax
  1850.         mov    [bx].fDesTimOutMsg,offset NoTimeServMsg
  1851.         xor    ax,ax
  1852.         call    SendUdpPkt
  1853.   DoneServ:
  1854.         ret
  1855. GetTime        endp
  1856.  
  1857.  
  1858.  
  1859. ;************************************************************************
  1860. ;*        SetTime
  1861. ;************************************************************************
  1862.  
  1863. SetTime        proc    near
  1864.         push    cs
  1865.         push    cs
  1866.         pop    ds
  1867.         pop    es
  1868.         cld
  1869.  
  1870.         mov    cx,4
  1871.         mov    si,offset TimeServIpNr
  1872.         mov    di,offset tsipnr
  1873.         xor    ah,ah
  1874.   TsIpLoop:
  1875.         lodsb
  1876.         stosw
  1877.         loop    TsIpLoop
  1878.  
  1879.         mov    cx,cTime
  1880.         xchg    ch,cl
  1881.         mov    bx,cTime+2
  1882.         xchg    bh,bl
  1883.  
  1884.         mov    dx,tzoffset+2
  1885.         xchg    dh,dl
  1886.         sub    bx,dx
  1887.         mov    ax,tzoffset
  1888.         xchg    ah,al
  1889.         sbb    cx,ax
  1890.  
  1891.         mov    ax,AlterTime
  1892.         imul    m6hour
  1893.         shl    ax,1
  1894.         rcl    dx,1
  1895.         shl    ax,1
  1896.         rcl    dx,1
  1897.         add    bx,ax
  1898.         adc    cx,dx
  1899.  
  1900.         mov    ax,AlterTime+2
  1901.         mov    dx,AlterTime+4
  1902.         add    bx,ax
  1903.         adc    cx,dx
  1904.  
  1905.         mov    si,AlgIndex
  1906.         or    si,si
  1907.         jnz    DoDls
  1908.         jmp    SetNoDls
  1909.   DoDls:
  1910.         push    bx
  1911.         push    cx
  1912.         add    si,4
  1913.         lodsw                ; from switching time
  1914.         imul    m1
  1915.         sub    bx,ax
  1916.         sbb    cx,dx
  1917.  
  1918.         call    DateTimeCalc
  1919.  
  1920.         cmp    si,offset AlgTab.Apa0    ; four entry part?
  1921.         jl    SingleEntry
  1922.         mov    al,AlgEntryLen
  1923.         mul    cNonLeapYear
  1924.         add    si,ax
  1925.         cmp    si,offset AlgTab.Ais0    ; acyclic entry?
  1926.         jb    SingleEntry
  1927.         cmp    cYear,WARNYEAR
  1928.         jb    SingleEntry
  1929.         mov    MsgTermStop,' '        ; activate warning msg
  1930.   SingleEntry:
  1931.         mov    bp,cDayOfYear
  1932.         lodsw                ; from switching weekday
  1933.         cmp    al,SAT
  1934.         ja    FromDate
  1935.         dec    bp
  1936.         cmp    ax,cWday
  1937.         jg    CurWeekF
  1938.         add    bp,7
  1939.   CurWeekF:
  1940.         sub    bp,cWday
  1941.         add    bp,ax
  1942.   FromDate:
  1943.         pop    cx
  1944.         pop    bx
  1945.         push    bx
  1946.         push    cx
  1947.         lodsw                ; from switching week
  1948.  
  1949.         push    ax
  1950.         lodsw                ; until switching time
  1951.         imul    m1
  1952.         sub    bx,ax
  1953.         sbb    cx,dx
  1954.  
  1955.         call    DateTimeCalc
  1956.  
  1957.         mov    di,cDayOfYear
  1958.         pop    dx
  1959.  
  1960.         lodsw                ; switching until weekday
  1961.         cmp    al,SAT
  1962.         ja    UntilDate
  1963.         dec    di
  1964.         cmp    ax,cWday
  1965.         jg    CurWeekU
  1966.         add    di,7
  1967.   CurWeekU:
  1968.         sub    di,cWday
  1969.         add    di,ax
  1970.   UntilDate:
  1971.         lodsw                ; until switching week
  1972.         test    cNonLeapYear,011b
  1973.         jnz    SetNotLeap
  1974.         cmp    ax,31+28
  1975.         jbe    SetChkLU
  1976.         inc    ax
  1977.   SetChkLU:
  1978.         cmp    dx,31+28
  1979.         jbe    SetNotLeap
  1980.         inc    dx
  1981.   SetNotLeap:
  1982.         pop    cx
  1983.         pop    bx
  1984.         cmp    ax,dx            ; north or south of equator?
  1985.         jl    SetSouth
  1986.         cmp    dx,bp
  1987.         jg    SetNoDls
  1988.         jmp    short SetChkUntil
  1989.   SetSouth:
  1990.         cmp    dx,bp
  1991.         jle    DoDLSaving
  1992.   SetChkUntil:
  1993.         cmp    di,ax
  1994.         jge    SetNoDls
  1995.   DoDLSaving:
  1996.         lodsw                ; dst advance time
  1997.         imul    m1
  1998.         add    bx,ax
  1999.         adc    cx,dx
  2000.   SetNoDls:
  2001.         call    DateTimeCalc
  2002.  
  2003.         test    Flagword,DONT_SETTIME
  2004.         jz    SetPCtime
  2005.         mov    di,offset msgset
  2006.         mov    cx,12
  2007.         mov    al,' '
  2008.         rep    stosb
  2009.         jmp    SkipTimeset
  2010.   SetPCtime:
  2011.         mov    cx,cYear
  2012.         mov    dh,byte ptr cMonth
  2013.         mov    dl,byte ptr Cday
  2014.         mov    ah,2Bh            ; set date
  2015.         int    21h
  2016.         or    al,al
  2017.         jz    DateOK
  2018.         mov    al,5
  2019.         call    terminate
  2020.   DateOK:
  2021.         mov    ch,byte ptr cHour
  2022.         mov    cl,byte ptr cMinute
  2023.         mov    dh,byte ptr cSecond
  2024.         mov    dl,99
  2025.         mov    ah,2Dh            ; set time
  2026.         int    21h
  2027.         or    al,al
  2028.         jz    TimeOK
  2029.         mov    al,6
  2030.         call    terminate
  2031.   TimeOK:
  2032.   SkipTimeset:
  2033.         mov    al,byte ptr cWday
  2034.         mul    m6
  2035.         add    ax,offset Weekdays
  2036.         mov    si,ax
  2037.         mov    di,offset msgweek
  2038.         mov    cx,3
  2039.         rep    movsw
  2040.         
  2041.         mov    si,offset cYear
  2042.         mov    di,offset msgyear
  2043.         mov    bh,'-'
  2044.         mov    bl,3
  2045.         call    PutNums
  2046.  
  2047.         mov    di,offset msghour
  2048.         mov    bh,':'
  2049.         mov    bl,3
  2050.         call    PutNums
  2051.  
  2052.         mov    mindigits,1
  2053.         mov    di,offset msgts
  2054.         mov    bh,'.'
  2055.         mov    bl,4
  2056.         call    PutNums
  2057.  
  2058.         mov    dx,offset msgset
  2059.         mov    ah,9
  2060.         int    21h            ; display string
  2061.  
  2062.         ret
  2063. SetTime        endp
  2064.  
  2065.  
  2066.  
  2067. ;************************************************************************
  2068. ;*        DateTimeCalc
  2069. ;************************************************************************
  2070.  
  2071. DateTimeCalc    proc    near
  2072.         mov    ax,bx
  2073.         mov    dx,cx
  2074.         push    si
  2075.         push    ax
  2076.         push    dx
  2077.  
  2078.         mov    si,offset Ytab
  2079.         mov    cx,4*64
  2080.         call    BinSearch
  2081.         add    bx,1964
  2082.         mov    cYear,bx
  2083.  
  2084.         push    ax
  2085.         push    dx
  2086.         shr    dx,1
  2087.         rcr    ax,1
  2088.         div    m12hour
  2089.         inc    ax
  2090.         mov    cDayOfYear,ax
  2091.         pop    dx
  2092.         pop    ax
  2093.  
  2094.         mov    si,offset Motab
  2095.         mov    cx,4*16
  2096.         and    bl,011b
  2097.         mov    cNonLeapYear,bl
  2098.         jnz    NoLeapYear
  2099.         mov    si,offset Mltab
  2100.   NoLeapYear:
  2101.         call    BinSearch
  2102.         inc    bx
  2103.         mov    cMonth,bx
  2104.  
  2105.         shr    dx,1
  2106.         rcr    ax,1
  2107.         rcr    bx,1
  2108.         div    m12hour
  2109.         inc    ax
  2110.         mov    cDay,ax
  2111.  
  2112.         mov    ax,dx
  2113.         xor    dx,dx
  2114.         shl    bx,1
  2115.         rcl    ax,1
  2116.         rcl    dx,1
  2117.         div    mhour
  2118.         mov    cHour,ax
  2119.  
  2120.         mov    ax,dx
  2121.         div    m60b
  2122.         mov    dl,ah
  2123.         xor    dh,dh
  2124.         mov    cSecond,dx
  2125.         xor    ah,ah
  2126.         mov    cMinute,ax
  2127.  
  2128.         pop    dx
  2129.         pop    ax
  2130.         shr    dx,1
  2131.         rcr    ax,1
  2132.         div    m12hour
  2133.         add    ax,1
  2134.         xor    dx,dx
  2135.         div    m7
  2136.         mov    cWday,dx
  2137.         pop    si
  2138.         ret
  2139. DateTimeCalc    endp
  2140.  
  2141.  
  2142.  
  2143. ;************************************************************************
  2144. ;*        BinSearch
  2145. ;************************************************************************
  2146.  
  2147. BinSearch    proc    near
  2148.         xor    bx,bx
  2149.   BinLoop:
  2150.         shr    cx,1
  2151.         cmp    cx,2
  2152.         je    BinDone
  2153.         add    bx,cx
  2154.         cmp    dx,2[si+bx]
  2155.   BinEval:
  2156.         ja    BinLoop
  2157.         je    BinEqual
  2158.         sub    bx,cx
  2159.         jmp    BinLoop
  2160.   BinEqual:
  2161.         cmp    ax,[si+bx]
  2162.         ja    BinLoop
  2163.         je    BinDone
  2164.         sub    bx,cx
  2165.         jmp    BinLoop
  2166.   BinDone:
  2167.         sub    ax,[si+bx]
  2168.         sbb    dx,2[si+bx]
  2169.         shr    bx,1
  2170.         shr    bx,1
  2171.         ret
  2172. BinSearch    endp
  2173.  
  2174.  
  2175.  
  2176. ;************************************************************************
  2177. ;*        IP receiver                        *
  2178. ;************************************************************************
  2179.  
  2180. IpRecv:
  2181.         pushf
  2182.         or    ax,ax        ; first or second call?
  2183.         jne    IpRecv_1    ; second
  2184.         push    cs
  2185.         pop    es
  2186.         mov    di,offset IpBuf.fHwStruc
  2187.         test    cs:Events,GOT_BOOTP
  2188.         jz    IpRecRet0
  2189.         mov    di,offset IpBuf2.fHwStruc
  2190.         test    cs:Events,GOT_TIMEREPLY
  2191.         jz    IpRecRet0
  2192.         xor    di,di
  2193.         mov    es,di
  2194. IpRecRet0:
  2195.         popf
  2196.         retf
  2197.  
  2198. IpRecv_1:
  2199.         push    cs
  2200.         pop    ds
  2201.         cli
  2202.         mov    word ptr StackBeg,sp
  2203.         mov    word ptr StackBeg+2,ss
  2204.         mov    sp,offset StackEnd
  2205.         mov    ss,MySegm
  2206.         sti
  2207.  
  2208.         mov    bx,si
  2209.         mov    bp,si
  2210.         add    bp,cx
  2211.         sub    bx,fHwStruc
  2212.         mov    [bx].fDesFrameLen,cx
  2213.         mov    [bx].fPtrPhys,si
  2214.         add    si,Hlen
  2215.         add    si,Hlen
  2216.         mov    ax,[si]
  2217.         xchg    ah,al
  2218.         cmp    ax,GIANT
  2219.         ja    RecvNotSnap
  2220.         add    si,8
  2221.   RecvNotSnap:
  2222.         lea    di,[si+2]
  2223.         mov    [bx].fPtrIp,di
  2224.  
  2225.         call    IpChkSum
  2226.         jne    IpRecRet
  2227.         cmp    si,bp
  2228.         ja    IpRecRet
  2229.         mov    [bx].fPtrUdp,si
  2230.  
  2231.         cmp    [di].iIpProt,17            ; UDP
  2232.         jne    IpRecRet
  2233.          mov    di,si
  2234.  
  2235.         call    UdpChkSum
  2236.         jne    IpRecRet
  2237.         cmp    si,bp
  2238.         jbe    IpRecUdp
  2239. IpRecRet:
  2240.         cli
  2241.         mov    sp, word ptr StackBeg
  2242.         mov    ss, word ptr StackBeg+2
  2243.         popf
  2244.         retf
  2245.  
  2246. IpRecUdp:
  2247.         test    Events,GOT_BOOTP
  2248.         jnz    RecvTime
  2249.  
  2250. ;        cmp    [bx].fDesFrameLen,BpLen
  2251. ;        jl    IpRecRet
  2252. if DEBUG
  2253. ;        cmp    byte ptr [bx].fHwStruc.hEthSrc+4,05ah    ; Nomina
  2254.         cmp    byte ptr [bx].fHwStruc.hEthSrc+4,059h    ; Pollux
  2255.         jne    IpRecRet
  2256. endif ; DEBUG
  2257.         cmp    word ptr [di].uUdpSrc,4300h    ; Src port 0043 = 67
  2258.         jne    IpRecRet
  2259.         cmp    word ptr [di].uUdpDst,4400h
  2260.         jne    IpRecRet
  2261.         cmp    byte ptr [di].uBotOp,2        ; reply
  2262.         jne    IpRecRet
  2263.  
  2264.         push    di
  2265.         lea    si,[di].uBotCliHwAd
  2266.         mov    di,offset ArpPkt.fArpMyHwAd
  2267.         mov    cx,Hlen
  2268.         repe    cmpsb
  2269.         pop    di
  2270.         jne    IpRecRet    
  2271.  
  2272.         mov    ax,word ptr SndFrame.fBotStruc.uBotXid    
  2273.         cmp    ax,word ptr [di].uBotXid
  2274.         jne    IpRecRet
  2275.         mov    ax,word ptr SndFrame.fBotStruc.uBotXid+2
  2276.         cmp    ax,word ptr [di].uBotXid+2
  2277.         jne    IpRecRet
  2278.  
  2279.         mov    dx,[di].uBotGwyIp
  2280.         mov    ax,[di].uBotGwyIp+2
  2281.         mov    si,[bx].fPtrPhys
  2282.         add    si,Hlen
  2283.         call    ArpPutNew
  2284.  
  2285.         or    Events,GOT_BOOTP
  2286.         jmp    IpRecRet
  2287.  
  2288. RecvTime:
  2289.         cmp    word ptr [di].uUdpSrc,2500h    ; Src port 0025 = 37
  2290.         jne    IpRecRet
  2291.  
  2292.         mov    ax,[di].uUdpData
  2293.         mov    cTime,ax
  2294.         mov    ax,[di].uUdpData+2
  2295.         mov    cTime+2,ax
  2296.  
  2297.         or    Events,GOT_TIMEREPLY
  2298.  
  2299.         jmp    IpRecRet
  2300.  
  2301.  
  2302. ;************************************************************************
  2303. ;*        ARP receiver                        *
  2304. ;************************************************************************
  2305.  
  2306. ArpRecv:
  2307.         pushf
  2308.         or    ax,ax            ; first or second call?
  2309.         jne    ArpRecv_1        ; second
  2310.         push    cs
  2311.         pop    es
  2312.         mov    di,offset ArpBuf.fHwStruc
  2313.         test    cs:Events,GOT_ARPREPLY
  2314.         jz    ArpRecRet0
  2315.         mov    di,offset ArpBuf2.fHwStruc
  2316. ArpRecRet0:
  2317.         popf
  2318.         retf
  2319.  
  2320. ArpRecv_1:
  2321.         cmp    cx,ArpLen
  2322.         jl    ArpRecRet
  2323.         push    cs
  2324.         pop    ds
  2325.         mov    bx,offset ArpBuf
  2326.         mov    dx,word ptr [bx].fArpMyHwAd+6
  2327.         mov    ax,word ptr [bx].fArpMyHwAd+6+2
  2328.         call    ArpFind
  2329.         lea    si,[bx].fArpMyHwAd
  2330.         jnz    ArpNotThere
  2331.         call    ArpPut
  2332.   ArpNotThere:
  2333.         cmp    dx,word ptr ArpPkt.fArpMyHwAd+6+4+6
  2334.         jne    ArpRecRet
  2335.         cmp    ax,word ptr ArpPkt.fArpMyHwAd+6+4+6+2
  2336.         jne    ArpRecRet
  2337.  
  2338.         call    ArpPutNew
  2339.  
  2340.         or    Events,GOT_ARPREPLY
  2341. ArpRecRet:
  2342.         popf
  2343.         retf
  2344.  
  2345.  
  2346.  
  2347. ;************************************************************************
  2348. ;*        Receive buffers                        *
  2349. ;************************************************************************
  2350.  
  2351. ArpBuf        equ    $
  2352. ArpBuf2        equ    ArpBuf+GIANT
  2353. IpBuf        equ    ArpBuf2+GIANT
  2354. IpBuf2        equ    IpBuf+GIANT
  2355. StackBeg    equ    IpBuf2+GIANT
  2356. StackEnd    equ    StackBeg+1000
  2357.  
  2358. code_s        ends
  2359.               end    start
  2360.