1 /******************************************************************************
2 * Copyright (c) 2004, 2008 IBM Corporation
4 * This program and the accompanying materials
5 * are made available under the terms of the BSD License
6 * which accompanies this distribution, and is available at
7 * http://www.opensource.org/licenses/bsd-license.php
10 * IBM Corporation - initial implementation
11 *****************************************************************************/
13 #include <netlib/tftp.h>
14 #include <netlib/ethernet.h>
15 #include <netlib/dhcp.h>
16 #include <netlib/dhcpv6.h>
17 #include <netlib/ipv4.h>
18 #include <netlib/ipv6.h>
19 #include <netlib/dns.h>
24 #include <sys/socket.h>
25 #include <netapps/args.h>
26 #include <libbootmsg/libbootmsg.h>
30 #define IP_INIT_DEFAULT 5
31 #define IP_INIT_NONE 0
32 #define IP_INIT_BOOTP 1
33 #define IP_INIT_DHCP 2
34 #define IP_INIT_DHCPV6_STATELESS 3
35 #define IP_INIT_IPV6_MANUAL 4
37 #define DEFAULT_BOOT_RETRIES 10
38 #define DEFAULT_TFTP_RETRIES 20
39 static int ip_version = 4;
56 * Parses a argument string for IPv6 booting, extracts all
57 * parameters and fills a structure accordingly
59 * @param arg_str string with arguments, separated with ','
60 * @param argc number of arguments
61 * @param obp_tftp_args structure which contains the result
62 * @return updated arg_str
65 parse_ipv6args (const char *arg_str, unsigned int argc,
66 obp_tftp_args_t *obp_tftp_args)
73 memset(&obp_tftp_args->si6addr.addr, 0, 16);
75 argncpy(arg_str, 0, arg_buf, 100);
76 if(str_to_ipv6(arg_buf, (uint8_t *) &(obp_tftp_args->si6addr.addr[0]))) {
77 arg_str = get_arg_ptr(arg_str, 1);
80 else if(arg_buf[0] == 0) {
81 memset(&obp_tftp_args->si6addr.addr, 0, 16);
82 arg_str = get_arg_ptr(arg_str, 1);
86 memset(&obp_tftp_args->si6addr.addr, 0, 16);
91 obp_tftp_args->filename[0] = 0;
93 argncpy(arg_str, 0, obp_tftp_args->filename, 100);
94 for(ptr = obp_tftp_args->filename; *ptr != 0; ++ptr)
98 arg_str = get_arg_ptr(arg_str, 1);
104 memset(&obp_tftp_args->ci6addr, 0, 16);
106 argncpy(arg_str, 0, arg_buf, 100);
107 if (str_to_ipv6(arg_buf, (uint8_t *) &(obp_tftp_args->ci6addr.addr[0]))) {
108 arg_str = get_arg_ptr(arg_str, 1);
111 else if(arg_buf[0] == 0) {
112 memset(&obp_tftp_args->ci6addr.addr, 0, 16);
113 arg_str = get_arg_ptr(arg_str, 1);
117 memset(&obp_tftp_args->ci6addr.addr, 0, 16);
122 memset(&obp_tftp_args->gi6addr, 0, 16);
124 argncpy(arg_str, 0, arg_buf, 100);
125 if (str_to_ipv6(arg_buf, (uint8_t *) &(obp_tftp_args->gi6addr.addr)) ) {
126 arg_str = get_arg_ptr(arg_str, 1);
129 else if(arg_buf[0] == 0) {
130 memset(&obp_tftp_args->gi6addr, 0, 16);
131 arg_str = get_arg_ptr(arg_str, 1);
135 memset(&obp_tftp_args->gi6addr.addr, 0, 16);
143 * Parses a argument string for IPv4 booting, extracts all
144 * parameters and fills a structure accordingly
146 * @param arg_str string with arguments, separated with ','
147 * @param argc number of arguments
148 * @param obp_tftp_args structure which contains the result
149 * @return updated arg_str
152 parse_ipv4args (const char *arg_str, unsigned int argc,
153 obp_tftp_args_t *obp_tftp_args)
160 memset(obp_tftp_args->siaddr, 0, 4);
162 argncpy(arg_str, 0, arg_buf, 100);
163 if(strtoip(arg_buf, obp_tftp_args->siaddr)) {
164 arg_str = get_arg_ptr(arg_str, 1);
167 else if(arg_buf[0] == 0) {
168 memset(obp_tftp_args->siaddr, 0, 4);
169 arg_str = get_arg_ptr(arg_str, 1);
173 memset(obp_tftp_args->siaddr, 0, 4);
178 obp_tftp_args->filename[0] = 0;
180 argncpy(arg_str, 0, obp_tftp_args->filename, 100);
181 for(ptr = obp_tftp_args->filename; *ptr != 0; ++ptr)
184 arg_str = get_arg_ptr(arg_str, 1);
190 memset(obp_tftp_args->ciaddr, 0, 4);
192 argncpy(arg_str, 0, arg_buf, 100);
193 if(strtoip(arg_buf, obp_tftp_args->ciaddr)) {
194 arg_str = get_arg_ptr(arg_str, 1);
197 else if(arg_buf[0] == 0) {
198 memset(obp_tftp_args->ciaddr, 0, 4);
199 arg_str = get_arg_ptr(arg_str, 1);
203 memset(obp_tftp_args->ciaddr, 0, 4);
208 memset(obp_tftp_args->giaddr, 0, 4);
210 argncpy(arg_str, 0, arg_buf, 100);
211 if(strtoip(arg_buf, obp_tftp_args->giaddr)) {
212 arg_str = get_arg_ptr(arg_str, 1);
215 else if(arg_buf[0] == 0) {
216 memset(obp_tftp_args->giaddr, 0, 4);
217 arg_str = get_arg_ptr(arg_str, 1);
221 memset(obp_tftp_args->giaddr, 0, 4);
228 * Parses a argument string which is given by netload, extracts all
229 * parameters and fills a structure according to this
231 * Netload-Parameters:
232 * [bootp,]siaddr,filename,ciaddr,giaddr,bootp-retries,tftp-retries
234 * @param arg_str string with arguments, separated with ','
235 * @param obp_tftp_args structure which contains the result
239 parse_args(const char *arg_str, obp_tftp_args_t *obp_tftp_args)
244 memset(obp_tftp_args, 0, sizeof(*obp_tftp_args));
246 argc = get_args_count(arg_str);
248 // find out if we should use BOOTP or DHCP
250 obp_tftp_args->ip_init = IP_INIT_DEFAULT;
252 argncpy(arg_str, 0, arg_buf, 100);
253 if (strcasecmp(arg_buf, "bootp") == 0) {
254 obp_tftp_args->ip_init = IP_INIT_BOOTP;
255 arg_str = get_arg_ptr(arg_str, 1);
258 else if(strcasecmp(arg_buf, "dhcp") == 0) {
259 obp_tftp_args->ip_init = IP_INIT_DHCP;
260 arg_str = get_arg_ptr(arg_str, 1);
263 else if(strcasecmp(arg_buf, "ipv6") == 0) {
264 obp_tftp_args->ip_init = IP_INIT_DHCPV6_STATELESS;
265 arg_str = get_arg_ptr(arg_str, 1);
270 obp_tftp_args->ip_init = IP_INIT_DEFAULT;
273 if (ip_version == 4) {
274 arg_str = parse_ipv4args (arg_str, argc, obp_tftp_args);
276 else if (ip_version == 6) {
277 arg_str = parse_ipv6args (arg_str, argc, obp_tftp_args);
280 // find out bootp-retries
282 obp_tftp_args->bootp_retries = DEFAULT_BOOT_RETRIES;
284 argncpy(arg_str, 0, arg_buf, 100);
286 obp_tftp_args->bootp_retries = DEFAULT_BOOT_RETRIES;
288 obp_tftp_args->bootp_retries = strtol(arg_buf, 0, 10);
289 if(obp_tftp_args->bootp_retries < 0)
290 obp_tftp_args->bootp_retries = DEFAULT_BOOT_RETRIES;
292 arg_str = get_arg_ptr(arg_str, 1);
296 // find out tftp-retries
298 obp_tftp_args->tftp_retries = DEFAULT_TFTP_RETRIES;
300 argncpy(arg_str, 0, arg_buf, 100);
302 obp_tftp_args->tftp_retries = DEFAULT_TFTP_RETRIES;
304 obp_tftp_args->tftp_retries = strtol(arg_buf, 0, 10);
305 if(obp_tftp_args->tftp_retries < 0)
306 obp_tftp_args->tftp_retries = DEFAULT_TFTP_RETRIES;
308 arg_str = get_arg_ptr(arg_str, 1);
314 * DHCP: Wrapper for obtaining IP and configuration info from DHCP server
315 * for both IPv4 and IPv6.
316 * (makes several attempts).
318 * @param ret_buffer buffer for returning BOOTP-REPLY packet data
319 * @param fn_ip contains the following configuration information:
320 * client MAC, client IP, TFTP-server MAC,
321 * TFTP-server IP, Boot file name
322 * @param retries No. of DHCP attempts
323 * @param flags flags for specifying type of dhcp attempt (IPv4/IPv6)
324 * ZERO - attempt DHCPv4 followed by DHCPv6
325 * F_IPV4 - attempt only DHCPv4
326 * F_IPV6 - attempt only DHCPv6
327 * @return ZERO - IP and configuration info obtained;
328 * NON ZERO - error condition occurs.
330 int dhcp(char *ret_buffer, filename_ip_t * fn_ip, unsigned int retries, int flags)
332 int i = (int) retries+1;
338 printf("\b\b\b%03d", i-1);
339 if (getchar() == 27) {
340 printf("\nAborted\n");
344 printf("\nGiving up after %d DHCP requests\n", retries);
347 if (!flags || (flags == F_IPV4)) {
349 rc = dhcpv4(ret_buffer, fn_ip);
351 if ((!flags && (rc == -1)) || (flags == F_IPV6)) {
353 set_ipv6_address(fn_ip->fd, 0);
354 rc = dhcpv6(ret_buffer, fn_ip);
357 memcpy(&fn_ip->own_ip6, get_ipv6_address(), 16);
362 if (rc != -1) /* either success or non-dhcp failure */
371 netboot(int argc, char *argv[])
375 int len = strtol(argv[2], 0, 16);
376 char *buffer = (char *) strtol(argv[1], 0, 16);
377 char *ret_buffer = (char *) strtol(argv[3], 0, 16);
381 obp_tftp_args_t obp_tftp_args;
382 char null_ip[4] = { 0x00, 0x00, 0x00, 0x00 };
383 char null_ip6[16] = { 0x00, 0x00, 0x00, 0x00,
384 0x00, 0x00, 0x00, 0x00,
385 0x00, 0x00, 0x00, 0x00,
386 0x00, 0x00, 0x00, 0x00 };
387 int huge_load = strtol(argv[4], 0, 10);
388 int32_t block_size = strtol(argv[5], 0, 10);
392 printf(" Bootloader 1.6 \n");
393 memset(&fn_ip, 0, sizeof(filename_ip_t));
395 /***********************************************************
397 * Initialize network stuff and retrieve boot informations
399 ***********************************************************/
401 /* Wait for link up and get mac_addr from device */
402 for(rc=0; rc<DEFAULT_BOOT_RETRIES; ++rc) {
404 set_timer(TICKS_SEC);
405 while (get_timer() > 0);
407 fd_device = socket(0, 0, 0, (char*) own_mac);
410 if(getchar() == 27) {
416 if (fd_device == -1) {
417 strcpy(buf,"E3000: (net) Could not read MAC address");
418 bootmsg_error(0x3000, &buf[7]);
420 write_mm_log(buf, strlen(buf), 0x91);
423 else if (fd_device == -2) {
424 strcpy(buf,"E3006: (net) Could not initialize network device");
425 bootmsg_error(0x3006, &buf[7]);
427 write_mm_log(buf, strlen(buf), 0x91);
431 fn_ip.fd = fd_device;
433 printf(" Reading MAC address from device: "
434 "%02x:%02x:%02x:%02x:%02x:%02x\n",
435 own_mac[0], own_mac[1], own_mac[2],
436 own_mac[3], own_mac[4], own_mac[5]);
438 // init ethernet layer
439 set_mac_address(own_mac);
442 parse_args(argv[6], &obp_tftp_args);
443 if(obp_tftp_args.bootp_retries - rc < DEFAULT_BOOT_RETRIES)
444 obp_tftp_args.bootp_retries = DEFAULT_BOOT_RETRIES;
446 obp_tftp_args.bootp_retries -= rc;
449 memset(&obp_tftp_args, 0, sizeof(obp_tftp_args_t));
450 obp_tftp_args.ip_init = IP_INIT_DEFAULT;
451 obp_tftp_args.bootp_retries = DEFAULT_BOOT_RETRIES;
452 obp_tftp_args.tftp_retries = DEFAULT_TFTP_RETRIES;
454 memcpy(&fn_ip.own_ip, obp_tftp_args.ciaddr, 4);
456 // reset of error code
459 /* if we still have got all necessary parameters, then we don't
460 need to perform an BOOTP/DHCP-Request */
461 if (ip_version == 4) {
462 if (memcmp(obp_tftp_args.ciaddr, null_ip, 4) != 0
463 && memcmp(obp_tftp_args.siaddr, null_ip, 4) != 0
464 && obp_tftp_args.filename[0] != 0) {
466 memcpy(&fn_ip.server_ip, &obp_tftp_args.siaddr, 4);
467 obp_tftp_args.ip_init = IP_INIT_NONE;
470 else if (ip_version == 6) {
471 if (memcmp(&obp_tftp_args.ci6addr, null_ip6, 16) != 0
472 && memcmp(&obp_tftp_args.si6addr, null_ip6, 16) != 0
473 && obp_tftp_args.filename[0] != 0) {
475 memcpy(&fn_ip.server_ip6.addr[0],
476 &obp_tftp_args.si6addr.addr, 16);
477 obp_tftp_args.ip_init = IP_INIT_IPV6_MANUAL;
480 obp_tftp_args.ip_init = IP_INIT_DHCPV6_STATELESS;
484 // construction of fn_ip from parameter
485 switch(obp_tftp_args.ip_init) {
487 printf(" Requesting IP address via BOOTP: ");
488 // if giaddr in not specified, then we have to identify
489 // the BOOTP server via broadcasts
490 if(memcmp(obp_tftp_args.giaddr, null_ip, 4) == 0) {
491 // don't do this, when using DHCP !!!
492 fn_ip.server_ip = 0xFFFFFFFF;
494 // if giaddr is specified, then we have to use this
495 // IP address as proxy to identify the BOOTP server
497 memcpy(&fn_ip.server_ip, obp_tftp_args.giaddr, 4);
499 rc = bootp(ret_buffer, &fn_ip, obp_tftp_args.bootp_retries);
502 printf(" Requesting IP address via DHCPv4: ");
503 rc = dhcp(ret_buffer, &fn_ip, obp_tftp_args.bootp_retries, F_IPV4);
505 case IP_INIT_DHCPV6_STATELESS:
506 printf(" Requesting information via DHCPv6: ");
507 rc = dhcp(ret_buffer, &fn_ip,
508 obp_tftp_args.bootp_retries, F_IPV6);
510 case IP_INIT_IPV6_MANUAL:
511 set_ipv6_address(fn_ip.fd, &obp_tftp_args.ci6addr);
513 case IP_INIT_DEFAULT:
514 printf(" Requesting IP address via DHCP: ");
515 rc = dhcp(ret_buffer, &fn_ip, obp_tftp_args.bootp_retries, 0);
522 if(rc >= 0 && ip_version == 4) {
523 if(memcmp(obp_tftp_args.ciaddr, null_ip, 4) != 0
524 && memcmp(obp_tftp_args.ciaddr, &fn_ip.own_ip, 4) != 0)
525 memcpy(&fn_ip.own_ip, obp_tftp_args.ciaddr, 4);
527 if(memcmp(obp_tftp_args.siaddr, null_ip, 4) != 0
528 && memcmp(obp_tftp_args.siaddr, &fn_ip.server_ip, 4) != 0)
529 memcpy(&fn_ip.server_ip, obp_tftp_args.siaddr, 4);
532 set_ipv4_address(fn_ip.own_ip);
534 else if (rc >= 0 && ip_version == 6) {
535 if(memcmp(&obp_tftp_args.ci6addr.addr, null_ip6, 16) != 0
536 && memcmp(&obp_tftp_args.ci6addr.addr, &fn_ip.own_ip6, 16) != 0)
537 memcpy(&fn_ip.own_ip6, &obp_tftp_args.ci6addr.addr, 16);
539 if(memcmp(&obp_tftp_args.si6addr.addr, null_ip6, 16) != 0
540 && memcmp(&obp_tftp_args.si6addr.addr, &fn_ip.server_ip6.addr, 16) != 0)
541 memcpy(&fn_ip.server_ip6.addr, &obp_tftp_args.si6addr.addr, 16);
544 strcpy(buf,"E3001: (net) Could not get IP address");
545 bootmsg_error(0x3001, &buf[7]);
547 write_mm_log(buf, strlen(buf), 0x91);
552 printf("%d.%d.%d.%d\n",
553 ((fn_ip.own_ip >> 24) & 0xFF), ((fn_ip.own_ip >> 16) & 0xFF),
554 ((fn_ip.own_ip >> 8) & 0xFF), ( fn_ip.own_ip & 0xFF));
558 "E3002: (net) ARP request to TFTP server "
559 "(%d.%d.%d.%d) failed",
560 ((fn_ip.server_ip >> 24) & 0xFF),
561 ((fn_ip.server_ip >> 16) & 0xFF),
562 ((fn_ip.server_ip >> 8) & 0xFF),
563 ( fn_ip.server_ip & 0xFF));
564 bootmsg_error(0x3002, &buf[7]);
566 write_mm_log(buf, strlen(buf), 0x91);
569 if (rc == -4 || rc == -3) {
570 strcpy(buf,"E3008: (net) Can't obtain TFTP server IP address");
571 bootmsg_error(0x3008, &buf[7]);
573 write_mm_log(buf, strlen(buf), 0x91);
578 /***********************************************************
580 * Load file via TFTP into buffer provided by OpenFirmware
582 ***********************************************************/
584 if (obp_tftp_args.filename[0] != 0) {
585 strncpy((char *) fn_ip.filename, obp_tftp_args.filename, sizeof(fn_ip.filename)-1);
586 fn_ip.filename[sizeof(fn_ip.filename)-1] = 0;
589 if (ip_version == 4) {
590 printf(" Requesting file \"%s\" via TFTP from %d.%d.%d.%d\n",
592 ((fn_ip.server_ip >> 24) & 0xFF),
593 ((fn_ip.server_ip >> 16) & 0xFF),
594 ((fn_ip.server_ip >> 8) & 0xFF),
595 ( fn_ip.server_ip & 0xFF));
596 } else if (ip_version == 6) {
598 printf(" Requesting file \"%s\" via TFTP from ", fn_ip.filename);
599 ipv6_to_str(fn_ip.server_ip6.addr, ip6_str);
600 printf("%s\n", ip6_str);
603 // accept at most 20 bad packets
604 // wait at most for 40 packets
605 rc = tftp(&fn_ip, (unsigned char *) buffer,
606 len, obp_tftp_args.tftp_retries,
607 &tftp_err, huge_load, block_size, ip_version);
609 if(obp_tftp_args.ip_init == IP_INIT_DHCP)
610 dhcp_send_release(fn_ip.fd);
613 printf(" TFTP: Received %s (%d KBytes)\n", fn_ip.filename,
615 } else if (rc == -1) {
616 bootmsg_error(0x3003, "(net) unknown TFTP error");
618 } else if (rc == -2) {
620 "E3004: (net) TFTP buffer of %d bytes "
621 "is too small for %s",
622 len, fn_ip.filename);
623 bootmsg_error(0x3004, &buf[7]);
625 write_mm_log(buf, strlen(buf), 0x91);
627 } else if (rc == -3) {
628 sprintf(buf,"E3009: (net) file not found: %s",
630 bootmsg_error(0x3009, &buf[7]);
632 write_mm_log(buf, strlen(buf), 0x91);
634 } else if (rc == -4) {
635 strcpy(buf,"E3010: (net) TFTP access violation");
636 bootmsg_error(0x3010, &buf[7]);
638 write_mm_log(buf, strlen(buf), 0x91);
640 } else if (rc == -5) {
641 strcpy(buf,"E3011: (net) illegal TFTP operation");
642 bootmsg_error(0x3011, &buf[7]);
644 write_mm_log(buf, strlen(buf), 0x91);
646 } else if (rc == -6) {
647 strcpy(buf, "E3012: (net) unknown TFTP transfer ID");
648 bootmsg_error(0x3012, &buf[7]);
650 write_mm_log(buf, strlen(buf), 0x91);
652 } else if (rc == -7) {
653 strcpy(buf, "E3013: (net) no such TFTP user");
654 bootmsg_error(0x3013, &buf[7]);
656 write_mm_log(buf, strlen(buf), 0x91);
658 } else if (rc == -8) {
659 strcpy(buf, "E3017: (net) TFTP blocksize negotiation failed");
660 bootmsg_error(0x3017, &buf[7]);
662 write_mm_log(buf, strlen(buf), 0x91);
664 } else if (rc == -9) {
665 strcpy(buf,"E3018: (net) file exceeds maximum TFTP transfer size");
666 bootmsg_error(0x3018, &buf[7]);
668 write_mm_log(buf, strlen(buf), 0x91);
670 } else if (rc <= -10 && rc >= -15) {
671 sprintf(buf,"E3005: (net) ICMP ERROR \"");
673 case -ICMP_NET_UNREACHABLE - 10:
674 sprintf(buf+strlen(buf),"net unreachable");
676 case -ICMP_HOST_UNREACHABLE - 10:
677 sprintf(buf+strlen(buf),"host unreachable");
679 case -ICMP_PROTOCOL_UNREACHABLE - 10:
680 sprintf(buf+strlen(buf),"protocol unreachable");
682 case -ICMP_PORT_UNREACHABLE - 10:
683 sprintf(buf+strlen(buf),"port unreachable");
685 case -ICMP_FRAGMENTATION_NEEDED - 10:
686 sprintf(buf+strlen(buf),"fragmentation needed and DF set");
688 case -ICMP_SOURCE_ROUTE_FAILED - 10:
689 sprintf(buf+strlen(buf),"source route failed");
692 sprintf(buf+strlen(buf)," UNKNOWN");
695 sprintf(buf+strlen(buf),"\"");
696 bootmsg_error(0x3005, &buf[7]);
698 write_mm_log(buf, strlen(buf), 0x91);
700 } else if (rc == -40) {
702 "E3014: (net) TFTP error occurred after "
703 "%d bad packets received",
704 tftp_err.bad_tftp_packets);
705 bootmsg_error(0x3014, &buf[7]);
706 write_mm_log(buf, strlen(buf), 0x91);
708 } else if (rc == -41) {
710 "E3015: (net) TFTP error occurred after "
711 "missing %d responses",
712 tftp_err.no_packets);
713 bootmsg_error(0x3015, &buf[7]);
714 write_mm_log(buf, strlen(buf), 0x91);
716 } else if (rc == -42) {
718 "E3016: (net) TFTP error missing block %d, "
719 "expected block was %d",
720 tftp_err.blocks_missed,
721 tftp_err.blocks_received);
722 bootmsg_error(0x3016, &buf[7]);
723 write_mm_log(buf, strlen(buf), 0x91);
730 * Parses a tftp arguments, extracts all
731 * parameters and fills server ip according to this
734 * @param buffer string with arguments,
735 * @param server_ip server ip as result
736 * @param filename default filename
737 * @param fd Socket descriptor
738 * @param len len of the buffer,
739 * @return 0 on SUCCESS and -1 on failure
741 int parse_tftp_args(char buffer[], char *server_ip, char filename[], int fd,
747 char domainname[256];
748 uint8_t server_ip6[16];
752 printf("\n unable to allocate memory, parsing failed\n");
755 strncpy(raw,(const char *)buffer,len);
756 /*tftp url contains tftp://[fd00:4f53:4444:90:214:5eff:fed9:b200]/testfile*/
757 if(strncmp(raw,"tftp://",7)){
758 printf("\n tftp missing in %s\n",raw);
762 tmp = strchr(raw,'[');
763 if(tmp != NULL && *tmp == '[') {
764 /*check for valid ipv6 address*/
765 tmp1 = strchr(tmp,']');
767 printf("\n missing ] in %s\n",raw);
772 /*look for file name*/
773 tmp1 = strchr(tmp,'/');
775 printf("\n missing filename in %s\n",raw);
780 /*check for 16 byte ipv6 address */
781 if (!str_to_ipv6((tmp+1), (uint8_t *)(server_ip))) {
782 printf("\n wrong format IPV6 address in %s\n",raw);
788 strcpy(filename,(tmp1+1));
794 /*here tftp://hostname/testfile from option request of dhcp*/
795 /*look for dns server name */
796 tmp1 = strchr(raw,'.');
798 printf("\n missing . seperator in %s\n",raw);
802 /*look for domain name beyond dns server name
803 * so ignore the current . and look for one more
805 tmp = strchr((tmp1+1),'.');
807 printf("\n missing domain in %s\n",raw);
811 tmp1 = strchr(tmp1,'/');
813 printf("\n missing filename in %s\n",raw);
817 j = tmp1 - (raw + 7);
820 strcpy(domainname, tmp);
821 if (dns_get_ip(fd, (int8_t *)domainname, server_ip6, 6) == 0) {
822 printf("\n DNS failed for IPV6\n");
825 ipv6_to_str(server_ip6, server_ip);
827 strcpy(filename,(tmp1+1));