@@ -130,6 +130,18 @@ of_open(struct boot_file_t* file,
return FILE_ERR_OK;
}
+static char *ipv4_to_str(__u32 ip)
+{
+ char *buf = malloc(sizeof("000.000.000.000"));
+
+ sprintf(buf,"%u.%u.%u.%u",
+ (ip & 0xff000000) >> 24,
+ (ip & 0x00ff0000) >> 16,
+ (ip & 0x0000ff00) >> 8,
+ (ip & 0x000000ff));
+ return buf;
+}
+
static int
of_net_open(struct boot_file_t* file,
struct partition_t* part, struct boot_fspec_t* fspec)
@@ -137,10 +149,42 @@ of_net_open(struct boot_file_t* file,
static char buffer[1024];
char *filename = NULL;
char *p;
+ struct bootp_packet *packet;
+ int real_tftp;
DEBUG_ENTER;
DEBUG_OPEN;
+ /* If /packages/cas exists the we have a "new skool" tftp */
+ real_tftp = (prom_finddevice("/packages/cas") != PROM_INVALID_HANDLE);
+ DEBUG_F("real_tftp == %x\n", real_tftp);
+
+ /* Check to see if we can get the [scyg]iaddr fields from netinfo */
+ packet = prom_get_netinfo();
+ if (packet != NULL) {
+ DEBUG_F("we have a boot packet\n");
+ DEBUG_F(" siaddr = <%x>\n", packet->siaddr);
+ DEBUG_F(" ciaddr = <%x>\n", packet->ciaddr);
+ DEBUG_F(" yiaddr = <%x>\n", packet->yiaddr);
+ DEBUG_F(" giaddr = <%x>\n", packet->giaddr);
+
+ if (fspec->siaddr == NULL && packet->siaddr != 0)
+ fspec->siaddr = ipv4_to_str(packet->siaddr);
+ if (fspec->ciaddr == NULL && packet->ciaddr != 0)
+ fspec->ciaddr = ipv4_to_str(packet->ciaddr);
+ if (fspec->giaddr == NULL && packet->giaddr != 0)
+ fspec->giaddr = ipv4_to_str(packet->giaddr);
+ }
+
+ /* FIXME: Yck! if we /still/ do not have a gateway then "cheat" and use
+ * the server. This will be okay if the client and server are on
+ * the same IP network, if not then lets hope the server does ICMP
+ * redirections */
+ if (fspec->giaddr == NULL) {
+ fspec->giaddr = ipv4_to_str(packet->siaddr);
+ DEBUG_F("Forcing giaddr to siaddr <%s>\n", fspec->giaddr);
+ }
+
if (fspec->file && strlen(fspec->file)) {
filename = strdup(fspec->file);
for (p = filename; *p; p++)
@@ -153,6 +197,10 @@ of_net_open(struct boot_file_t* file,
strncpy(buffer, fspec->dev, 768);
if (fspec->is_ipv6)
strcat(buffer, TOK_IPV6 ",");
+
+ /* If we didn't get a ':' include one */
+ if (fspec->dev[strlen(fspec->dev)-1] != ':')
+ strcat(buffer, ":");
strcat(buffer, fspec->siaddr);
strcat(buffer, ",");
if (fspec->is_ipv6 && (strstr(filename, "filename=") == NULL))
@@ -162,12 +210,15 @@ of_net_open(struct boot_file_t* file,
strcat(buffer, fspec->ciaddr);
strcat(buffer, ",");
strcat(buffer, fspec->giaddr);
- strcat(buffer, ",");
- strcat(buffer, fspec->bootp_retries);
- strcat(buffer, ",");
- strcat(buffer, fspec->tftp_retries);
- strcat(buffer, ",");
- strcat(buffer, fspec->addl_params);
+
+ if (real_tftp) {
+ strcat(buffer, ",");
+ strcat(buffer, fspec->bootp_retries);
+ strcat(buffer, ",");
+ strcat(buffer, fspec->tftp_retries);
+ strcat(buffer, ",");
+ strcat(buffer, fspec->addl_params);
+ }
DEBUG_F("Opening: \"%s\"\n", buffer);