home *** CD-ROM | disk | FTP | other *** search
-
- PAGE 44,132
-
- ;*************************************************************************
- ;** **
- ;** PDCLKSET **
- ;** **
- ;** **
- ;** Copyright (C) 1991 Jan.Engvald @ LDC.lu.se **
- ;** **
- ;** This program is free software; you can redistribute it and/or modify**
- ;** it under the terms of the GNU General Public License as published by**
- ;** the Free Software Foundation, version 1. **
- ;** **
- ;** This program is distributed in the hope that it will be useful, **
- ;** but WITHOUT ANY WARRANTY; without even the implied warranty of **
- ;** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the **
- ;** GNU General Public License for more details. **
- ;** **
- ;** You should have received a copy of the GNU General Public License **
- ;** along with this program; if not, write to the Free Software **
- ;** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. **
- ;** **
- ;*************************************************************************
- ;** **
- ;** PDCLKSET sets the time and date of the PC clock using a TIME server.**
- ;** To do so, the following information is required: **
- ;** **
- ;** - This clients unique IP number. **
- ;** - The IP number of a UDP/IP time server. **
- ;** - The time offset from UTC (GMT) at this place. **
- ;** - If daylight saving (summer) time is used, which algorithm to use. **
- ;** **
- ;** All the above info can be supplied as arguments to PDCLKSET. If any **
- ;** of the first three are missing, it will send a BOOTP request to try **
- ;** to find the missing info. Except for client IP number, arguments to **
- ;** PDCLKSET overrides BOOTP info. **
- ;** **
- ;** BOOTP can not supply which dst algorithm to use; also, time offset **
- ;** can't always be trusted. So, in practice, time offset and dst algo- **
- ;** rithm (if applicable) are required arguments. **
- ;** **
- ;** If PDCLKSET finds more than one time server (sum of arguments and **
- ;** BOOTP fields) and the first one does not answer, it will try the **
- ;** second server. **
- ;** **
- ;** It is very hard to get accurate info on all the dst algorithms used **
- ;** all over the world, so the one you choose, you should test out. Use **
- ;** the alter argument to add or subtract time and days, and check that **
- ;** the dst switch occurs correctly. When using the alter argument, the **
- ;** date and time is displayed as usual, but the PC clock is not set. **
- ;** If you find any errors, mail me the correct info to my mail address **
- ;** below. If you want to, you can customize your own dst algorithm, see**
- ;** detailed info below. **
- ;** **
- ;** PDCLKSET talks to the network card via a packet driver. If you have **
- ;** more than one packet driver, it will use the first one (lowest **
- ;** packet interrupt number) unless you use the pktintno argument. **
- ;** In AUTOEXEC.BAT you should first load the packet driver, then call **
- ;** PDCLKSET. It is very small (6 kbyte) and executes fast, so you will **
- ;** not notice any delay. PDCLKSET is not a TSR and does not require any**
- ;** CONFIG.SYS files, so no memory is wasted. Use TERMIN.COM if you want**
- ;** to unload the packet driver. **
- ;** Note: If you always log into a Novell server after a boot, you **
- ;** don't need this program, the PC clock will be set from the server. **
- ;** **
- ;** Call syntax: **
- ;** **
- ;** (time is [- | +]{<hours>h | <minutes>m | <seconds>[s]}) **
- ;** **
- ;** pdclkset b[ootp] or **
- ;** **
- ;** pdclkset [o[ffset]=time] **
- ;** **
- ;** [d[aylightsave]=PAC | USA | CUB | CHIL | BRZ | GBR | **
- ;** W_EU | M_EU | E_EU | LIBY | EGY | TURK | **
- ;** ISR | IRAN | PRC | ROK | AUS | TASM | **
- ;** NSW | LHI | NZE | **
- ;** FrTime,FrWeekDay,FrDayOfYear, **
- ;** ToTime,ToWday,ToDayOfYr,AddTime] **
- ;** **
- ;** [i[pnr]=n.n.n.n] [t[imserver]=n.n.n.n[,n.n.n.n]] **
- ;** **
- ;** [m[ask]=n.n.n.n] [g[ateway]=n.n.n.n[,n.n.n.n]] **
- ;** **
- ;** [a[lter]=days,time] [p[ktintno]=decimalnr] **
- ;** **
- ;** **
- ;** Examples: **
- ;** **
- ;** pdclkset offs= -60m dst=M_EU (my IP nr and timeserver(s) from BOOTP)**
- ;** **
- ;** pdclkset o=5h d=USA ip=123.45.6.7 ts=123.45.6.8 (BOOTP not used)**
- ;** **
- ;*************************************************************************
- ;** **
- ;** Acknowledgments: **
- ;** **
- ;** The checksum routine used is a modified NCSA Telnet version. **
- ;** The dst algorithm was modelled after PCIP SETCLOCK (thanks Drew!), **
- ;** but enhanced to use parameters from a table. **
- ;** The dst algorithm table was derived from a comp.sources.unix 1989 **
- ;** posting by ado@ncifcrf.gov of localtime.c and related routines **
- ;** and tables, and a later update (very useful data, thanks!). **
- ;** The packet driver interface routines were copied from the Clarkson **
- ;** packet driver distribution, without which this project would not **
- ;** have been possible (thanks Russ!). **
- ;** The small UDP/IP library was written by me, and can probably be **
- ;** used in other small assembler applications. **
- ;* *
- ;* Jan Engvald, Lund University Computing Center *
- ;* ____________________________________________________________________ *
- ;* Address: Box 783 E-mail: Jan.Engvald@ldc.lu.se *
- ;* S-220 07 LUND Earn/Bitnet: xjeldc@seldc52 *
- ;* SWEDEN (Span/Hepnet: Sweden::Gemini::xjeldc) *
- ;* Office: Soelvegatan 18 VAXPSI: psi%2403732202020::xjeldc *
- ;* Telephone: +46 46 107458 (X.400: C=se; A=TeDe; P=Sunet; O=lu; *
- ;* Telefax: +46 46 138225 OU=ldc; S=Engvald; G=Jan) *
- ;* Telex: 33533 LUNIVER S *
- ;* *
- ;*************************************************************************
-
- ;************************************************************************
- ;* Compile time constants *
- ;************************************************************************
-
- DEBUG equ 0
- IDSTRING equ 'PDCLKSET ver 1.02'
-
- MN equ 60 ; seconds in a minute
- HR equ 60*MN ; seconds in an hour
-
- SUN equ 0 ; Sunday
- SAT equ 6 ; Saturday
- DAT equ 0ffh ; Specific date follows
-
- JANLW equ 31 ; Jan last week
- FEB2W equ 31+2*7 ; Feb 2nd week
- MAR1W equ 31+28+1*7 ; Mar 1st week
- MAR2W equ 31+28+2*7 ; Mar 2nd week
- MAR3W equ 31+28+3*7 ; Mar 2rd week
- MARLW equ 31+28+31 ; Mar last week
- APR01 equ 31+28+31+1 ; Apr 1
- APR03 equ 31+28+31+3 ; Apr 3
- APR07 equ 31+28+31+7 ; Apr 7
- APR1W equ 31+28+31+1*7 ; Apr 1st week
- APR12 equ 31+28+31+12 ; Apr 12
- APR14 equ 31+28+31+14 ; Apr 14
- APR2W equ 31+28+31+2*7 ; Apr 2nd week
- APR18 equ 31+28+31+18 ; Apr 18
- APR3W equ 31+28+31+3*7 ; Apr 3rd week
- APR22 equ 31+28+31+22 ; Apr 22
- APR23 equ 31+28+31+23 ; Apr 23
- APRNL equ 31+28+31+30-7 ; Apr next last week
- APR26 equ 31+28+31+26 ; Apr 26
- APRLW equ 31+28+31+30 ; Apr last week
- MAY01 equ 31+28+31+30+1 ; May 1
- MAY04 equ 31+28+31+30+4 ; May 4
- MAY1W equ 31+28+31+30+1*7 ; May 1st week
- MAY2W equ 31+28+31+30+2*7 ; May 2nd week
- AUG28 equ 31+28+31+30+31+30+31+28 ; Aug 28
- AUG4W equ 31+28+31+30+31+30+31+4*7 ; Aug 4th week
- SEP01 equ 31+28+31+30+31+30+31+31+1 ; Sep 1
- SEP1W equ 31+28+31+30+31+30+31+31+1*7 ; Sep 1st week
- SEP08 equ 31+28+31+30+31+30+31+31+8 ; Sep 8
- SEP12 equ 31+28+31+30+31+30+31+31+12 ; Sep 12
- SEP2W equ 31+28+31+30+31+30+31+31+2*7 ; Sep 2nd week
- SEP16 equ 31+28+31+30+31+30+31+31+16 ; Sep 16
- SEP17 equ 31+28+31+30+31+30+31+31+17 ; Sep 17
- SEP20 equ 31+28+31+30+31+30+31+31+20 ; Sep 20
- SEP3W equ 31+28+31+30+31+30+31+31+3*7 ; Sep 3rd week
- SEP28 equ 31+28+31+30+31+30+31+31+28 ; Sep 28
- SEP30 equ 31+28+31+30+31+30+31+31+30 ; Sep 30
- SEPLW equ 31+28+31+30+31+30+31+31+30 ; Sep last week
- OCT01 equ 31+28+31+30+31+30+31+31+30+1 ; Oct 1
- OCT1W equ 31+28+31+30+31+30+31+31+30+1*7 ; Oct 1st week
- OCT2W equ 31+28+31+30+31+30+31+31+30+2*7 ; Oct 2nd week
- OCT3W equ 31+28+31+30+31+30+31+31+30+3*7 ; Oct 3rd week
- OCT24 equ 31+28+31+30+31+30+31+31+30+24 ; Oct 18 - 24
- OCT4W equ 31+28+31+30+31+30+31+31+30+4*7 ; Oct 4th week
- OCT29 equ 31+28+31+30+31+30+31+31+30+29 ; Oct 23 - 29
- OCTLW equ 31+28+31+30+31+30+31+31+30+31 ; Oct last week
- NOV13 equ 31+28+31+30+31+30+31+31+30+31+13 ; Nov 5 - 13
- DEC01 equ 31+28+31+30+31+30+31+31+30+31+30+1 ; Dec 1
- DEC2W equ 31+28+31+30+31+30+31+31+30+31+30+2*7 ; Dec 2nd week
-
- AlgE struc
- AlgName db "EUR " ; Name of dst algorithm
- AlgFromTime dw 2*HR ; local standard time dst start
- AlgFromWeekDay dw SUN ; weekday dst start
- AlgFromWeek dw MARLW ; last day-of-year dst start
- AlgUntilTime dw 2*HR ; local standard time dst end
- AlgUntilWeekDay dw SUN ; weekday dst end
- AlgUntilWeek dw SEPLW ; last day-of-year dst end
- AlgAddAmount dw 1*HR ; dst advance amount
- AlgEntryLen = $-AlgName
- AlgE ends
-
- AlgData struc
- AUSA AlgE <"USA ", 2*HR,SUN,APR1W, 1*HR,SUN,OCTLW, HR> ; USA Canada Mexico
- ACub AlgE <"CUB ", 0*HR,SUN,MAY2W,-1*HR,SUN,OCT2W, HR> ; Cuba
- AChl AlgE <"CHIL", 0*HR,SUN,OCT2W,-1*HR,SUN,MAR2W, HR> ; Chile
- ABrz AlgE <"BRZ ", 2*HR,SAT,OCT4W, 1*HR,SAT,FEB2W, HR> ; Brazil
- AGBR AlgE <"GBR ", 1*HR,SUN,MARLW, 1*HR,SUN,OCT29, HR> ; United Kingdom
- AWEu AlgE <"W_EU", 1*HR,SUN,MARLW, 1*HR,SUN,SEPLW, HR> ; West Europe
- AMEu AlgE <"M_EU", 2*HR,SUN,MARLW, 2*HR,SUN,SEPLW, HR> ; Central Europe + SU
- AEEu AlgE <"E_EU", 3*HR,SUN,MARLW, 3*HR,SUN,SEPLW, HR> ; East Europe
- ALby AlgE <"LIBY", 2*HR,DAT,APR01, 1*HR,DAT,SEP30, HR> ; Libya
- AEgy AlgE <"EGY ", 2*HR,DAT,MAY01, 1*HR,DAT,OCT01, HR> ; Egypt
- ATur AlgE <"TURK", 1*HR,SUN,MARLW, 0*HR,SUN,SEPLW, HR> ; Turkey
- AIra AlgE <"IRAN", 2*HR,SUN,MARLW, 1*HR,SUN,SEP3W, HR> ; Iran
- APRC AlgE <"PRC ", 2*HR,SUN,APR2W, 2*HR,SUN,SEP2W, HR> ; People Rep of China
- AROK AlgE <"ROK ", 2*HR,SUN,MAY2W, 2*HR,SUN,OCT2W, HR> ; Rep of Korea
- AAus AlgE <"AUS ", 2*HR,SUN,OCTLW, 2*HR,SUN,MAR3W, HR> ; South Australia
- ATas AlgE <"TASM", 2*HR,SUN,OCT24, 2*HR,SUN,MAR3W, HR> ; Tasmania
- ANSW AlgE <"NSW ", 2*HR,SUN,OCTLW, 2*HR,SUN,MAR1W, HR> ; New South Wales
- ALHI AlgE <"LHI ", 2*HR,SUN,OCTLW, 2*HR,SUN,MAR1W, 30*MN> ; LHI (Australia)
- ANZe AlgE <"NZE ", 2*HR,SUN,OCTLW, 2*HR,SUN,MAR1W, HR> ; New Zealand
-
- ; All entries below this line are indexed by year modulo 4
-
- APa0 AlgE <"PAC ", 2*HR,SUN,APR1W, 1*HR,SUN,NOV13, HR> ; Pacific presidential
- APa1 AlgE <"PAC ", 2*HR,SUN,APR1W, 1*HR,SUN,OCTLW, HR> ; Pacific non-pres
- APa2 AlgE <"PAC ", 2*HR,SUN,APR1W, 1*HR,SUN,OCTLW, HR> ; Pacific non-pres
- APa3 AlgE <"PAC ", 2*HR,SUN,APR1W, 1*HR,SUN,OCTLW, HR> ; Pacific non-pres
-
- ; All entries above this line are cyclic and will last forever
- ; All entries below this line are non-cyclic, they only last 4 years
-
- AIs0 AlgE <"ISR ", 0*HR,DAT,APR26,-1*HR,DAT,SEP20, HR> ; Israel 1992
- AIs1 AlgE <"ISR ", 0*HR,DAT,APR18,-1*HR,DAT,SEP12, HR> ; Israel 1993
- AIs2 AlgE <"ISR ", 0*HR,DAT,APR03,-1*HR,DAT,AUG28, HR> ; Israel 1994
- AIs3 AlgE <"ISR ", 0*HR,DAT,APR07,-1*HR,DAT,SEP01, HR> ; Israel 1991
-
- if 0 ; as years go by, replace entries above from below
- AIs3 AlgE <"ISR ", 0*HR,DAT,APR23,-1*HR,DAT,SEP17, HR> ; Israel 1995
- AIs0 AlgE <"ISR ", 0*HR,DAT,APR14,-1*HR,DAT,SEP08, HR> ; Israel 1996
- AIs1 AlgE <"ISR ", 0*HR,DAT,MAY04,-1*HR,DAT,SEP28, HR> ; Israel 1997
- AIs2 AlgE <"ISR ", 0*HR,DAT,APR19,-1*HR,DAT,SEP13, HR> ; Israel 1998
- AIs3 AlgE <"ISR ", 0*HR,DAT,APR11,-1*HR,DAT,SEP05, HR> ; Israel 1999
- AIs0 AlgE <"ISR ", 0*HR,DAT,APR30,-1*HR,DAT,SEP24, HR> ; Israel 2000
- AIs1 AlgE <"ISR ", 0*HR,DAT,APR15,-1*HR,DAT,SEP09, HR> ; Israel 2001
- AIs2 AlgE <"ISR ", 0*HR,DAT,APR07,-1*HR,DAT,SEP01, HR> ; Israel 2002
- AIs3 AlgE <"ISR ", 0*HR,DAT,APR27,-1*HR,DAT,SEP21, HR> ; Israel 2003
- AIs0 AlgE <"ISR ", 0*HR,DAT,APR18,-1*HR,DAT,SEP12, HR> ; Israel 2004
- AIs1 AlgE <"ISR ", 0*HR,DAT,MAY01,-1*HR,DAT,SEP25, HR> ; Israel 2005
- AIs2 AlgE <"ISR ", 0*HR,DAT,APR23,-1*HR,DAT,SEP17, HR> ; Israel 2006
- AIs3 AlgE <"ISR ", 0*HR,DAT,APR15,-1*HR,DAT,SEP09, HR> ; Israel 2007
- AIs0 AlgE <"ISR ", 0*HR,DAT,APR27,-1*HR,DAT,SEP21, HR> ; Israel 2008
- AIs1 AlgE <"ISR ", 0*HR,DAT,APR19,-1*HR,DAT,SEP13, HR> ; Israel 2009
- endif
- AlgData ends
-
- WARNYEAR equ 1995 ; acyclic data invalid year
-
- ;************************************************************************
-
- .386 ; (to avoid masm expression overflow)
- .lfcond
-
- include defs.asm
-
- ;************************************************************************
- ;* Start of segment (PSP data) *
- ;************************************************************************
-
- code_s segment use16
- assume cs:code_s, ds:code_s, es:code_s
-
- org 5Ch ; PSP reused for data
-
- org 80h ; PSP command parameter area
- phd_dioa db ?
- db ? ; always a space
- phd_string db ?
-
-
- ;************************************************************************
- ;* Start of segment (code) *
- ;************************************************************************
-
- org 100h
- start: jmp start1 ; jump over data area
-
- id_label db IDSTRING
-
-
- ;************************************************************************
- ;* *
- ;* Data area *
- ;* *
- ;************************************************************************
-
- NotEnoughMsg db "Need to know at least IP nr, Offset and Timeserver", CR, LF, '$'
- NoArpReplyMsg db "No ARP reply from Time Server", CR, LF, '$'
- NoBotReplyMsg db "No BOOTP reply", CR, LF, '$'
- NoTimeServMsg db "No reply from time server.", CR, LF, '$'
- usage_msg db LF
- db "Copyright (C) 1991 by Jan.Engvald@ldc.lu.se, see file COPYING.", CR, LF
- db IDSTRING, " usage to set the PC clock from an UDP/IP TIME server:", CR, LF, LF
- db "pdclkset b[ootp] or", CR, LF, LF, LF
- db "pdclkset [o[ffset]=time] (time is [-|+]{<hours>h|<minutes>m|<seconds>[s]})", CR, LF, LF
- db " [d[aylightsave]=PAC | USA | CUB | CHIL | BRZ | GBR |", CR, LF
- db " W_EU | M_EU | E_EU | LIBY | EGY | TURK | ISR |", CR, LF
- db " IRAN | PRC | ROK | AUS | TASM | NSW | LHI | NZE |", CR, LF
- db " FrTime,FrWeekDay,FrDayOfYear,ToTime,ToWday,ToDayOfYr,AddTime]", CR, LF, LF
- db " [i[pnr]=n.n.n.n] [t[imserver]=n.n.n.n[,n.n.n.n]]", CR, LF, LF
- db " [m[ask]=n.n.n.n] [g[ateway]=n.n.n.n[,n.n.n.n]]", CR, LF, LF
- db " [a[lter]=days,time] [p[ktintno]=decimalnr]", CR, LF, LF, LF
- db "Example: pdclkset offs= -60m dst=M_EU (my IP nr and timeserver(s) from BOOTP)", CR, LF
- db " pdclkset o=5h d=USA ip=123.45.6.7 ts=123.45.6.8 (BOOTP not used)"
- crlf_msg db CR, LF, '$'
-
-
- MsgNotSet db "***************************************", CR, LF, 7
- db "* *", CR, LF, 7
- db "* Could not set correct date and time *", CR, LF
- db "* *", CR, LF
- db "***************************************", CR, LF, "$"
- MsgTerm db "End of ", IDSTRING, " (error="
- MsgTermNr db 255, ")", CR, LF
- MsgTermStop db "$", 7, Cr, LF, 7
- db "Dst entries too old, update and reassemble PDCLKSET", CR, LF, '$'
-
-
- even
- Flagword dw DEBUG
- DONT_SETTIME equ 1
- HAVE_MYIPNR equ 2
- HAVE_TIMEOFFSET equ 4
- HAVE_TIMESERVER equ 8
-
- TimeServIpNr dw 0, 0
- dw 0, 0
-
- Sday equ 3600*24
-
- days macro incval
- dd x*Sday
- x = x+incval
- endm
-
- Ytab:
- x = 15*366 + 49*365 ; start at 1964
- rept 16
- days 366
- days 365
- days 365
- days 365
- endm ; ends on year 2027
-
- Motab: ; normal year
- x = 0
- days 31 jan
- days 28 feb
- days 31 mar
- days 30 apr
- days 31 may
- days 30 jun
- days 31 jul
- days 31 aug
- days 30 sep
- days 31 oct
- days 30 nov
- days 31 dec
- days 1
-
- Mltab: ; leap yer
- x = 0
- days 31 jan
- days 29 feb
- days 31 mar
- days 30 apr
- days 31 may
- days 30 jun
- days 31 jul
- days 31 aug
- days 30 sep
- days 31 oct
- days 30 nov
- days 31 dec
- days 1
-
- Weekdays db " Sun"
- db " Mon"
- db " Tues"
- db "Wednes"
- db " Thurs"
- db " Fri"
- db " Satur"
-
-
- AlgTab AlgData <>
- AlgTabEnd equ $
-
- AlgIndex dw 0
-
- m6hour dw 6*3600
- m12hour dw 12*3600
- mhour dw 3600
- m60b db 60,0
- m7 dw 7
- m6 db 6
- m1 dw 1
- mindigits dw 2
-
- cWday dw 0
- cYear dw 0
- cMonth dw 0
- cDay dw 0
- cHour dw 0
- cMinute dw 0
- cSecond dw 0
- tsipnr dw 0, 0, 0, 0
-
- cNonLeapYear db 0, 0
- cDayOfYear dw 0
- cTime dw 0, 0
- AlterTime dw 0, 0, 0
- tzoffset dw 0, 0
-
- msgweek = $+13
- msgyear = $+23
- msghour = $+37
- msgset db 'Clock set to Wednesday 1989-10-21 at 18:21:15'
- msgts = $+11
- db ' from host 1.2.3.4 ', CR, LF, '$'
-
- .8086 ; ensure no 386-only instructions
-
- ;************************************************************************
- ;************************************************************************
- ;*
- ;* Packet interface routines
- ;*
- ;************************************************************************
- ;************************************************************************
-
-
- int_pkt macro
- pushf
- cli
- call their_isr
- endm
-
- their_isr dd ?
- packet_int_no db 60h,?,?,?
- signature db 'PKT DRVR',0
- signature_len equ $-signature
- no_signature db "No packet driver at that address",'$'
-
-
-
- ;************************************************************************
- ;* FindPktint
- ;************************************************************************
-
- FindPktint proc near
- FindLoop:
- call TestPktInt
- je FindRet
- inc packet_int_no
- cmp packet_int_no,80h
- jb FindLoop
-
- mov dx,offset no_signature
- mov ah,9
- int 21h
- mov ax,4c02h
- int 21h
- FindRet:
- ret
- Findpktint endp
-
-
-
- ;************************************************************************
- ;* TestPktInt
- ;************************************************************************
-
- TestPktInt proc near
- mov ah,35h ; get their packet interrupt.
- mov al,packet_int_no
- int 21h
- mov their_isr.offs,bx
- mov their_isr.segm,es
- lea di,3[bx]
- mov si,offset signature
- mov cx,signature_len
- repe cmpsb
- ret
- TestPktInt endp
-
-
-
- include pkterr.asm
-
- ;************************************************************************
- ;*
- ;* Note! The code from here to the end will be changed a lot in august
- ;* 1991. I will separate the PDCLKSET application and the UDP/IP library,
- ;* rename variables and some routines, maybe moving code between normal
- ;* and interrupt code. Also note that PDCLKSET only sends two or three
- ;* packets, so currently there is no ICMP handling. In most cases it is
- ;* needed, though, and has to be added on. Some other things to make the
- ;* library RFC-compliant will also be added.
- ;* / Jan E LDC
- ;************************************************************************
-
-
-
-
- ARPSLOTS equ 5
- ROUTESLOTS equ 5
- MAXDEFGWYS equ 5
-
-
- Something2Do proc near
- test Events,GOT_ARPREQ
- jz SomethingRet
- call SendArpReply
- SomethingRet:
- ret
- Something2Do endp
-
-
-
- ;************************************************************************
- ;************************************************************************
- ;*
- ;* UDP/IP library
- ;*
- ;************************************************************************
- ;************************************************************************
-
-
-
- Descriptor struc
- fIOCB iocb <>
- fPtrPhys dw 0
- fPtrIp dw 0
- fPtrUdp dw 0
- fDesFrameLen dw 0
- fDesEvent dw 0
- fDesTimOutMsg dw 0
- fTickResend dw 18
- fTickTimeout dw 73
- Descriptor ends
-
- HwStruc struc
- hEthDst db 6 dup (0ffh) ; Ether broadcast
- hEthSrc db 6 dup (0) ; my Ether addr (filled in)
- hProtType dw 0008 ; 0800 = IP
- HwStruc ends
-
- SnapStruc struc
- sDSAP db 170
- sSSAP db 170
- sContr db 3
- sOrgCode db 0,0,0
- sProt db 08, 00
- SnapStruc ends
-
- IpStruc struc
- iIpVerHlen db 45h ; ver 4, 5 32-bit header words
- iIpTos db 0 ; type of service
- iIpLen dw 0 ; IP packet length
- iIpId dw 0100h ; id 0001
- iIpFlFra dw 0 ; no flags or fragments
- iIpTtl db 0 ; time to live
- iIpProt db 0 ; 17 = udp
- iIpXsum dw 0 ; header checksum
- iIpSrc dw 0, 0 ; Don't know my IP nmbr
- iIpDst dw 0ffffh, 0ffffh ; local net broadcast IP
- iIpOptions equ $-iIpVerHlen
- IpStruc ends
-
- UdpStruc struc
- uUdpSrc dw 4400h ; source port 44h = 68
- uUdpDst dw 4300h ; dest port 43h = 67
- uUdpLen dw 0 ; 134h
- uUdpXsum dw 0 ; udp checksum
- uUdpData equ $-uUdpSrc
- UdpStruc ends
-
- BootpStruc struc
- uUdpStruc UdpStruc <>
- uBotOp db 1 ; bootp request
- uBotHtype db 0 ; hardware type
- uBotHlen db 0 ; hardware addr lenght
- uBotHops db 0 ; hops
- uBotXid dw 0, 0 ; transaction id
- uBotSecs dw 0001 ; 0100h seconds since boot
- uBotUnused dw 0 ; not defined
- uBotCliIp dw 0, 0 ; Client IP unknown
- uBotYourIp dw 0, 0 ; my IP yet unknown
- uBotServIp dw 0, 0 ; Server IP
- uBotGwyIp dw 0, 0 ; Gateway IP
- uBotCliHwAd db 16 dup (0) ; My Hardware address
- uBotSname db 64 dup (0) ; server name
- uBotFilNam db 128 dup (0) ; file name
- uBotMagNum dw 8263h, 6353h ; Magic number * test *
- uBotVend db 64-4 dup (0) ; Vendor specific area
- BpDataLen = $-uBotOp
- BootpStruc ends
-
- BootpFrame struc
- fDescriptor Descriptor <>
- fHwStruc HwStruc <>
- fIpStruc IpStruc <>
- fBotStruc BootpStruc <>
- BpLen = $-fHwStruc
- BootpFrame ends
-
- ArpFrame struc
- fArpDescr Descriptor <>
- fArpHwDst db 6 dup (0ffh) ; Ether broadcast
- fArpHwSrc db 6 dup (0) ; my Ether addr
- fArpType dw 0608h ; 0806 = ARP
- fArpHtype dw 0 ; 0001 = Ether
- fArpProt dw 0008h ; 0800 = IP
- fArpHlen db 0 ; Hw addr length
- fArpPlen db 4 ; IP addr length
- fArpOp dw 0100h ; 0001 = request
- fArpMyHwAd db 38 dup (0)
- ArpLen = $-fArpHwDst
- ArpFrame ends
-
-
- even
- Events dw 1
- DONT_WAIT equ 1
- GOT_BOOTP equ 2
- GOT_ARPREPLY equ 4
- GOT_TIMEREPLY equ 8
- GOT_ARPREQ equ 16
-
- MySegm dw 0
- Hlen dw 0
- MyMask dw 2 dup (0ffffh)
- MyNet dw 2 dup (0ffffh)
- IpHandle dw 0
- ArpHandle dw 0
-
- ifndef MAXDEFGWYS
- MAXDEFGWYS equ 5
- endif
-
- DefGwys dw MAXDEFGWYS*2 dup (0)
- DefGwyIndex dw 0
-
- ifndef ROUTESLOTS
- ROUTESLOTS equ 5
- endif
-
- RouteTabIp2 dw ROUTESLOTS dup (0ffffh)
- RouteTabIp1 dw ROUTESLOTS dup (0ffffh)
- RouteTabIp4 dw ROUTESLOTS dup (0ffffh)
- RouteTabIp3 dw ROUTESLOTS dup (0ffffh)
- RouteTabTos dw ROUTESLOTS dup (0)
- RouteTabTr dw ROUTESLOTS dup (0)
- RoutePutSlot dw 0
-
- ifndef ARPSLOTS
- ARPSLOTS equ 5
- endif
-
- ArpTabIp2 dw ARPSLOTS dup (0ffffh)
- ArpTabIp1 dw ARPSLOTS dup (0ffffh)
- ArpTabSnap dw ARPSLOTS dup (0)
- ArpTabTr dw ARPSLOTS dup (0)
- ArpTabHwAdr db ARPSLOTS*16 dup (0ffh)
- ArpPutSlot dw 0
-
-
-
- SndFrame BootpFrame <>
- ArpPkt ArpFrame <>
-
-
-
- ;************************************************************************
- ;* SendUdpPkt
- ;*
- ;* Input: AX = UDP data length (AX destroyed)
- ;* BX = packet ptr (BX saved)
- ;* Output: Non-zero if OK; zero if timeout
- ;* Destroys: AX, CX, DX, SI, DI, BP and flags
- ;************************************************************************
-
- SendUdpPkt proc near
- add ax,8
- mov [bx].fDesFrameLen,ax
- push ax
- xchg ah,al
- mov di,[bx].fPtrUdp
- mov [di].uUdpLen,ax
- mov [di].uUdpXsum,1
- mov di,[bx].fPtrIp
- mov [di].iIpProt,17
- call UdpChkSum
- pop ax
- call SendIpPkt
- ret
- SendUdpPkt endp
-
-
-
- ;************************************************************************
- ;* SendIpPkt
- ;*
- ;* Input: AX = IP data length (AX destroyed)
- ;* BX = packet ptr (BX saved)
- ;* Output: Non-zero if OK; zero if timeout
- ;* Destroys: AX, CX, DX, SI, DI, BP and flags
- ;************************************************************************
-
- SendIpPkt proc near
- mov di,[bx].fPtrIp
- mov [di].iIpTtl,64h
- mov [di].iIpXsum,1
- call IPHdrLength
- add [bx].fDesFrameLen,cx
- add ax,cx
- xchg ah,al
- mov [di].iIpLen,ax
- call IpChkSum
- call PutPhysHdr
- jz SendIpRet
- call SendAndWait
- SendIpRet:
- ret
- SendIpPkt endp
-
-
-
- ;************************************************************************
- ;* PutPhysHdr
- ;* Output: Non-zero if OK; zero if timeout
- ;************************************************************************
-
- PutPhysHdr proc near
- mov si,offset ArpPkt.fArpMyHwAd
- mov di,[bx].fPtrPhys
- mov cx,Hlen
- add di,cx
- mov es,MySegm
- push cx
- rep movsb
- pop cx
- shl cx,1
- add cx,2
- add [bx].fDesFrameLen,cx
- mov word ptr [di],0008h
- call PutPhysDest
- ret
- PutPhysHdr endp
-
-
-
- ;************************************************************************
- ;* ArpPutNew
- ;************************************************************************
-
- ArpPutNew proc near
- call ArpFind
- jz ArpPut
- ArpPutWrap:
- add ArpPutSlot,2
- mov di,ArpPutSlot
- cmp di,2*ARPSLOTS
- jl ArpPut
- mov ArpPutSlot,0
- jmp short ArpPutWrap
- ArpPut:
- push si
- mov ArpTabIp1[di],dx
- mov ArpTabIp2[di],ax
- mov cl,3
- shl di,cl
- lea di,ArpTabHwAdr[di]
- mov cx,Hlen
- rep movsb
- pop si
- ret
- ArpPutNew endp
-
-
-
- ;************************************************************************
- ;* ArpFind
- ;************************************************************************
-
- ArpFind proc near
- mov es,MySegm
- cld
- mov di,offset ArpTabIp2
- mov cx,ARPSLOTS
- ArpFindNext: ; look for matching slot
- repne scasw
- jz ArpFound2nd
- ArpNotFound:
- jmp short ArpFindRet ; non zero
- ArpFound2nd:
- cmp dx,2*ARPSLOTS-2[di]
- jne ArpFindNext
- sub di,offset ArpTabIp2+2
- cmp di,di ; set zero flag
- ArpFindRet:
- ret
- ArpFind endp
-
-
-
- ;************************************************************************
- ;* RouteFind
- ;************************************************************************
-
- RouteFind proc near
- mov es,MySegm
- cld
- mov di,offset RouteTabIp2
- mov cx,ROUTESLOTS
- RouteFindNext: ; look for matching slot
- repne scasw
- jz RouteFound2nd
- RouteNotFound:
- jmp short RouteFindRet ; non zero
- RouteFound2nd:
- cmp dx,2*RouteSLOTS-2[di]
- jne RouteFindNext
- sub di,offset RouteTabIp2+2
- cmp di,di ; set zero flag
- RouteFindRet:
- ret
- RouteFind endp
-
-
-
- ;************************************************************************
- ;* MyNetChk
- ;************************************************************************
-
- MyNetChk proc near
- push ax
- push dx
- and dx,MyMask
- cmp dx,MyNet
- jne MyNetRet
- and ax,MyMask+2
- cmp ax,MyNet+2
- MyNetRet:
- pop dx
- pop ax
- ret
- MyNetChk endp
-
-
-
- ;************************************************************************
- ;* PutPhysDest
- ;* Output: Non-zero if OK; zero if timeout
- ;************************************************************************
-
- PutPhysDest proc near
- mov di,[bx].fPtrIp
- mov dx,[di].iIpDst
- mov ax,[di].iIpDst+2
- call MyNetChk
- jz PutArp
- call RouteFind
- jz PutArp
-
- mov di,RoutePutSlot
- mov RouteTabIp1[di],dx
- mov RouteTabIp2[di],ax
- mov si,DefGwyIndex
- mov dx,DefGwys[si]
- mov ax,DefGwys+2[si]
- mov RouteTabIp3[di],dx
- mov RouteTabIp4[di],ax
- inc di
- cmp di,ROUTESLOTS
- jb PutRouteSlot
- xor di,di
- PutRouteSlot:
- mov RoutePutSlot,di
- PutArp:
- call ArpFind
- jnz NeedArpReq
- FoundArpEntry:
- mov cl,3
- shl di,cl
- lea si,ArpTabHwAdr[di]
- mov di,[bx].fPtrPhys
- mov cx,Hlen
- mov es,MySegm
- rep movsb
- dec cx
- ret
-
- NeedArpReq:
- push bx
- mov di,[bx].fPtrIp
- mov ax,[di].iIpSrc
- mov word ptr ArpPkt.fArpMyHwAd+6,ax
- mov ax,[di].iIpSrc+2
- mov word ptr ArpPkt.fArpMyHwAd+8,ax
- mov ax,[di].iIpDst
- mov cx,[di].iIpDst+2
- mov dx,[bx].fDesTimOutMsg
- mov bx,offset ArpPkt
- mov word ptr [bx].fArpMyHwAd+6+4+6,ax
- mov word ptr [bx].fArpMyHwAd+6+4+6+2,cx
- mov [bx].fDesTimOutMsg,dx
- mov [bx].fTickResend,5
- mov [bx].fTickTimeout,20
- mov [bx].fPtrPhys,offset ArpPkt.fHwStruc
- mov [bx].fDesFrameLen,ArpLen
- mov [bx].fDesEvent,GOT_ARPREPLY
- call SendAndWait
- pop bx
- jz PutPhysRet
- jmp PutPhysDest
- PutPhysRet:
- ret
- PutPhysDest endp
-
-
-
- ;************************************************************************
- ;* SendAndWait
- ;* Output: Non-zero if OK; zero if timeout
- ;************************************************************************
-
- SendAndWait proc near
- mov si,[bx].fDesEvent
- not si
- and Events,si
- not si
- call SendRawPkt
-
- mov ax,40h
- mov es,ax
- mov bp,es:6ch ; get current ticks value
- mov di,[bx].fTickResend ; first resend time
- lea ax,[bp+di]
- add bp,[bx].fTickTimeout ; time out
- WaitLoop:
- test Events,si ; got what we want?
- jnz SendWaitRet
- call Something2Do ; anything else to do?
- cmp ax,es:6ch ; time to resend?
- jg ChkTimeout
- shl di,1 ; double resend time
- cmp di,30*18
- jbe SendDouble
- mov di,30*18 ; max 30 seconds
- SendDouble:
- add ax,di ; next resend time
- call SendRawPkt
- ChkTimeout:
- cmp bp,es:6ch ; time out?
- jg WaitLoop
-
- mov dx,[bx].fDesTimOutMsg
- or dx,dx
- jz SendWaitRet
- mov ah,9 ; print error msg in dx
- int 21h
- mov al,04 ; error code
- call Terminate
- SendWaitRet:
- ret
- SendAndWait endp
-
-
-
- ;************************************************************************
- ;* SendRawPkt
- ;*
- ;* (The saving of all registers below is not needed for the Clarkson
- ;* collection of packet drivers, but as far as I understand the packet
- ;* driver specification other drivers may need it.)
- ;************************************************************************
-
- SendRawPkt proc near
- push dx
- push cx
- push bx
- push ax
- push si
- push di
- push bp
- push es
- mov si,[bx].fPtrPhys
- mov cx,[bx].fDesFrameLen
- mov ah,4
- push ds
- int_pkt
- pop ds
- pop es
- pop bp
- pop di
- pop si
- pop ax
- pop bx
- pop cx
- jc BadPkt
- pop dx
- ret
- BadPkt:
- call print_error
- mov al,03 ; error code
- call Terminate
- SendRawPkt endp
-
-
-
- ;************************************************************************
- ;* ChkSum
- ;* Input: SI = start addr
- ;* CX = # of bytes
- ;* Output: AX = 1-complement checksum
- ;* CX = partial checksum
- ;* SI = addr of next byte
- ;* Non-zero
- ;* Destroys: Flags
- ;************************************************************************
-
- ChkSum proc near
- push dx
- shr cx,1 ; divide by two, round down
- pushf ; keep odd bit in carry
- xor dx,dx ; clear dx and carry
- ChkLoop:
- lodsw
- adc dx,ax ; add to previous running sum
- loop ChkLoop
-
- adc dx,0 ; add the last carry in again
- popf ; odd # of bytes?
- jnc NotOdd
- lodsb ; get that last byte
- xor ah,ah ; clear carry and the high portion
- add dx,ax ; add the last one in
- adc dx,0 ; add the carry in, too
- NotOdd:
- mov ax,dx
- mov cx,dx
- pop dx
- not ax ; take one more 1-complement
- jz AllOnes
- ret
- AllOnes:
- not ax
- ret
- ChkSum endp
-
-
-
- ;************************************************************************
- ;* UdpChkSum (both for generate and check!)
- ;************************************************************************
-
- UdpChkSum proc near
- mov si,[bx].fPtrIp
- mov di,[bx].fPtrUdp
- xor dx,dx
- mov [si].iIpTtl,dl ; Note: Time To Live destroyed!
- xchg dx,[di].uUdpXsum
- or dx,dx
- jz NoUdpSum
- mov cx,[di].uUdpLen ; checksum pseudo hdr
- mov [si].iIpXsum,cx
- xchg ch,cl
- push cx
- mov cx,12
- add si,iIpTtl
- call ChkSum
- mov [di].uUdpXsum,cx ; move partial checksum
- pop cx ; into udp hdr
- mov si,[bx].fPtrUdp ; checksum udp hdr+data
- call ChkSum
- mov [di].uUdpXsum,ax
- cmp ax,dx
- NoUdpSum:
- ret
- UdpChkSum endp
-
-
-
- ;************************************************************************
- ;* IpHdrLength
- ;************************************************************************
-
- IpHdrLength proc near
- mov si,[bx].fPtrIp
- mov cx,[si]
- and cx,0fh
- shl cx,1
- shl cx,1
- ret
- IpHdrLength endp
-
-
-
- ;************************************************************************
- ;* IpChkSum (both for generate and check!)
- ;************************************************************************
-
- IpChkSum proc near
- xor dx,dx
- mov di,[bx].fPtrIp
- xchg dx,[di].iIpXsum
- call IpHdrLength
- call ChkSum
- mov [di].iIpXsum,ax
- cmp ax,dx
- ret
- IpChkSum endp
-
-
-
- ;************************************************************************
- ;* SendArpReply
- ;************************************************************************
-
- SendArpReply proc near
- ret
- SendArpReply endp
-
-
-
- ;************************************************************************
- ;* EndProtocol
- ;************************************************************************
-
- EndProtocol proc near
- mov ah,3 ; release handle in bx
- push ds
- int_pkt
- pop ds
- call print_error
- ret
- EndProtocol endp
-
-
-
- ;************************************************************************
- ;* Terminate
- ;************************************************************************
-
- Terminate proc near
- pop bx ; remove return addr fr stack
- push ax
- mov bx,IpHandle
- call EndProtocol
- mov bx,ArpHandle
- call EndProtocol
-
- pop ax
- push ax
- cmp al,0
- jz termnorm
- mov dx,offset MsgNotSet
- mov ah,9
- int 21h
- termnorm:
- pop ax
- push ax
- add al,'0'
- mov MsgTermNr,al
- mov dx,offset MsgTerm
- mov ah,9
- int 21h
-
- pop ax
- mov ah,4ch
- int 21h
- Terminate endp
-
-
-
- ;************************************************************************
- ;************************************************************************
- ;*
- ;* Input and Output routines
- ;*
- ;************************************************************************
- ;************************************************************************
-
-
-
- ;************************************************************************
- ;* SkipPastEq
- ;************************************************************************
-
- SkipPastEq proc near
- mov cx,30
- SkipLook4Eq:
- cmp al,'='
- je SkipFoundEq
- lodsb
- loop SkipLook4Eq
- SkipFoundEq:
- call skip_blanks
- ret
- SkipPastEq endp
-
-
-
- ;************************************************************************
- ;* GetNums
- ;************************************************************************
-
- GetNums proc near
- mov bh,','
- jmp short GetSkipBlanks
- GetNumsDot:
- mov bh,'.'
- GetSkipBlanks:
- call skip_blanks
- GetNextNum:
- call GetDec
- stosw
- dec bl
- jz GetNumsRet
- lodsb
- cmp al,bh
- jne GetNumsRet
- jmp short GetNextNum
- GetNumsRet:
- ret
- GetNums endp
-
-
-
- ;************************************************************************
- ;* GetDec
- ;************************************************************************
-
- GetDec proc near
- xor dx,dx
- lodsb
- cmp al,'-'
- pushf
- je GetDecSign
- cmp al,'+'
- jne GetNextDig
- GetDecSign:
- lodsb
- GetNextDig:
- cmp al,'0'
- jb GetDecEnd
- cmp al,'9'
- ja GetDecEnd
- sub al,'0'
- cbw
- add ax,dx
- mov cx,ax
- mul k10
- mov dx,ax
- lodsb
- jmp short GetNextDig
- GetDecEnd:
- mov dx,60*60
- cmp al,'h'
- je GetDecScale
- mov dx,60
- cmp al,'m'
- je GetDecScale
- mov dx,1
- cmp al,'s'
- je GetDecScale
- dec si
- GetDecScale:
- mov ax,cx
- mul dx
- popf
- jne GetDecRet
- not dx
- not ax
- add ax,1
- adc dx,0
- GetDecRet:
- ret
- GetDec endp
-
-
-
- k10 dw 10
- TmpIpNr dw 0, 0, 0, 0
-
-
-
- ;************************************************************************
- ;* GetIpNr
- ;************************************************************************
-
- GetIpNr proc near
- push di
- mov bl,4
- mov di,offset TmpIpNr
- call GetNumsDot
- jnz GetIpNrRet
- mov cx,4
- pop di
- push si
- mov si,offset TmpIpNr
- GetIpNrLoop:
- lodsw
- stosb
- loop GetIpNrLoop
-
- pop si
- xor ax,ax
- GetIpNrRet:
- ret
- GetIpNr endp
-
-
-
- ;************************************************************************
- ;* PutNums
- ;************************************************************************
-
- PutNums proc near
- NextNum:
- lodsw
- call PutDec
- dec bl
- jz PutNumsRet
- mov al,bh
- stosb
- jmp short NextNum
- PutNumsRet:
- ret
- PutNums endp
-
-
-
- ;************************************************************************
- ;* PutDec
- ;************************************************************************
-
- PutDec proc near
- xor cx,cx
- NextDec:
- xor dx,dx
- div k10
- add dx,'0'
- push dx
- inc cx
- or ax,ax
- jnz NextDec
- mov ax,'0'
- ZeroFill:
- cmp cx,mindigits
- jae putdigs
- push ax
- inc cx
- jmp short ZeroFill
- PutDigs:
- pop ax
- stosb
- loop PutDigs
- ret
- PutDec endp
-
-
-
- include skipblk.asm
- include chrout.asm
-
-
-
- ;************************************************************************
- ;************************************************************************
- ;* *
- ;* Program begins *
- ;* *
- ;************************************************************************
- ;************************************************************************
-
-
- start1:
- mov ax,cs
- mov ds,ax
- mov es,ax
- mov MySegm,ax
- cld
-
- call DoArgs
- call FindPktint
- call InitArp
- call InitIp
-
- HAVE_ENOUGH equ HAVE_MYIPNR + HAVE_TIMEOFFSET + HAVE_TIMESERVER
- mov dx,Flagword
- and dx,HAVE_ENOUGH
- cmp dx,HAVE_ENOUGH
- je SkipBootp
-
- call DoBootpPkt
- call InterpBootp
- SkipBootp:
- mov dx,Flagword
- and dx,HAVE_ENOUGH
- cmp dx,HAVE_ENOUGH
- je DoTime
-
- mov dx,offset NotEnoughMsg
- mov ah,9
- int 21h
- mov al,7 ; error code 7
- jmp short SkipTime
- DoTime:
- or Events,GOT_BOOTP
- call GetTime
- call SetTime
- mov al,0 ; error code = 0
- SkipTime:
- call terminate
-
- ;************************************************************************
- ;************************************************************************
- ;* End of program *
- ;************************************************************************
- ;************************************************************************
-
-
-
- ;************************************************************************
- ;* DoArgs
- ;************************************************************************
-
- DoArgs proc near
- mov si,offset phd_dioa
- lodsb
- xor ah,ah
- mov bp,ax
- add bp,si
- call skip_blanks
- cmp al,CR ;end of line?
- je ArgError
-
- NextArg:
- call skip_blanks
- cmp si,bp
- jbe ArgFound
- jmp DoArgRet
- ArgFound:
- or al,020h ; conv to lower case
-
- cmp al,'m' ; net mask
- jne ArgNotMask
- call SkipPastEq
- mov di,offset MyMask
- call GetIpNr
- jz NextArg
- ArgError: jmp usage_error
- ArgNotMask:
- cmp al,'i' ; my ip nr
- jne ArgNotMyIp
- call SkipPastEq
- mov di,offset SndFrame.fIpStruc.iIpSrc
- call GetIpNr
- jnz ArgError
- or Flagword,HAVE_MYIPNR
- jmp short NextArg
- ArgNotMyIp:
- cmp al,'a' ; alter time
- jne ArgNotAlter
- call SkipPastEq
- mov di,offset AlterTime
- mov bl,2
- call GetNums
- mov AlterTime+4,dx
- jnz ArgError
- or word ptr Flagword,DONT_SETTIME
- jmp short NextArg
- ArgNotAlter:
- cmp al,'p' ; Packet int number
- jne NotPktIntNr
- call SkipPastEq
- call GetDec
- mov word ptr packet_int_no,ax
- jmp short NextArg
- NotPktIntNr:
- cmp al,'o' ; time offset
- jne ArgNotOffset
- call SkipPastEq
- call GetDec
- xchg ah,al
- xchg dh,dl
- mov tzoffset,dx
- mov tzoffset+2,ax
- or Flagword,HAVE_TIMEOFFSET
- jmp NextArg
- ArgNotOffset:
- cmp al,'t' ; time server
- jne ArgNotTimServ
- call SkipPastEq
- mov di,offset TimeServIpNr
- call GetIpNr
- jnz usage_error
- or Flagword,HAVE_TIMESERVER
- lodsb
- cmp al,','
- jne ArgNextArg
- call GetIpNr
- jnz usage_error
- jmp NextArg
- ArgNotTimServ:
- cmp al,'g' ; defult gateways
- jne ArgNotGwys
- call SkipPastEq
- mov di,offset DefGwys
- call GetIpNr
- jnz usage_error
- lodsb
- cmp al,','
- jne ArgNextArg
- call GetIpNr
- jne usage_error
- ArgNextArg:
- jmp NextArg
- ArgNotGwys:
- cmp al,'d' ; daylight saving algorithm
- jne ArgNotDlsAlg
- call SkipPastEq
- cmp al,'9'
- jbe ArgGetAlgPar
- lodsw
- mov dx,ax
- lodsw
- mov di,offset AlgTab-AlgEntryLen
- cmp ah,CR
- jne ArgNextDls
- mov ah,' '
- dec si
- ArgNextDls:
- add di,AlgEntryLen
- cmp di,offset AlgTabEnd
- jae usage_error
- cmp dx,[di]
- jne ArgNextDls
- cmp ax,[di+2]
- jne ArgNextDls
- mov AlgIndex,di
- jmp NextArg
- ArgGetAlgPar:
- mov di,offset AlgTab
- mov AlgIndex,di
- add di,4
- mov bl,5
- call GetNums
- jnz usage_error
- jmp NextArg
- ArgNotDlsAlg:
- cmp al,'b' ; bootp
- je DoArgRet
-
- cmp al,CR+020h
- jne usage_error
- DoArgRet:
- ret
-
- usage_error:
- mov dx,offset usage_msg
- error:
- mov ah,9
- int 21h
- mov ax,4c01h
- int 21h
- DoArgs endp
-
-
-
- ;************************************************************************
- ;* InitArp
- ;************************************************************************
-
- InitArp proc near
- push ds
- mov ax,1ffh ; driver_info
- int_pkt
- pop ds
- call fatal_error
-
- mov ah,2 ; access all packets.
- mov al,ch ; their class from driver_info().
- mov byte ptr ArpPkt.fArpHtype+1,al
- mov bx,dx ; their type from driver_info().
- mov dl,cl ;their number from driver_info().
- mov cx,2 ;type length of zero.
- mov si,offset ArpPkt.fArpType
- push cs ;es:di -> our receiver.
- pop es
- mov di,offset ArpRecv
- push ds
- int_pkt
- pop ds
- call fatal_error
- mov ArpHandle,ax
-
- mov ArpPkt.fPtrPhys,offset ArpPkt.fArpHwDst
-
- mov bx,ax
- push cs
- pop es
- mov di,offset ArpPkt.fArpMyHwAd
- mov cx,15
- mov ah,6 ; get my Hw addr
- push ds
- int_pkt
- pop ds
- call fatal_error
- mov ArpPkt.fArpHlen,cl
- mov Hlen,cx
-
- mov si,offset ArpPkt.fArpMyHwAd
- mov di,offset ArpPkt.fArpHwSrc
- mov es,MySegm
- mov cx,Hlen
- rep movsb
- ret
- InitArp endp
-
-
-
- ;************************************************************************
- ;* InitIp
- ;************************************************************************
-
- InitIp proc near
- push ds
-
- mov SndFrame.fPtrPhys,offset SndFrame.fHwStruc
- mov SndFrame.fPtrIp,offset SndFrame.fIpStruc
- mov SndFrame.fPtrUdp,offset SndFrame.fBotStruc
-
- mov ax,1ffh ;driver_info
- int_pkt
- pop ds
- call fatal_error
-
- mov ah,2 ;access all packets.
- mov al,ch ;their class from driver_info().
- mov bx,dx ;their type from driver_info().
- mov dl,cl ;their number from driver_info().
- mov cx,2 ;type length of zero.
- mov si,offset SndFrame.fHwStruc.hProtType
- push cs ;es:di -> our receiver.
- pop es
- mov di,offset IpRecv
- push ds
- int_pkt
- pop ds
- call fatal_error
- mov IpHandle,ax
-
- mov si,offset ArpPkt.fArpMyHwAd
- mov di,offset SndFrame.fHwStruc.hEthSrc
- mov es,MySegm
- mov cx,Hlen
- rep movsb
- ret
- InitIp endp
-
-
-
- ;************************************************************************
- ;* DoBootpPkt
- ;************************************************************************
-
- DoBootpPkt proc near
- mov ax,40h
- mov es,ax
- mov ax,es:6ch
- mov SndFrame.fBotStruc.uBotXid,ax
-
- mov al,byte ptr ArpPkt.fArpHtype+1
- mov SndFrame.fBotStruc.uBotHtype,al
- mov si,offset ArpPkt.fArpMyHwAd
- mov di,offset SndFrame.fBotStruc.uBotCliHwAd
- mov es,MySegm
- mov cx,Hlen
- mov SndFrame.fBotStruc.uBotHlen,cl
- rep movsb
-
-
- mov bx,offset SndFrame ; frame to send
- mov [bx].fDesEvent,GOT_BOOTP ; event to wait for
- mov [bx].fDesTimOutMsg,offset NoBotReplyMsg ; error msg
- mov ax,BpDataLen
- call SendUdpPkt
- ret
- DoBootpPkt endp
-
-
-
- ;************************************************************************
- ;* InterpBootp
- ;************************************************************************
-
- InterpBootp proc near
- mov bx,offset IpBuf
- mov di,[bx].fPtrUdp
- mov ax,[di].uBotYourIp
- mov SndFrame.fIpStruc.iIpSrc,ax
- mov word ptr ArpPkt.fArpMyHwAd+6,ax
- mov ax,[di].uBotYourIp+2
- mov SndFrame.fIpStruc.iIpSrc+2,ax
- mov word ptr ArpPkt.fArpMyHwAd+8,ax
- or Flagword,HAVE_MYIPNR
-
- cmp word ptr [di].uBotMagNum,8263h
- jne VendEnd
- cmp word ptr [di].uBotMagNum+2,6353h
- jne VendEnd
-
- lea si,[di].uBotVend
- lea bx,[si]+64-4
- mov es,MySegm
- VendLoop:
- cmp si,bx
- jb VendNext
-
- VendEnd:
- ret
-
- VendNext:
- lodsb
-
- cmp al,0
- je VendLoop
-
- cmp al,1
- jne NotMask
- mov di,offset MyMask
- call Xtract4Bytes
- jmp short VendLoop
- NotMask:
- cmp al,2
- jne NotTimeOffs
- test Flagword,HAVE_TIMEOFFSET
- jnz VendDefault
- mov di,offset tzoffset
- call Xtract4Bytes
- or Flagword,HAVE_TIMEOFFSET
- jmp short VendLoop
- NotTimeOffs:
- cmp al,3
- jne NotDefGwys
- mov di,offset DefGwys
- mov cx,4*MAXDEFGWYS
- call XtractNBytes
- jmp short VendLoop
- NotDefGwys:
- cmp al,4
- jne NotTimeserv
- or Flagword,HAVE_TIMESERVER
- cmp TimeServIpNr+4,0
- jne VendDefault
- cmp TimeServIpNr,0
- jne OneServer
- mov di,offset TimeServIpNr
- call Xtract8Bytes
- jmp short VendLoop
- OneServer:
- mov di,offset TimeServIpNr+4
- call Xtract4Bytes
- jmp short VendLoop
- NotTimeserv:
- cmp al,0ffh
- je VendEnd
- VendDefault:
- lodsb
- xor ah,ah
- add si,ax
- jmp Vendloop
-
- InterpBootp endp
-
-
-
- ;************************************************************************
- ;* Xtract4Bytes
- ;************************************************************************
-
- Xtract4Bytes proc near
- mov cl,4
- jmp short XtractNBytes
- Xtract8Bytes:
- mov cl,8
- XtractNBytes:
- lodsb
- cmp cl,al
- jbe XtractOkLen
- mov cl,al
- XtractOkLen:
- xor ch,ch
- xor ah,ah
- push ax
- push si
- rep movsb
- pop si
- pop ax
- add si,ax
- ret
- Xtract4Bytes endp
-
-
-
- ;************************************************************************
- ;* GetTime
- ;************************************************************************
-
- GetTime proc near
- mov bx,offset SndFrame
- mov [bx].fBotStruc.uUdpDst,2500h ; 37 = time
- mov [bx].fBotStruc.uUdpSrc,1234
- mov ax,TimeServIpNr
- mov [bx].fIpStruc.iIpDst,ax
- mov ax,TimeServIpNr+2
- mov [bx].fIpStruc.iIpDst+2,ax
- mov [bx].fDesEvent,GOT_TIMEREPLY
- mov dx,offset NoTimeServMsg
- cmp TimeServIpNr+4,0
- je No2ndServ
- xor dx,dx
- No2ndServ:
- mov [bx].fDesTimOutMsg,dx
- xor ax,ax ; No data! (length=0)
- call SendUdpPkt
- jnz DoneServ
-
- mov ax,TimeServIpNr+4
- mov TimeServIpNr,ax
- mov ax,TimeServIpNr+6
- mov TimeServIpNr+2,ax
- mov TimeServIpNr+4,0
-
- mov ax,TimeServIpNr
- mov [bx].fIpStruc.iIpDst,ax
- mov ax,TimeServIpNr+2
- mov [bx].fIpStruc.iIpDst+2,ax
- mov [bx].fDesTimOutMsg,offset NoTimeServMsg
- xor ax,ax
- call SendUdpPkt
- DoneServ:
- ret
- GetTime endp
-
-
-
- ;************************************************************************
- ;* SetTime
- ;************************************************************************
-
- SetTime proc near
- push cs
- push cs
- pop ds
- pop es
- cld
-
- mov cx,4
- mov si,offset TimeServIpNr
- mov di,offset tsipnr
- xor ah,ah
- TsIpLoop:
- lodsb
- stosw
- loop TsIpLoop
-
- mov cx,cTime
- xchg ch,cl
- mov bx,cTime+2
- xchg bh,bl
-
- mov dx,tzoffset+2
- xchg dh,dl
- sub bx,dx
- mov ax,tzoffset
- xchg ah,al
- sbb cx,ax
-
- mov ax,AlterTime
- imul m6hour
- shl ax,1
- rcl dx,1
- shl ax,1
- rcl dx,1
- add bx,ax
- adc cx,dx
-
- mov ax,AlterTime+2
- mov dx,AlterTime+4
- add bx,ax
- adc cx,dx
-
- mov si,AlgIndex
- or si,si
- jnz DoDls
- jmp SetNoDls
- DoDls:
- push bx
- push cx
- add si,4
- lodsw ; from switching time
- imul m1
- sub bx,ax
- sbb cx,dx
-
- call DateTimeCalc
-
- cmp si,offset AlgTab.Apa0 ; four entry part?
- jl SingleEntry
- mov al,AlgEntryLen
- mul cNonLeapYear
- add si,ax
- cmp si,offset AlgTab.Ais0 ; acyclic entry?
- jb SingleEntry
- cmp cYear,WARNYEAR
- jb SingleEntry
- mov MsgTermStop,' ' ; activate warning msg
- SingleEntry:
- mov bp,cDayOfYear
- lodsw ; from switching weekday
- cmp al,SAT
- ja FromDate
- dec bp
- cmp ax,cWday
- jg CurWeekF
- add bp,7
- CurWeekF:
- sub bp,cWday
- add bp,ax
- FromDate:
- pop cx
- pop bx
- push bx
- push cx
- lodsw ; from switching week
-
- push ax
- lodsw ; until switching time
- imul m1
- sub bx,ax
- sbb cx,dx
-
- call DateTimeCalc
-
- mov di,cDayOfYear
- pop dx
-
- lodsw ; switching until weekday
- cmp al,SAT
- ja UntilDate
- dec di
- cmp ax,cWday
- jg CurWeekU
- add di,7
- CurWeekU:
- sub di,cWday
- add di,ax
- UntilDate:
- lodsw ; until switching week
- test cNonLeapYear,011b
- jnz SetNotLeap
- cmp ax,31+28
- jbe SetChkLU
- inc ax
- SetChkLU:
- cmp dx,31+28
- jbe SetNotLeap
- inc dx
- SetNotLeap:
- pop cx
- pop bx
- cmp ax,dx ; north or south of equator?
- jl SetSouth
- cmp dx,bp
- jg SetNoDls
- jmp short SetChkUntil
- SetSouth:
- cmp dx,bp
- jle DoDLSaving
- SetChkUntil:
- cmp di,ax
- jge SetNoDls
- DoDLSaving:
- lodsw ; dst advance time
- imul m1
- add bx,ax
- adc cx,dx
- SetNoDls:
- call DateTimeCalc
-
- test Flagword,DONT_SETTIME
- jz SetPCtime
- mov di,offset msgset
- mov cx,12
- mov al,' '
- rep stosb
- jmp SkipTimeset
- SetPCtime:
- mov cx,cYear
- mov dh,byte ptr cMonth
- mov dl,byte ptr Cday
- mov ah,2Bh ; set date
- int 21h
- or al,al
- jz DateOK
- mov al,5
- call terminate
- DateOK:
- mov ch,byte ptr cHour
- mov cl,byte ptr cMinute
- mov dh,byte ptr cSecond
- mov dl,99
- mov ah,2Dh ; set time
- int 21h
- or al,al
- jz TimeOK
- mov al,6
- call terminate
- TimeOK:
- SkipTimeset:
- mov al,byte ptr cWday
- mul m6
- add ax,offset Weekdays
- mov si,ax
- mov di,offset msgweek
- mov cx,3
- rep movsw
-
- mov si,offset cYear
- mov di,offset msgyear
- mov bh,'-'
- mov bl,3
- call PutNums
-
- mov di,offset msghour
- mov bh,':'
- mov bl,3
- call PutNums
-
- mov mindigits,1
- mov di,offset msgts
- mov bh,'.'
- mov bl,4
- call PutNums
-
- mov dx,offset msgset
- mov ah,9
- int 21h ; display string
-
- ret
- SetTime endp
-
-
-
- ;************************************************************************
- ;* DateTimeCalc
- ;************************************************************************
-
- DateTimeCalc proc near
- mov ax,bx
- mov dx,cx
- push si
- push ax
- push dx
-
- mov si,offset Ytab
- mov cx,4*64
- call BinSearch
- add bx,1964
- mov cYear,bx
-
- push ax
- push dx
- shr dx,1
- rcr ax,1
- div m12hour
- inc ax
- mov cDayOfYear,ax
- pop dx
- pop ax
-
- mov si,offset Motab
- mov cx,4*16
- and bl,011b
- mov cNonLeapYear,bl
- jnz NoLeapYear
- mov si,offset Mltab
- NoLeapYear:
- call BinSearch
- inc bx
- mov cMonth,bx
-
- shr dx,1
- rcr ax,1
- rcr bx,1
- div m12hour
- inc ax
- mov cDay,ax
-
- mov ax,dx
- xor dx,dx
- shl bx,1
- rcl ax,1
- rcl dx,1
- div mhour
- mov cHour,ax
-
- mov ax,dx
- div m60b
- mov dl,ah
- xor dh,dh
- mov cSecond,dx
- xor ah,ah
- mov cMinute,ax
-
- pop dx
- pop ax
- shr dx,1
- rcr ax,1
- div m12hour
- add ax,1
- xor dx,dx
- div m7
- mov cWday,dx
- pop si
- ret
- DateTimeCalc endp
-
-
-
- ;************************************************************************
- ;* BinSearch
- ;************************************************************************
-
- BinSearch proc near
- xor bx,bx
- BinLoop:
- shr cx,1
- cmp cx,2
- je BinDone
- add bx,cx
- cmp dx,2[si+bx]
- BinEval:
- ja BinLoop
- je BinEqual
- sub bx,cx
- jmp BinLoop
- BinEqual:
- cmp ax,[si+bx]
- ja BinLoop
- je BinDone
- sub bx,cx
- jmp BinLoop
- BinDone:
- sub ax,[si+bx]
- sbb dx,2[si+bx]
- shr bx,1
- shr bx,1
- ret
- BinSearch endp
-
-
-
- ;************************************************************************
- ;* IP receiver *
- ;************************************************************************
-
- IpRecv:
- pushf
- or ax,ax ; first or second call?
- jne IpRecv_1 ; second
- push cs
- pop es
- mov di,offset IpBuf.fHwStruc
- test cs:Events,GOT_BOOTP
- jz IpRecRet0
- mov di,offset IpBuf2.fHwStruc
- test cs:Events,GOT_TIMEREPLY
- jz IpRecRet0
- xor di,di
- mov es,di
- IpRecRet0:
- popf
- retf
-
- IpRecv_1:
- push cs
- pop ds
- cli
- mov word ptr StackBeg,sp
- mov word ptr StackBeg+2,ss
- mov sp,offset StackEnd
- mov ss,MySegm
- sti
-
- mov bx,si
- mov bp,si
- add bp,cx
- sub bx,fHwStruc
- mov [bx].fDesFrameLen,cx
- mov [bx].fPtrPhys,si
- add si,Hlen
- add si,Hlen
- mov ax,[si]
- xchg ah,al
- cmp ax,GIANT
- ja RecvNotSnap
- add si,8
- RecvNotSnap:
- lea di,[si+2]
- mov [bx].fPtrIp,di
-
- call IpChkSum
- jne IpRecRet
- cmp si,bp
- ja IpRecRet
- mov [bx].fPtrUdp,si
-
- cmp [di].iIpProt,17 ; UDP
- jne IpRecRet
- mov di,si
-
- call UdpChkSum
- jne IpRecRet
- cmp si,bp
- jbe IpRecUdp
- IpRecRet:
- cli
- mov sp, word ptr StackBeg
- mov ss, word ptr StackBeg+2
- popf
- retf
-
- IpRecUdp:
- test Events,GOT_BOOTP
- jnz RecvTime
-
- ; cmp [bx].fDesFrameLen,BpLen
- ; jl IpRecRet
- if DEBUG
- ; cmp byte ptr [bx].fHwStruc.hEthSrc+4,05ah ; Nomina
- cmp byte ptr [bx].fHwStruc.hEthSrc+4,059h ; Pollux
- jne IpRecRet
- endif ; DEBUG
- cmp word ptr [di].uUdpSrc,4300h ; Src port 0043 = 67
- jne IpRecRet
- cmp word ptr [di].uUdpDst,4400h
- jne IpRecRet
- cmp byte ptr [di].uBotOp,2 ; reply
- jne IpRecRet
-
- push di
- lea si,[di].uBotCliHwAd
- mov di,offset ArpPkt.fArpMyHwAd
- mov cx,Hlen
- repe cmpsb
- pop di
- jne IpRecRet
-
- mov ax,word ptr SndFrame.fBotStruc.uBotXid
- cmp ax,word ptr [di].uBotXid
- jne IpRecRet
- mov ax,word ptr SndFrame.fBotStruc.uBotXid+2
- cmp ax,word ptr [di].uBotXid+2
- jne IpRecRet
-
- mov dx,[di].uBotGwyIp
- mov ax,[di].uBotGwyIp+2
- mov si,[bx].fPtrPhys
- add si,Hlen
- call ArpPutNew
-
- or Events,GOT_BOOTP
- jmp IpRecRet
-
- RecvTime:
- cmp word ptr [di].uUdpSrc,2500h ; Src port 0025 = 37
- jne IpRecRet
-
- mov ax,[di].uUdpData
- mov cTime,ax
- mov ax,[di].uUdpData+2
- mov cTime+2,ax
-
- or Events,GOT_TIMEREPLY
-
- jmp IpRecRet
-
-
- ;************************************************************************
- ;* ARP receiver *
- ;************************************************************************
-
- ArpRecv:
- pushf
- or ax,ax ; first or second call?
- jne ArpRecv_1 ; second
- push cs
- pop es
- mov di,offset ArpBuf.fHwStruc
- test cs:Events,GOT_ARPREPLY
- jz ArpRecRet0
- mov di,offset ArpBuf2.fHwStruc
- ArpRecRet0:
- popf
- retf
-
- ArpRecv_1:
- cmp cx,ArpLen
- jl ArpRecRet
- push cs
- pop ds
- mov bx,offset ArpBuf
- mov dx,word ptr [bx].fArpMyHwAd+6
- mov ax,word ptr [bx].fArpMyHwAd+6+2
- call ArpFind
- lea si,[bx].fArpMyHwAd
- jnz ArpNotThere
- call ArpPut
- ArpNotThere:
- cmp dx,word ptr ArpPkt.fArpMyHwAd+6+4+6
- jne ArpRecRet
- cmp ax,word ptr ArpPkt.fArpMyHwAd+6+4+6+2
- jne ArpRecRet
-
- call ArpPutNew
-
- or Events,GOT_ARPREPLY
- ArpRecRet:
- popf
- retf
-
-
-
- ;************************************************************************
- ;* Receive buffers *
- ;************************************************************************
-
- ArpBuf equ $
- ArpBuf2 equ ArpBuf+GIANT
- IpBuf equ ArpBuf2+GIANT
- IpBuf2 equ IpBuf+GIANT
- StackBeg equ IpBuf2+GIANT
- StackEnd equ StackBeg+1000
-
- code_s ends
- end start
-