1. uboot dhcp's issue analysis
pxa2128-eth Waiting for PHY auto negotiation to complete. done
pxa2128-eth: link up, 100 Mb/s, full duplex
BOOTP broadcast 1
DHCP client bound to address 10.66.130.251
Using pxa2128-eth device
TFTP from server 10.66.130.4; our IP address is 10.66.130.251
Filename 'pxelinux.0'.
Load address: 0x1100000
Loading: #
done
Bytes transferred = 14146 (3742 hex)
Automatic boot of image at addr 0x01100000 ...
Wrong Image Format for dhcp command
ERROR: can't get kernel image!
#if defined(CONFIG_CMD_DHCP)
int do_dhcp (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
return netboot_common(DHCP, cmdtp, argc, argv);
}
U_BOOT_CMD(
dhcp, 3, 1, do_dhcp,
"boot image via network using DHCP/TFTP protocol",
"[loadAddress] [[hostIPaddr:]bootfilename]"
);
#endif
static int
netboot_common (proto_t proto, cmd_tbl_t *cmdtp, int argc, char * const argv[])
{
char *s;
char *end;
int rcode = 0;
int size;
ulong addr;
/* pre-set load_addr */
if ((s = getenv("loadaddr")) != NULL) {
load_addr = simple_strtoul(s, NULL, 16);
}
switch (argc) {
case 1:
break;
case 2: /*
* Only one arg - accept two forms:
* Just load address, or just boot file name. The latter
* form must be written in a format which can not be
* mis-interpreted as a valid number.
*/
addr = simple_strtoul(argv[1], &end, 16);
if (end == (argv[1] + strlen(argv[1])))
load_addr = addr;
else
copy_filename(BootFile, argv[1], sizeof(BootFile));
break;
case 3: load_addr = simple_strtoul(argv[1], NULL, 16); // argc is 3. so this is point.
copy_filename (BootFile, argv[2], sizeof(BootFile));
break;
default:
show_boot_progress (-80);
return cmd_usage(cmdtp);
}
show_boot_progress (80);
if ((size = NetLoop(proto)) < 0) { // This function is important!
show_boot_progress (-81);
return 1;
}
show_boot_progress (81);
/* NetLoop ok, update environment */
netboot_update_env(); // update the env related to net device.
/* done if no file was loaded (no errors though) */
if (size == 0) {
show_boot_progress (-82);
return 0;
}
/* flush cache */
flush_cache(load_addr, size);
show_boot_progress(82);
rcode = bootm_maybe_autostart(cmdtp, argv[0]);
if (rcode < 0)
show_boot_progress (-83);
else
show_boot_progress (84);
return rcode;
}
Coming into NetLoop, we focus on DHCP:(net.c)
#if defined(CONFIG_CMD_DHCP)
case DHCP:
BootpTry = 0;
NetOurIP = 0;
DhcpRequest(); /* Basically same as BOOTP */
break;
#endif
Now we come into bootp.c, and the function would send out DHCP request using broadcast.
/*
* Handle DHCP received packets.
*/
static void
DhcpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
unsigned len)
{
Bootp_t *bp = (Bootp_t *)pkt;
debug("DHCPHandler: got packet: (src=%d, dst=%d, len=%d) state: %d\n",
src, dest, len, dhcp_state);
if (BootpCheckPkt(pkt, dest, src, len)) /* Filter out pkts we don't want */
return;
debug("DHCPHandler: got DHCP packet: (src=%d, dst=%d, len=%d) state: %d\n",
src, dest, len, dhcp_state);
switch (dhcp_state) {
case SELECTING:
/*
* Wait an appropriate time for any potential DHCPOFFER packets
* to arrive. Then select one, and generate DHCPREQUEST response.
* If filename is in format we recognize, assume it is a valid
* OFFER from a server we want.
*/
debug("DHCP: state=SELECTING bp_file: \"%s\"\n", bp->bp_file);
#ifdef CONFIG_SYS_BOOTFILE_PREFIX
if (strncmp(bp->bp_file,
CONFIG_SYS_BOOTFILE_PREFIX,
strlen(CONFIG_SYS_BOOTFILE_PREFIX)) == 0 ) {
#endif /* CONFIG_SYS_BOOTFILE_PREFIX */
debug("TRANSITIONING TO REQUESTING STATE\n");
dhcp_state = REQUESTING;
if (NetReadLong((ulong*)&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC))
DhcpOptionsProcess((u8 *)&bp->bp_vend[4], bp);
NetSetTimeout(TIMEOUT, BootpTimeout);
DhcpSendRequestPkt(bp);
#ifdef CONFIG_SYS_BOOTFILE_PREFIX
}
#endif /* CONFIG_SYS_BOOTFILE_PREFIX */
return;
break;
case REQUESTING:
debug("DHCP State: REQUESTING\n");
if ( DhcpMessageType((u8 *)bp->bp_vend) == DHCP_ACK ) {
if (NetReadLong((ulong*)&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC))
DhcpOptionsProcess((u8 *)&bp->bp_vend[4], bp);
BootpCopyNetParams(bp); /* Store net params from reply */
dhcp_state = BOUND;
printf ("DHCP client bound to address %pI4\n", &NetOurIP);
auto_load();
return;
}
break;
case BOUND:
/* DHCP client bound to address */
break;
default:
puts ("DHCP: INVALID STATE\n");
break;
}
}
The function
BootpCopyNetParams would handle bootfile and serverip, sometimes issue would be happened here!
/*
* Copy parameters of interest from BOOTP_REPLY/DHCP_OFFER packet
*/
static void BootpCopyNetParams(Bootp_t *bp)
{
IPaddr_t tmp_ip;
NetCopyIP(&NetOurIP, &bp->bp_yiaddr);
#if !defined(CONFIG_BOOTP_SERVERIP)
NetCopyIP(&tmp_ip, &bp->bp_siaddr);
if (tmp_ip != 0)
NetCopyIP(&NetServerIP, &bp->bp_siaddr);
memcpy (NetServerEther, ((Ethernet_t *)NetRxPacket)->et_src, 6);
#endif
if (strlen(bp->bp_file) > 0 && !BootFile[0]) // If BootFile has no data, then copy
copy_filename (BootFile, bp->bp_file, sizeof(BootFile));
debug("Bootfile: %s\n", BootFile);
/* Propagate to environment:
* don't delete exising entry when BOOTP / DHCP reply does
* not contain a new value
*/
if (*BootFile) {
setenv ("bootfile", BootFile);
}
}
Then make tftp serverip as serverip, not dhcp server ip!
2. Capturing with tcpdump for viewing with Wireshark
D.3. tcpdump: Capturing with tcpdump for viewing with Wireshark
There are occasions when you want to capture packets using tcpdump rather than wireshark, especially when you want to do a remote capture and do not want the network load associated with running Wireshark remotely (not to mention all the X traffic polluting your capture).
However, the default tcpdump parameters result in a capture file where each packet is truncated, because most versions of tcpdump, will, by default, only capture the first 68 or 96 bytes of each packet.
To ensure that you capture complete packets, use the following command:
tcpdump -i <interface> -s 65535 -w <some-file>
You will have to specify the correct interface and the name of a file to save into. In addition, you will have to terminate the capture with ^C when you believe you have captured enough packets.
Note! | |
---|---|
tcpdump is not part of the Wireshark distribution. You can get it from: http://www.tcpdump.org for various platforms. |