Name update
This commit is contained in:
@@ -56,11 +56,17 @@ pub fn decide(ctx: &ReplyContext<'_>) -> BootDirective {
|
||||
// it'll then do the same script-fetch the iPXE path does.
|
||||
let name = ctx.arch.ipxe_bootfile().unwrap_or("snponly.efi");
|
||||
BootDirective::HttpScript {
|
||||
url: format!("{}/ipxe/{}", ctx.public_base_url.trim_end_matches('/'), name),
|
||||
url: format!(
|
||||
"{}/ipxe/{}",
|
||||
ctx.public_base_url.trim_end_matches('/'),
|
||||
name
|
||||
),
|
||||
}
|
||||
}
|
||||
FirmwareClass::PxeClient => match ctx.arch.ipxe_bootfile() {
|
||||
Some(name) => BootDirective::TftpIpxe { filename: name.to_string() },
|
||||
Some(name) => BootDirective::TftpIpxe {
|
||||
filename: name.to_string(),
|
||||
},
|
||||
None => BootDirective::Ignore,
|
||||
},
|
||||
FirmwareClass::Other => BootDirective::Ignore,
|
||||
@@ -107,12 +113,16 @@ pub fn build_reply(ctx: &ReplyContext<'_>, directive: &BootDirective) -> Option<
|
||||
|
||||
match directive {
|
||||
BootDirective::TftpIpxe { filename } => {
|
||||
opts.insert(DhcpOption::TFTPServerName(ctx.our_ip.to_string().into_bytes()));
|
||||
opts.insert(DhcpOption::TFTPServerName(
|
||||
ctx.our_ip.to_string().into_bytes(),
|
||||
));
|
||||
opts.insert(DhcpOption::BootfileName(filename.as_bytes().to_vec()));
|
||||
}
|
||||
BootDirective::HttpScript { url } => {
|
||||
opts.insert(DhcpOption::BootfileName(url.as_bytes().to_vec()));
|
||||
opts.insert(DhcpOption::TFTPServerName(ctx.our_ip.to_string().into_bytes()));
|
||||
opts.insert(DhcpOption::TFTPServerName(
|
||||
ctx.our_ip.to_string().into_bytes(),
|
||||
));
|
||||
}
|
||||
BootDirective::Ignore => return None,
|
||||
}
|
||||
|
||||
@@ -4,9 +4,7 @@
|
||||
use crate::reply::{build_reply, decide, BootDirective, ReplyContext};
|
||||
use dhcproto::v4::{DhcpOption, Message, OptionCode};
|
||||
use dhcproto::{Decodable, Decoder, Encodable, Encoder};
|
||||
use openpxe_core::{
|
||||
ClientArch, ClientEvent, ClientRegistry, FirmwareClass,
|
||||
};
|
||||
use openpxe_core::{ClientArch, ClientEvent, ClientRegistry, FirmwareClass};
|
||||
use socket2::{Domain, Protocol, Socket, Type};
|
||||
use std::net::{IpAddr, Ipv4Addr, SocketAddr, SocketAddrV4};
|
||||
use std::sync::Arc;
|
||||
@@ -86,11 +84,22 @@ impl DhcpProxyServer {
|
||||
) -> anyhow::Result<()> {
|
||||
let request = Message::decode(&mut Decoder::new(data))?;
|
||||
|
||||
let vendor_class = request.opts().get(OptionCode::ClassIdentifier).and_then(|o| {
|
||||
if let DhcpOption::ClassIdentifier(v) = o { Some(v.as_slice()) } else { None }
|
||||
});
|
||||
let vendor_class = request
|
||||
.opts()
|
||||
.get(OptionCode::ClassIdentifier)
|
||||
.and_then(|o| {
|
||||
if let DhcpOption::ClassIdentifier(v) = o {
|
||||
Some(v.as_slice())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
let user_class = request.opts().get(OptionCode::UserClass).and_then(|o| {
|
||||
if let DhcpOption::UserClass(v) = o { Some(v.as_slice()) } else { None }
|
||||
if let DhcpOption::UserClass(v) = o {
|
||||
Some(v.as_slice())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
let class = FirmwareClass::classify(vendor_class, user_class);
|
||||
if matches!(class, FirmwareClass::Other) {
|
||||
@@ -135,7 +144,9 @@ impl DhcpProxyServer {
|
||||
}
|
||||
self.metrics.record_dhcp_reply(arch.as_str());
|
||||
|
||||
let Some(reply) = build_reply(&ctx, &directive) else { return Ok(()); };
|
||||
let Some(reply) = build_reply(&ctx, &directive) else {
|
||||
return Ok(());
|
||||
};
|
||||
let mut out = Vec::with_capacity(512);
|
||||
reply.encode(&mut Encoder::new(&mut out))?;
|
||||
|
||||
@@ -203,7 +214,10 @@ fn bind_udp(bind: IpAddr, port: u16, broadcast: bool) -> anyhow::Result<UdpSocke
|
||||
|
||||
fn format_mac(chaddr: &[u8]) -> String {
|
||||
let take = chaddr.iter().take(6).copied().collect::<Vec<_>>();
|
||||
take.iter().map(|b| format!("{b:02x}")).collect::<Vec<_>>().join(":")
|
||||
take.iter()
|
||||
.map(|b| format!("{b:02x}"))
|
||||
.collect::<Vec<_>>()
|
||||
.join(":")
|
||||
}
|
||||
|
||||
/// Walk raw DHCP options looking for option 93 (Client System Architecture)
|
||||
@@ -217,10 +231,17 @@ fn extract_raw_arch(packet: &[u8]) -> Option<u16> {
|
||||
let mut i = 0;
|
||||
while i < opts.len() {
|
||||
let code = opts[i];
|
||||
if code == 0xff { return None; } // END
|
||||
if code == 0x00 { i += 1; continue; } // PAD
|
||||
if code == 0xff {
|
||||
return None;
|
||||
} // END
|
||||
if code == 0x00 {
|
||||
i += 1;
|
||||
continue;
|
||||
} // PAD
|
||||
i += 1;
|
||||
if i >= opts.len() { return None; }
|
||||
if i >= opts.len() {
|
||||
return None;
|
||||
}
|
||||
let len = opts[i] as usize;
|
||||
i += 1;
|
||||
if code == 93 && len >= 2 && i + 2 <= opts.len() {
|
||||
@@ -240,7 +261,7 @@ mod tests {
|
||||
// Minimal BOOTP header + magic cookie + option 93 (arch)=0x0007 + END.
|
||||
let mut pkt = vec![0u8; 240];
|
||||
pkt[236..240].copy_from_slice(&[99, 130, 83, 99]); // magic cookie
|
||||
pkt.extend_from_slice(&[53, 1, 1]); // option 53 DHCPDISCOVER
|
||||
pkt.extend_from_slice(&[53, 1, 1]); // option 53 DHCPDISCOVER
|
||||
pkt.extend_from_slice(&[93, 2, 0x00, 0x07]);
|
||||
pkt.push(0xff);
|
||||
assert_eq!(extract_raw_arch(&pkt), Some(0x0007));
|
||||
|
||||
Reference in New Issue
Block a user