gitee.com/mirrors_u-root/u-root@v7.0.0+incompatible/pkg/boot/netboot/pxe/pxe.go (about)

     1  // Copyright 2017-2018 the u-root Authors. All rights reserved
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package pxe implements the PXE config file parsing.
     6  //
     7  // See http://www.pix.net/software/pxeboot/archive/pxespec.pdf
     8  package pxe
     9  
    10  import (
    11  	"context"
    12  	"encoding/hex"
    13  	"fmt"
    14  	"net"
    15  	"net/url"
    16  	"path"
    17  	"strings"
    18  
    19  	"github.com/u-root/u-root/pkg/boot"
    20  	"github.com/u-root/u-root/pkg/boot/syslinux"
    21  	"github.com/u-root/u-root/pkg/curl"
    22  )
    23  
    24  // ParseConfig probes for config files based on the Mac and IP given
    25  // and uses s to fetch files.
    26  func ParseConfig(ctx context.Context, workingDir *url.URL, mac net.HardwareAddr, ip net.IP, s curl.Schemes) ([]boot.OSImage, error) {
    27  	rootDir := *workingDir
    28  	rootDir.Path = ""
    29  
    30  	for _, relname := range probeFiles(mac, ip) {
    31  		// "When booting, the initial working directory for PXELINUX
    32  		// will be the parent directory of pxelinux.0 unless overridden
    33  		// with DHCP option 210."
    34  		//
    35  		// https://wiki.syslinux.org/wiki/index.php?title=Config#Working_directory
    36  		imgs, err := syslinux.ParseConfigFile(ctx, s, path.Join("pxelinux.cfg", relname), &rootDir, workingDir.Path)
    37  		if curl.IsURLError(err) {
    38  			// We didn't find the file.
    39  			// TODO(hugelgupf): log this.
    40  			continue
    41  		}
    42  		return imgs, err
    43  	}
    44  	return nil, fmt.Errorf("no valid pxelinux config found")
    45  }
    46  
    47  func probeFiles(ethernetMac net.HardwareAddr, ip net.IP) []string {
    48  	files := make([]string, 0, 10)
    49  	// Skipping client UUID. Figure that out later.
    50  
    51  	// MAC address.
    52  	files = append(files, fmt.Sprintf("01-%s", strings.ToLower(strings.Replace(ethernetMac.String(), ":", "-", -1))))
    53  
    54  	// IP address in upper case hex, chopping one letter off at a time.
    55  	if ip != nil {
    56  		ipf := strings.ToUpper(hex.EncodeToString(ip))
    57  		for n := len(ipf); n >= 1; n-- {
    58  			files = append(files, ipf[:n])
    59  		}
    60  	}
    61  	files = append(files, "default")
    62  	return files
    63  }