root/modules/pxechain.asm

Revision 49029ca74eaf5d657d429d9c7c5085e5109d444a, 9.8 KB (checked in by H. Peter Anvin <hpa@…>, 3 years ago)

pxechain: remove unused ipaddrbuf

Remove unused ipaddrbuf.

  • Property mode set to 100644
Line 
1; "$Id: pxechain.asm,v 1.2 2007/12/16 08:15:39 jhutz Exp $"
2; -*- fundamental -*- (asm-mode sucks)  vim:noet:com=\:;
3; ****************************************************************************
4;
5;  pxechain.asm
6;
7;  A comboot program to chain from PXELINUX to another PXE network
8;  bootstrap program (NBP).  This improves on PXELINUX's built-in PXE
9;  chaining support by arranging for the server address and boot filename
10;  reported by the PXE stack to be those from which the new NBP was
11;  loaded, allowing PXELINUX to be used to select from multiple NBP's,
12;  such as gPXE, another PXELINUX(*), Windows RIS, and so on.
13;
14;  (*) This seems unnecessary at first, but it is very helpful when
15;  selecting from among self-contained network boot images.
16;
17;   Copyright (c) 2007 Carnegie Mellon University
18;   Copyright (C) 1994-2007  H. Peter Anvin
19;
20;  This program is free software; you can redistribute it and/or modify
21;  it under the terms of the GNU General Public License as published by
22;  the Free Software Foundation, Inc., 53 Temple Place Ste 330,
23;  Boston MA 02111-1307, USA; either version 2 of the License, or
24;  (at your option) any later version; incorporated herein by reference.
25;
26; ****************************************************************************
27
28;%define DEBUG
29;%define NO_RUN
30
31                absolute 0
32pspInt20:       resw 1
33pspNextP:       resw 1
34                resb 124
35pspCmdLen:      resb 1
36pspCmdArg:      resb 127
37
38                section .text
39                org     0x100
40
41%ifdef DEBUG
42%macro MARK 1.nolist
43                mov ah,0x02
44                mov dl,%1&0xff
45                int 0x21
46%if (%1 >> 8) & 0xff
47                mov dl,(%1 >> 8) & 0xff
48                int 0x21
49%if (%1 >> 16) & 0xff
50                mov dl,(%1 >> 16) & 0xff
51                int 0x21
52%if (%1 >> 24) & 0xff
53                mov dl,(%1 >> 24) & 0xff
54                int 0x21
55%endif
56%endif
57%endif
58                mov dl,' '
59                int 0x21
60%endmacro
61%macro SHOWD 1.nolist
62                mov al,%1
63                call print_dec
64                mov ah,0x02
65                mov dl,' '
66                int 0x21
67%endmacro
68%macro SHOWX 1.nolist
69                mov bx,%1
70                call print_hex
71                mov ah,0x02
72                mov dl,' '
73                int 0x21
74%endmacro
75%else
76%macro MARK 1.nolist
77%endmacro
78%macro SHOWD 1.nolist
79%endmacro
80%macro SHOWX 1.nolist
81%endmacro
82%endif
83
84_start:
85                MARK 'INIT'
86
87; There should be exactly one command-line argument, which is of the form
88; [[ipaddress]::]tftp_filename, just like filenames given to PXELINUX.
89; Too few or too many arguments is an error.
90;
91; This code is based on mangle_name in pxelinux.asm
92parse_args:
93                cld
94                xor cx,cx
95                mov cl,[pspCmdLen]
96                dec cx
97                mov si,pspCmdArg+1
98                and cx,cx
99                je near usage           ; no args is bad
100                add si,cx
101                dec si
102                std
103.chomp:         lodsb
104                cmp al,' '
105                loopz .chomp
106                inc cx
107                cld
108                mov [pspCmdLen],cl
109                mov si,pspCmdArg+1
110                cmp word [si],'::'      ; Leading ::?
111                je near gotprefix
112                dec cx
113                jz noip
114                MARK 'SCAN'
115
116.more:
117                inc si
118                cmp byte [si],' '
119                je near usage
120                cmp word [si],'::'
121                je near parse_ip
122                loop .more
123
124noip:
125                MARK 'NOIP'
126                mov ax,0x0e             ; get config file name
127                int 0x22
128                mov si,bx
129%ifdef DEBUG
130                mov ah,0x02
131                mov dl,'['
132                int 0x21
133                mov ax,0x02
134                int 0x22
135                mov ah,0x02
136                mov dl,']'
137                int 0x21
138                mov dl,' '
139                int 0x21
140%endif
141                push ds
142                push es
143                pop ds
144                pop es
145                push es
146.find_prefix:
147                lodsb
148                and al,al
149                jnz .find_prefix
150                dec si
151
152                mov cx,si
153                sub cx,bx
154                MARK 'LEN'
155                SHOWD cl                ; assume it's <256 for debugging
156                dec si
157                std
158.find_slash:
159                lodsb
160                cmp al,'/'
161                je .slash
162                loop .find_slash
163.slash:
164                cmp cx,127
165                cld
166                jna .copy_prefix
167                pop ds
168                jmp too_long
169
170.copy_prefix:
171                SHOWD cl
172                MARK 'PFX'
173                mov si,bx
174                mov di,tftp_filename
175                mov bx,128
176                sub bx,cx
177                rep movsb
178                pop ds
179
180                mov cl,[pspCmdLen]
181                mov si,pspCmdArg+1
182                jmp prefix_done
183
184usage:
185                xor cx,cx
186                mov si,msg_usage
187                jmp fail
188
189too_long:
190                xor cx,cx
191                mov si,msg_too_long
192                jmp fail
193
194parse_ip:
195                MARK 'PIP'
196                mov di,si
197                mov si,pspCmdArg+1
198                call parse_dotquad
199                jc .notdq
200                cmp si,di               ; is it the same place?
201                jne .notdq
202                mov [tftp_siaddr],eax
203                jmp gotprefix
204.notdq:
205                MARK 'NDQ'
206                mov si,di
207                mov bx,pspCmdArg+1
208                mov ax,0x0010           ; DNS resolve
209                int 0x22
210                and eax,eax
211                jz noip
212                mov [tftp_siaddr],eax
213gotprefix:
214                MARK 'GOTP'
215                dec cx                  ; skip the ::
216                dec cx
217                inc si
218                inc si
219                mov di,tftp_filename
220                mov bx,128
221
222prefix_done:
223                SHOWD bl
224                MARK 'LEFT'
225
226; SI points at the filename, plus remaining arguments,
227; CX contains their combined length.
228; DI points to where the filename should be stored
229; BX says how much space is left for the filename and NUL
230
231                and cx,cx
232                jz usage                ; no args is bad
233.copy_filename:
234                lodsb
235%ifdef DEBUG
236                mov dl,al
237                mov ah,0x2
238                int 0x21
239%endif
240                cmp al,' '
241                je usage
242                dec bx
243                jz too_long
244                stosb
245                loop .copy_filename
246                xor eax,eax
247                stosb
248
249; get PXE cached data
250                MARK 'GCI'
251                mov ax,0x0009           ; call PXE stack
252                mov bx,0x0071           ; PXENV_GET_CACHED_INFO
253                mov di,PXECacheParms
254                int 0x22
255                and eax,eax
256                jz .fix_siaddr
257                mov cx,[gci_status]
258                mov si,msg_get_cache
259                jmp fail
260
261.fix_siaddr:
262                mov bx,[gci_bufferseg]
263                mov es,bx
264                mov bx,[gci_buffer]
265                mov eax,[es:bx+12]      ; save our address (ciaddr)
266                mov [open_ciaddr],eax   ; ... in case we have to do UDP open
267                mov eax,[tftp_siaddr]
268                and eax,eax
269                jnz .replace_addr
270                MARK 'ADDR'
271                mov eax,[es:bx+20]      ; siaddr
272                mov [tftp_siaddr],eax
273                jmp .addr_done
274.replace_addr:
275                mov [es:bx+20],eax
276.addr_done:
277                mov si,tftp_filename    ; copy the new filename...
278                lea di,[es:bx+108]      ; to the "cached DHCP response"
279                mov cx,128
280                rep movsb
281                mov bx,ds               ; restore es before proceeding
282                mov es,bx
283
284; print out what we are doing
285%ifdef DEBUG
286                mov ah,0x02             ; write character
287                mov dl,0x0d             ; print a CRLF first
288                int 0x21
289                mov dl,0x0a
290                int 0x21
291%endif
292                mov ax,0x0002           ; write string
293                mov bx,msg_booting
294                int 0x22
295                mov ebx,[tftp_siaddr]
296                call print_dotquad
297                mov ah,0x02             ; write character
298                mov dl,' '
299                int 0x21
300                mov ax,0x0002           ; write string
301                mov bx,tftp_filename
302                int 0x22
303                mov ah,0x02             ; write character
304                mov dl,0x0d
305                int 0x21
306                mov dl,0x0a
307                int 0x21
308
309%ifndef NO_RUN
310                mov ax,0x0009           ; call PXE stack
311                mov bx,0x0031           ; PXENV_UDP_CLOSE
312                mov di,PXECloseParms
313                int 0x22
314                mov cx,[close_status]
315                mov si,msg_udp_close
316                and ax,ax
317                jnz fail
318
319                mov ax,0x0009           ; call PXE stack
320                mov bx,0x0073           ; PXENV_RESTART_TFTP
321                mov di,PXERestartTFTPParms
322                int 0x22
323                mov cx,[tftp_status]
324                mov si,msg_rst_tftp
325                call fail
326
327                mov ax,0x0009           ; call PXE stack
328                mov bx,0x0030           ; PXENV_UDP_OPEN
329                mov di,PXEOpenParms
330                int 0x22
331                mov cx,[open_status]
332                mov si,msg_udp_open
333                and ax,ax
334                jnz fail
335                ret
336%endif
337
338fail:
339                MARK 'FAIL'
340                SHOWX cs
341                SHOWX ds
342                SHOWX es
343                SHOWX si
344%ifdef DEBUG
345                mov ah,0x02             ; write character
346                mov dl,0x0d             ; print a CRLF first
347                int 0x21
348                mov dl,0x0a
349                int 0x21
350%endif
351                mov ax,0x0002           ; write string
352                mov bx,msg_progname     ; print our name
353                int 0x22
354                mov bx,si               ; ... the error message
355                int 0x22
356                mov ah,0x02             ; write character
357                jcxz .done
358                mov dl,' '              ; ... and the error code, in []
359                int 0x21
360                mov dl,'['
361                int 0x21
362                mov bx,cx
363                call print_hex
364                mov ah,0x02             ; write character
365                mov dl,']'
366                int 0x21
367.done:
368                mov dl,0x0d             ; and finally a CRLF
369                int 0x21
370                mov dl,0x0a
371                int 0x21
372                ret
373
374
375; print_hex
376;
377; Take a 16-bit integer in BX and print it as 2 hex digits.
378; Destroys AX and DL.
379;
380print_hex:
381                mov al,bh
382                aam 16
383                cmp ah,10
384                jb .lt_a000
385                add ah,'A'-'0'-10
386.lt_a000:       add ah,'0'
387                mov dl,ah
388                mov ah,0x02             ; write character
389                int 0x21
390
391                cmp al,10
392                jb .lt_a00
393                add al,'A'-'0'-10
394.lt_a00:        add al,'0'
395                mov dl,al
396                mov ah,0x02             ; write character
397                int 0x21
398
399                mov al,bl
400                aam 16
401                cmp ah,10
402                jb .lt_a0
403                add ah,'A'-'0'-10
404.lt_a0:         add ah,'0'
405                mov dl,ah
406                mov ah,0x02             ; write character
407                int 0x21
408
409                cmp al,10
410                jb .lt_a
411                add al,'A'-'0'-10
412.lt_a:          add al,'0'
413                mov dl,al
414                mov ah,0x02             ; write character
415                int 0x21
416                ret
417
418
419; print_dec
420;
421; Take an 8-bit integer in AL and print it in decimal.
422; Destroys AX and DL.
423;
424print_dec:
425                cmp al,10               ; < 10?
426                jb .lt10                ; If so, skip first 2 digits
427
428                cmp al,100              ; < 100
429                jb .lt100               ; If so, skip first digit
430
431                aam 100
432                ; Now AH = 100-digit; AL = remainder
433                add ah,'0'
434                mov dl,ah
435                mov ah,0x02
436                int 0x21
437
438.lt100:
439                aam 10
440                ; Now AH = 10-digit; AL = remainder
441                add ah,'0'
442                mov dl,ah
443                mov ah,0x02
444                int 0x21
445
446.lt10:
447                add al,'0'
448                mov dl,al
449                mov ah,0x02
450                int 0x21
451                ret
452
453
454; print_dotquad
455;
456; Take an IP address (in network byte order) in EBX and print it
457; as a dotted quad.
458; Destroys EAX, EBX, ECX, EDX
459;
460print_dotquad:
461                mov cx,3
462.octet:
463                mov al,bl
464                call print_dec
465                jcxz .done
466                mov ah,0x02
467                mov dl,'.'
468                int 0x21
469                ror ebx,8       ; Move next char into LSB
470                dec cx
471                jmp .octet
472.done:
473                ret
474
475
476; parse_dotquad:
477;               Read a dot-quad pathname in DS:SI and output an IP
478;               address in EAX, with SI pointing to the first
479;               nonmatching character.
480;
481;               Return CF=1 on error.
482;
483;               No segment assumptions permitted.
484;
485parse_dotquad:
486                push cx
487                mov cx,4
488                xor eax,eax
489.parseloop:
490                mov ch,ah
491                mov ah,al
492                lodsb
493                sub al,'0'
494                jb .notnumeric
495                cmp al,9
496                ja .notnumeric
497                aad                             ; AL += 10 * AH; AH = 0;
498                xchg ah,ch
499                jmp .parseloop
500.notnumeric:
501                cmp al,'.'-'0'
502                pushf
503                mov al,ah
504                mov ah,ch
505                xor ch,ch
506                ror eax,8
507                popf
508                jne .error
509                loop .parseloop
510                jmp .done
511.error:
512                loop .realerror                 ; If CX := 1 then we're done
513                clc
514                jmp .done
515.realerror:
516                stc
517.done:
518                dec si                          ; CF unchanged!
519                pop cx
520                ret
521
522                section .data
523msg_booting:    db 'TFTP boot: ',0
524msg_progname:   db 'pxechain: ',0
525msg_usage:      db 'usage: pxechain.cbt [[ipaddress]::]filename',0dh,0ah,0
526msg_too_long:   db 'pxechain: filename is too long (max 127)',0dh,0ah,0
527msg_get_cache:  db 'PXENV_GET_CACHED_INFO',0
528msg_rst_tftp:   db 'PXENV_RESTART_TFTP',0
529msg_udp_close:  db 'PXENV_UDP_CLOSE',0
530msg_udp_open:   db 'PXENV_UDP_OPEN',0
531
532PXECacheParms:
533gci_status:     dw 0
534gci_packettype: dw 3                    ; PXENV_PACKET_TYPE_CACHED_REPLY
535gci_buffersize: dw 0
536gci_buffer:     dw 0
537gci_bufferseg:  dw 0
538gci_bufferlim:  dw 0
539
540PXERestartTFTPParms:
541tftp_status:    dw 0
542tftp_filename:  times 128 db 0
543tftp_bufsize:   dd 0x00090000           ; available memory for NBP
544tftp_bufaddr:   dd 0x00007c00           ; PXE NBP load address
545tftp_siaddr:    dd 0
546tftp_giaddr:    dd 0
547tftp_mcaddr:    dd 0
548tftp_mcport:    dw 0
549tftp_msport:    dw 0
550tftp_timeout:   dw 0
551tftp_reopendly: dw 0
552
553PXECloseParms:
554close_status:   dw 0
555
556PXEOpenParms:
557open_status:    dw 0
558open_ciaddr:    dd 0
Note: See TracBrowser for help on using the browser.