github.com/xyproto/u-root@v6.0.1-0.20200302025726-5528e0c77a3c+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  	"encoding/hex"
    12  	"fmt"
    13  	"net"
    14  	"net/url"
    15  	"path"
    16  	"strings"
    17  
    18  	"github.com/u-root/u-root/pkg/boot/syslinux"
    19  	"github.com/u-root/u-root/pkg/curl"
    20  )
    21  
    22  // ParseConfig probes for config files based on the Mac and IP given.
    23  func ParseConfig(workingDir *url.URL, mac net.HardwareAddr, ip net.IP) (*syslinux.Config, error) {
    24  	return ParseConfigWithSchemes(workingDir, mac, ip, curl.DefaultSchemes)
    25  }
    26  
    27  // ParseConfigWithSchemes probes for config files based on the Mac and IP given
    28  // and uses s to fetch files.
    29  func ParseConfigWithSchemes(workingDir *url.URL, mac net.HardwareAddr, ip net.IP, s curl.Schemes) (*syslinux.Config, error) {
    30  	for _, relname := range probeFiles(mac, ip) {
    31  		c, err := syslinux.ParseConfigFileWithSchemes(s, path.Join("pxelinux.cfg", relname), workingDir)
    32  		if curl.IsURLError(err) {
    33  			// We didn't find the file.
    34  			// TODO(hugelgupf): log this.
    35  			continue
    36  		}
    37  		return c, err
    38  	}
    39  	return nil, fmt.Errorf("no valid pxelinux config found")
    40  }
    41  
    42  func probeFiles(ethernetMac net.HardwareAddr, ip net.IP) []string {
    43  	files := make([]string, 0, 10)
    44  	// Skipping client UUID. Figure that out later.
    45  
    46  	// MAC address.
    47  	files = append(files, fmt.Sprintf("01-%s", strings.ToLower(strings.Replace(ethernetMac.String(), ":", "-", -1))))
    48  
    49  	// IP address in upper case hex, chopping one letter off at a time.
    50  	if ip != nil {
    51  		ipf := strings.ToUpper(hex.EncodeToString(ip))
    52  		for n := len(ipf); n >= 1; n-- {
    53  			files = append(files, ipf[:n])
    54  		}
    55  	}
    56  	files = append(files, "default")
    57  	return files
    58  }