Watt-32 tcp/ip  2.2 dev-rel.10
sock_ini.c
Go to the documentation of this file.
1 
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <signal.h>
35 #include <setjmp.h>
36 #include <limits.h>
37 #include <float.h>
38 #include <math.h>
39 #include <time.h>
40 #include <io.h>
41 
42 #ifdef __HIGHC__
43 #include <init.h> /* _mwenv(), PL_ENV */
44 #endif
45 
46 #ifdef __DJGPP__
47 #include <sys/exceptn.h>
48 #endif
49 
50 #include "copyrigh.h"
51 #include "wattcp.h"
52 #include "strings.h"
53 #include "language.h"
54 #include "misc.h"
55 #include "run.h"
56 #include "timer.h"
57 #include "profile.h"
58 #include "wdpmi.h"
59 #include "x32vm.h"
60 #include "powerpak.h"
61 #include "pcbootp.h"
62 #include "pcrarp.h"
63 #include "pcdhcp.h"
64 #include "pcconfig.h"
65 #include "pcigmp.h"
66 #include "pcicmp.h"
67 #include "pctcp.h"
68 #include "pcarp.h"
69 #include "pcsed.h"
70 #include "pcqueue.h"
71 #include "pcpkt.h"
72 #include "pcdbug.h"
73 #include "netaddr.h"
74 #include "syslog2.h"
75 #include "pcdns.h"
76 #include "bsdname.h"
77 #include "bsddbug.h"
78 #include "ip4_frag.h"
79 #include "ip6_in.h"
80 #include "printk.h"
81 #include "sock_ini.h"
82 
83 #if (DOSX & PHARLAP)
84 #include <mw/exc.h>
85 #endif
86 
87 #if defined(USE_TFTP)
88 #include "tftp.h"
89 #endif
90 
91 #if defined(USE_BSD_API)
92 #include "socket.h"
93 #include "get_xby.h"
94 #endif
95 
96 #if defined(USE_BIND)
97 #include "resolver.h"
98 #endif
99 
100 #if defined(USE_ECHO_DISC)
101 #include "echo.h"
102 #endif
103 
104 #if defined(USE_PPPOE)
105 #include "pppoe.h"
106 #endif
107 
108 #if defined(USE_IDNA)
109 #include "idna.h"
110 #endif
111 
112 #if defined(USE_DYNIP_CLI)
113 #include "dynip.h"
114 #endif
115 
116 #if defined(WIN32)
117 #include "winpkt.h"
118 #endif
119 
120 #if defined(__HIGHC__) /* Metaware's HighC have SIGBREAK == SIGQUIT */
121 #undef SIGBREAK
122 #endif
123 
124 #include "nochkstk.h"
125 
126 typedef void (MS_CDECL *_signal_handler) (int);
127 typedef void (MS_CDECL *_atexit_handler) (void);
128 
129 BOOL _bootp_on = FALSE;
130 BOOL _dhcp_on = FALSE;
131 BOOL _dhcp6_on = FALSE;
132 BOOL _rarp_on = FALSE;
133 BOOL _do_mask_req = FALSE;
134 BOOL _watt_do_exit = TRUE;
135 BOOL _watt_no_config = FALSE;
137 WattUserConfigFunc _watt_user_config_fn = NULL;
138 
139 BOOL survive_eth = 0;
144 #if defined(USE_DHCP)
145  BOOL survive_bootp = TRUE;
146 #else
147  BOOL survive_bootp = FALSE;
148 #endif
149 
150 #if defined(USE_RARP)
151  BOOL survive_dhcp = TRUE;
152 #else
153  BOOL survive_dhcp = FALSE;
154 #endif
155 
156 BOOL survive_rarp = FALSE;
157 BOOL _watt_is_init = FALSE;
159 static BOOL tcp_is_init = FALSE;
160 static int old_break = -1;
199 WattUserConfigFunc W32_CALL _watt_user_config (WattUserConfigFunc fn)
200 {
201  WattUserConfigFunc old_fn = _watt_user_config_fn;
202 
203  _watt_user_config_fn = fn;
204  return (old_fn);
205 }
206 
211 static int do_exit (int code)
212 {
213  if (_watt_do_exit)
214  exit (code);
215  return (code);
216 }
217 
221 #if !defined(MAKE_TSR)
222 
223 static BOOL use_except = TRUE;
224 
225 #if (DOSX & (DOS4GW|X32VM))
226 
227 static jmp_buf exc_jmp;
228 static struct FAULT_STRUC exc_buf;
229 
230 static void pre_except_handler (const struct FAULT_STRUC *exc)
231 {
232  exc_buf = *exc;
233  longjmp (exc_jmp, SIGSEGV);
234 }
235 
236 #if !defined(__CCDL__) && !defined(__BORLANDC__)
237 static void do_traceback (void)
238 {
239  _printk_safe = TRUE;
240  _printk ("\r\nException %d at %04X:%08X\r\n",
241  exc_buf.fault_num, exc_buf.cs, exc_buf.eip);
242 
243  _printk (" EAX %08X EBX %08X ECX %08X EDX %08X\r\n",
244  exc_buf.eax, exc_buf.ebx, exc_buf.ecx, exc_buf.edx);
245 
246  _printk (" ESI %08X EDI %08X EBP %08X ESP %08X\r\n",
247  exc_buf.esi, exc_buf.edi, exc_buf.ebp, exc_buf.esp);
248 
249  _printk (" DS %04X ES %04X FS %04X GS %04X SS %04X EFLAGS %08X\r\n",
250  exc_buf.ds, exc_buf.es, exc_buf.fs, exc_buf.gs, exc_buf.ss,
251  exc_buf.eflags);
252 
253  _printk_flush();
254 
255  if (!exc_buf.mode) /* exception in protected mode */
256  {
257  stack_rewind (exc_buf.eip, exc_buf.ebp);
258  _printk_flush();
259  }
260 }
261 #endif /* __CCDL__ */
262 #endif /* DOS4GW|X32VM */
263 
264 
265 #if defined(__DJGPP__)
266 static void except_handler (int sig)
267 {
268  static BOOL been_here = FALSE;
269  static jmp_buf exc_buf;
270 
271  _watt_fatal_error = TRUE;
272 
273  if (been_here)
274  {
275  been_here = FALSE;
276  signal (sig, SIG_DFL);
277  __djgpp_exception_state_ptr = &exc_buf;
278  }
279  else /* save exception context in case of reentry */
280  {
281  memcpy (&exc_buf, __djgpp_exception_state_ptr, sizeof(exc_buf));
282  been_here = TRUE;
283  psignal (sig, "TCP/IP shutdown");
284  rundown_run();
285 
286 #if 0
287 
290  StackWalk (exc_buf[0].__eip, exc_buf[0].__ebp);
291 #endif
292  }
293  raise (SIGABRT);
294 }
295 
296 #elif (DOSX & PHARLAP)
297 static void except_handler (excReg *regs)
298 {
299  _watt_fatal_error = TRUE;
300  rundown_run();
301  _exit (-1);
302  ARGSUSED (regs);
303 }
304 
305 #else
306 /*
307  * Note: Watcom's extension to SIGFPE is undocumented.
308  * This is dead code on Windows since except_handler()
309  * isn't installed yet.
310  */
311 static void except_handler (int sig, int code)
312 {
313 #if defined(__WATCOMC__) && !defined(W32_NO_8087)
314  if (sig == SIGFPE && code == FPE_IOVERFLOW)
315  {
316  _fpreset();
317  outsnl (_LANG("Ignoring SIGFPE (FPE_IOVERFLOW)"));
318  return;
319  }
320 #endif
321 
322 #if defined(__MSDOS__)
323  /* Take extra care only under MSDOS.
324  */
325  _watt_fatal_error = TRUE;
326 #endif
327 
328 #if defined(SIGFPE)
329  if (sig == SIGFPE)
330  {
331 #if defined(__WATCOMC__)
332  outs (_LANG("Trapping SIGFPE code 0x"));
333  outhex (code);
334 #else
335  outsnl (_LANG("Trapping SIGFPE."));
336 #endif
337  }
338  else
339 #endif
340 
341 #if defined(SIGSEGV)
342  if (sig == SIGSEGV)
343  {
344  outsnl (_LANG("Trapping SIGSEGV"));
345 #if (DOSX & (DOS4GW|X32VM)) && !defined(__CCDL__) && !defined(__BORLANDC__)
346  do_traceback();
347 #endif
348  }
349 #endif
350 
351  rundown_run();
352 
353 #if (DOSX) /* don't pull in iob for small/large */
354  fflush (stdout);
355  fflush (stderr);
356 #endif
357 
358  ARGSUSED (code);
359 #if defined(__POCC__)
360  exit (-1);
361 #else
362  _exit (-1);
363 #endif
364 }
365 #endif /* __DJGPP__ */
366 
367 
372 static void setup_sig_handlers (void)
373 {
374 #if (DOSX & (DOS4GW|X32VM))
375  volatile int sig;
376 #endif
377 
378 #if defined(WIN32) /* no need for a special exc-handler (yet?) */
379  use_except = FALSE;
380 #else
381  if (getenv("WATT32-NOEXC") || /* don't trap exceptions */
382  getenv("WATT32-NOEXCEPT"))
383  use_except = FALSE;
384 #endif
385 
386  if (!use_except)
387  return;
388 
389 #if (DOSX & PHARLAP)
390  InstallExcHandler (except_handler);
391 
392 #elif (DOSX & X32VM)
393  _printk_init (2000, NULL);
394  _x32_fault_intercept (pre_except_handler);
395  sig = setjmp (exc_jmp);
396  if (sig)
397  except_handler (sig, 0);
398 
399 #elif (DOSX & DOS4GW)
400  signal (SIGSEGV, (void(*)(int))except_handler);
401  signal (SIGFPE, (void(*)(int))except_handler);
402 
403  _printk_init (2000, NULL);
404  dpmi_except_handler (pre_except_handler); /* Only effective for Causeway */
405  sig = setjmp (exc_jmp);
406  if (sig)
407  except_handler (sig, 0);
408 
409 #elif defined(__DJGPP__)
410  signal (SIGSEGV, except_handler);
411  signal (SIGTRAP, except_handler);
412  signal (SIGFPE, except_handler);
413  signal (SIGILL, except_handler);
414 
415 #else
416  /*
417  * SIGSEGV may not be effective under all environments.
418  * PowerPak definetely supports SIGSEGV.
419  */
420  #ifdef SIGSEGV
421  signal (SIGSEGV, (_signal_handler)except_handler);
422  #endif
423  #ifdef SIGFPE
424  signal (SIGFPE, (_signal_handler)except_handler);
425  #endif
426 #endif
427 }
428 
429 static void restore_sig_handlers (void)
430 {
431  if (!_watt_cbroke)
432  signal (SIGINT, SIG_DFL);
433 
434  if (old_break >= 0)
436 
437  if (!use_except)
438  return;
439 
440 #if (DOSX & DOS4GW)
441  signal (SIGSEGV, SIG_DFL);
442  signal (SIGFPE, SIG_DFL);
443 
444 #elif defined(__DJGPP__)
445  signal (SIGSEGV, SIG_DFL);
446  signal (SIGTRAP, SIG_DFL);
447  signal (SIGFPE, SIG_DFL);
448  signal (SIGILL, SIG_DFL);
449 
450 #elif defined(__BORLANDC__) && defined(SIGSEGV) && defined(SIGFPE)
451  signal (SIGSEGV, SIG_DFL);
452  signal (SIGFPE, SIG_DFL);
453 #endif
454 }
455 #endif /* MAKE_TSR */
456 
457 
462 static void tcp_shutdown (void)
463 {
464  if (!tcp_is_init)
465  return;
466 
467 #if !defined(USE_UDP_ONLY)
468  while (_tcp_allsocs)
469  TCP_ABORT (_tcp_allsocs); /* Sends RST if needed */
470  _tcp_allsocs = NULL;
471 #endif
472  _udp_allsocs = NULL;
473 
474 #if defined(USE_DHCP)
475  /*
476  * If DHCP-config saved to disk and remaining lease is above min.,
477  * do nothing. Otherwise be nice and release our address
478  */
479  DHCP_release (FALSE);
480 #endif
481 
482 #if defined(USE_PPPOE)
483  pppoe_exit();
484 #endif
485 
486  tcp_is_init = FALSE;
487 }
488 
489 
499 static int tcp_init (void)
500 {
501  int rc = WERR_NO_DRIVER;
502 
503  if (!tcp_is_init)
504  {
505  tcp_is_init = TRUE;
506  rc = _eth_init(); /* initialize LAN-card */
507  if (rc == 0)
508  {
509  last_nameserver = 0; /* reset the nameserver table */
510  last_cookie = 0; /* eat all remaining crumbs */
511 
512  if (!init_localport()) /* clear local ports in-use */
513  return (WERR_NO_MEM);
514 
515  /* I not already set, try asking a DOS network extension
516  * for a host-name.
517  */
518  if (!strcmp(hostname,"random-pc"))
520  }
521  }
522  return (rc);
523 }
524 
528 static void tcp_post_init (void)
529 {
530  int MTU;
531 
532  if (!tcp_is_init) /* tcp_init() not called */
533  return;
534 
535  memdbg_post_init();
536 
537 #if defined(USE_BSD_API)
538  ReadEthersFile(); /* requires gethostbyname() */
539 #endif
540 
541 #if defined(USE_PROFILER)
542  if (profile_enable)
543  profile_init();
544 #endif
545 
546 #if defined(USE_IPV6)
547  _ip6_post_init();
548 #endif
549 
550 #if defined(USE_DEBUG)
551  if (debug_on >= 3)
552  rundown_dump();
553 #endif
554 
555  MTU = pkt_get_mtu(); /* driver knows correct MTU (includes MAC-header) */
556  if (MTU > 0)
557  _mtu = MTU;
558 
559  if (_mtu > ETH_MAX_DATA)
560  _mtu = ETH_MAX_DATA;
561 
562  if (_mss > MSS_MAX)
563  _mss = MSS_MAX;
564 
565 #if defined(__MSDOS__) && !defined(USE_UDP_ONLY)
566  {
567  DWORD max_rwin;
568 
569  /* Work around a limitation of NDIS3PKT. It only allocates 6 buffers
570  * per VDD (DOS-box). Thus receiving a burts of RWIN/MSS packets, they
571  * could all get lost. Clamp our advertised RWIN. Hence, it's adviced
572  * to use SwsVpkt in a Windows DOS-box.
573  *
574  * Note: bandwidth <= 1.3 * MTU / (RTT * sqrt(Loss))
575  */
576  max_rwin = 6 * _mss;
577 
578  if (_eth_ndis3pkt && tcp_recv_win > max_rwin)
579  tcp_recv_win = max_rwin;
580  }
581 #endif
582 
583  if (usr_post_init) /* tell hook(s) we're done */
584  (*usr_post_init)();
585 }
586 
593 static int tcp_do_bootp (BOOL try_bootp, BOOL try_dhcp, BOOL try_rarp)
594 {
595  if (try_bootp)
596  {
597 #if defined(USE_BOOTP)
598  if (BOOTP_do_boot())
599  return (0);
600 
601  outsnl (_LANG("failed"));
602  if (!survive_bootp)
603  return (WERR_BOOTP_FAIL);
604 #else
605  outsnl ("BOOTP needed, but library wasn't built with \"USE_BOOTP\"");
606 #endif
607 
608 #if defined(USE_DHCP)
609  try_dhcp = TRUE;
610 #endif
611 
612 #if defined(USE_RARP)
613  try_rarp = TRUE;
614 #endif
615  }
616 
617  if (try_dhcp)
618  {
619 #if defined(USE_DHCP)
620  if (DHCP_do_boot())
621  return (0);
622 
623  outsnl (_LANG("failed"));
624  if (!survive_dhcp)
625  return (WERR_DHCP_FAIL);
626 #else
627  outsnl ("DHCP needed, but library wasn't built with \"USE_DHCP\"");
628 #endif
629 
630 #if defined(USE_RARP)
631  try_rarp = TRUE;
632 #endif
633  }
634 
635  if (try_rarp)
636  {
637 #if defined(USE_RARP)
638  if (_dorarp())
639  return (0);
640 
641  outsnl (_LANG("failed"));
642  if (!survive_rarp)
643  return (WERR_RARP_FAIL);
644 #else
645  outsnl ("RARP needed, but library wasn't built with \"USE_RARP\"");
646 #endif
647  }
648  return (WERR_NO_IPADDR); /* all attempts failed */
649 }
650 
651 
652 #if defined(USE_DEBUG)
653 /*
654  * A guard against this common error; The wattlib user forgot to rebuild
655  * using the latest <tcp.h>.
656  *
657  * \todo: check this in a GUI program.
658  */
659 static void check_sock_sizes (size_t tcp_Sock_size, size_t udp_Sock_size)
660 {
661  char buf[100];
662  char *p = buf;
663 
664  if (tcp_Sock_size > 0 && tcp_Sock_size < sizeof(_tcp_Socket))
665  p += sprintf (p, "sizeof(_tcp_Socket) in <tcp.h> too small. "
666  "%d bytes needed\r\n", SIZEOF(_tcp_Socket));
667 
668  if (udp_Sock_size > 0 && udp_Sock_size < sizeof(_udp_Socket))
669  p += sprintf (p, "sizeof(_udp_Socket) in <tcp.h> too small."
670  " %d bytes needed\r\n", SIZEOF(_udp_Socket));
671  if (p != buf)
672  {
673  (*_printf) ("Watt-32 development error: %s", buf);
674  exit (-1);
675  }
676 }
677 
678 static void check_time_t (size_t time_t_size)
679 {
680 #if 0
681  /* I'm not sure a 32-bit 'time_t' is needed for ABI compatibility (?).
682  * \note: a 'long' is still 32-bit on Win64.
683  */
684  if (time_t_size && time_t_size != sizeof(long))
685  {
686  (*_printf) ("Size mismatch in 'time_t'. Your application may break in "
687  "mysterious ways.\n"
688 #if defined(_MSC_VER) || defined(__MINGW32__)
689  "Build with \"-D_USE_32BIT_TIME_T\"\n"
690 #endif
691  );
692  }
693 #endif
694  (void) time_t_size;
695 }
696 #endif /* USE_DEBUG */
697 
698 
699 /*
700  * Return error text for watt_sock_init() result.
701  */
702 const char * W32_CALL sock_init_err (int rc)
703 {
704  enum eth_init_result rc2 = rc;
705 
706  switch (rc2)
707  {
708  case WERR_ILL_DOSX:
709  return _LANG ("Illegal DOS-extender and library combination");
710 
711  case WERR_NO_MEM:
712  return _LANG ("No memory for buffers");
713 
714  case WERR_PKT_ERROR:
715  return _LANG ("Error in " PKTDRVR_STR " interface");
716 
717  case WERR_NO_DRIVER:
718  return _LANG ("No " PKTDRVR_STR " found");
719 
720  case WERR_BOOTP_FAIL:
721  return _LANG ("BOOTP protocol failed");
722 
723  case WERR_DHCP_FAIL:
724  return _LANG ("DHCP protocol failed");
725 
726  case WERR_RARP_FAIL:
727  return _LANG ("RARP protocol failed");
728 
729  case WERR_NO_IPADDR:
730  return _LANG ("Failed to get an IP-address");
731 
732  case WERR_PPPOE_DISC:
733  return _LANG ("Timeout in PPPoE discovery");
734 
735  case WERR_NO_ERROR:
736  break;
737  }
738  return _LANG ("No error");
739 }
740 
741 
747 static BOOL sock_init_called = FALSE;
748 
749 int W32_CALL watt_sock_init (size_t tcp_Sock_size, size_t udp_Sock_size, size_t time_t_size)
750 {
751  static int rc = 0;
752 
753  if (sock_init_called) /* return previous result */
754  return (rc);
755 
756  sock_init_called = TRUE;
757 
758  memdbg_init(); /* Init Fortify or CrtDbg; a possible no-op */
759 
760 #if defined(USE_DEBUG)
761  _printf = printf;
762 #endif
763 
764 #if defined(WIN32)
765  /* Nothing to do here */
766 #elif defined(__HIGHC__)
767  if (_mwenv != PL_ENV)
768  {
769  outsnl (_LANG("\7Only Pharlap DOS extender supported"));
770  return do_exit (rc = WERR_ILL_DOSX);
771  }
772 #elif defined(WATCOM386)
773  if (!dpmi_init())
774  return do_exit (rc = WERR_ILL_DOSX);
775 #endif
776 
777 #if (DOSX & POWERPAK)
778  if (!powerpak_init())
779  {
780  puts ("\7PowerPak initialisation failed");
781  return do_exit (rc = WERR_ILL_DOSX);
782  }
783 #endif
784 
785 #if defined(USE_DEBUG)
786  check_sock_sizes (tcp_Sock_size, udp_Sock_size);
787  check_time_t (time_t_size);
788 #else
789  ARGSUSED (tcp_Sock_size);
790  ARGSUSED (udp_Sock_size);
791  ARGSUSED (time_t_size);
792 #endif
793 
794  /* DOSX: Set DOS far-ptr, get CPU type, use BSWAP
795  * instruction on 486+CPUs, setup DOS transfer buffer.
796  * ALL: Find DOS/Win-version, init timers etc.
797  */
798  init_misc();
799 
800 #if !defined(MAKE_TSR)
802 #endif
803 
804  /* Init PKTDRVR/WinPcap/SwsVpkt, get ether-addr, set
805  * config-hook for parsing TCP-values.
806  */
807  rc = tcp_init();
808 
809  if (rc && !survive_eth) /* if survive we pretend all is ok and go on */
810  return do_exit (rc); /* else failed */
811 
812  _watt_is_init = TRUE;
813 
814  /* UPDATE: 26FEB2006 psuggs@pobox.com
815  * Add a shutdown method to remove and clear the daemons so that
816  * we can reinitialize cleanly.
817  */
818  RUNDOWN_ADD (daemon_clear, 1000);
819 
820  /* Setup the ARP daemon, GvB 2002-09
821  */
822  _arp_init();
823 
824  /* Prepare to parse WATTCP.CFG config options related
825  * to DHCP, SYSLOG, BIND, TFTP, ECHO/DISCARD clients, PPPoE and IPv6.
826  */
827 #if defined(USE_DHCP)
828  DHCP_init();
829 #endif
830 
831 #if defined(USE_BSD_API)
832  syslog_init();
833 #endif
834 
835 #if defined(USE_BIND)
836  res_init0();
837 #endif
838 
839 #if defined(USE_TFTP)
840  tftp_init();
841 #endif
842 
843 #if defined(USE_ECHO_DISC)
845 #endif
846 
847 #if defined(USE_PPPOE)
848  pppoe_init();
849 #endif
850 
851 #if defined(USE_DYNIP_CLI)
852  dynip_init();
853 #endif
854 
855 #if defined(USE_IPV6)
856  _ip6_init();
857 #endif
858 
859 #if defined(USE_IDNA)
860  iconv_init (0);
861 #endif
862 
863  old_break = tcp_cbreak (0x10);
864 
865  /* The only atexit() handler
866  */
867  atexit (/*(_atexit_handler)*/ sock_exit);
868 
869 #if !defined(MAKE_TSR)
870  RUNDOWN_ADD (restore_sig_handlers, 3);
871 #endif
872 
873  if (_watt_no_config && !_watt_user_config_fn)
874  {
875  if (!my_ip_addr)
876  {
877 #if defined(USE_BOOTP)
878  _bootp_on = TRUE; /* if no fixed IP, try BOOTP/DHCP/RARP */
879 #endif
880 #if defined(USE_DHCP)
881  _dhcp_on = TRUE;
882 #endif
883 #if defined(USE_RARP)
884  _rarp_on = TRUE;
885 #endif
886  }
887  else if (debug_on)
888  outsnl (_LANG("Fixed IP configuration."));
889  }
890 
891  else if (!tcp_config(NULL))
892  {
893 #if defined(USE_BOOTP)
894  _bootp_on = TRUE; /* if no config file try BOOTP/DHCP/RARP */
895 #endif
896 #if defined(USE_DHCP)
897  _dhcp_on = TRUE;
898 #endif
899 #if defined(USE_RARP)
900  _rarp_on = TRUE;
901 #endif
902  }
903 
904 #if defined(USE_DEBUG)
905  if (debug_xmit) /* if dbug_init() called */
906  {
907  dbug_open();
908 #if defined(USE_BSD_API)
909  _sock_dbug_open();
910 #if defined(USE_FORTIFY)
911  Fortify_SetOutputFunc (bsd_fortify_print);
912 #endif
913 #endif
914  }
915 #endif
916 
917 #if defined(USE_DHCP)
918  /*
919  * If we read previously configured values okay, skip the below booting.
920  */
921  if (_dhcp_on && DHCP_read_config())
922  {
923  _dhcp_on = FALSE;
924  _bootp_on = FALSE;
925  _rarp_on = FALSE;
926  }
927 #endif
928 
929  /* Test and fix configured values
930  */
931  tcp_post_init();
932 
933  if (_bootp_on || _dhcp_on || _rarp_on)
934  {
936  if (rc && !survive_eth)
937  return do_exit (rc);
938  }
939 
940 #if defined(USE_PPPOE)
941  if (!pppoe_start())
942  {
943  outsnl (_LANG("Timeout waiting for PADS/PADO"));
944  rc = WERR_PPPOE_DISC;
945  if (!survive_eth)
946  return do_exit (rc);
947  }
948 #endif
949 
950  if (!my_ip_addr) /* all boot attempts failed */
951  {
952  outsnl (_LANG("All attempt (config-file/DHCP/BOOTP/RARP) to get "
953  "a IP-address failed.\r\n"
954  "Check your configuration."));
955 
958  rc = WERR_NO_IPADDR;
959  if (!survive_eth)
960  return do_exit (rc);
961  }
962 
963  if (_pkt_inf) /* Warn only if we have a pktdrvr/WinPcap instance */
964  {
965 #if defined(WIN32)
966  if (my_ip_addr && !pkt_check_address(my_ip_addr))
967  (*_printf) ("Warning: using same IP-address (%s) as Winsock.\n\7",
968  _inet_ntoa(NULL,my_ip_addr));
969 #endif
970 
971 #if defined(USE_DEBUG)
972  if (sin_mask == 0)
973  outsnl ("Warning: \"NETMASK\" is 0.0.0.0 !");
974 
975  if (_arp_check_gateways() == 0)
976  outsnl ("Warning: no default gateway!");
977 #endif
978  }
979 
980  if (dynamic_host && !reverse_lookup_myip())
981  outsnl (_LANG("Cannot reverse resolve local IP-address. "
982  "Set \"DYNAMIC_HOST\" = 0."));
983 
984 #if defined(USE_MULTICAST)
985  if (_multicast_on)
986  {
987  /* all multicast level 2 systems must join at startup
988  */
989  join_mcast_group (MCAST_ALL_SYST);
990  }
991 #endif
992 
993 #if defined(USE_FRAGMENTS)
994  /* Initialise IPv4 fragment handling.
995  */
996  ip4_frag_init();
997 #endif
998 
999  /* if "ICMP_MASK_REQ = 1" in wattcp.cfg, send an ICMP_MASK_REQ.
1000  */
1001  if (_do_mask_req)
1002  icmp_send_mask_req();
1003 
1004 #if defined(USE_TFTP)
1005  /*
1006  * If application supplied a tftp_writer hook, try to load
1007  * the specified BOOT-file.
1008  */
1009  if (_tftp_write)
1010  tftp_boot_load();
1011 #endif
1012 
1013 #if defined(USE_ECHO_DISC)
1014  echo_discard_start(); /* start echo/discard services */
1015 #endif
1016 
1017 #if defined(USE_DYNIP_CLI)
1018  dynip_exec();
1019 #endif
1020 
1021  return (rc);
1022 }
1023 
1024 /*
1025  * Old compatibility (if user didn't include <tcp.h>
1026  */
1027 #undef sock_init
1028 int W32_CALL sock_init (void)
1029 {
1030  return watt_sock_init (0, 0, sizeof(time_t));
1031 }
1032 
1033 
1039 void MS_CDECL sock_exit (void)
1040 {
1041  if (_watt_is_init || sock_init_called)
1042  {
1043  _watt_is_init = sock_init_called = FALSE;
1044 
1045  if (!_watt_fatal_error)
1046  tcp_shutdown();
1047 
1048  /* Closed the PKTDRVR/WinPcap etc. No effect if already done.
1049  */
1050  rundown_run();
1051  }
1052 }
1053 
1057 void W32_CALL sock_sig_exit (const char *msg, int sig)
1058 {
1059 #if defined(SIGBREAK)
1060  if (sig == SIGBREAK) /* should only happen for Watcom (from signal.c) */
1061  sig = SIGINT;
1062 #endif
1063 
1064  if (sig == SIGINT)
1065  _watt_cbroke++;
1066 
1067  sock_exit(); /* calls registered rundown functions */
1068 
1069  if (msg)
1070  outsnl (msg);
1071 
1072 #if (DOSX) /* don't pull in _streams[] for SMALL/LARGE model */
1073  fflush (stdout);
1074  fflush (stderr);
1075 #endif
1076 
1077 
1078 #if defined(__HIGHC__)
1079  /*
1080  * If "#pragma on(check_stack)" is in effect somewhere, we're sure
1081  * to crash in an atexit() function. It's not nice, but bypass them
1082  * by calling _exit(). Application should hook SIGINT itself to clean
1083  * itself up. Same applies for djgpp apps.
1084  */
1085  sig = 0; /* calls exit() */
1086 
1087 #elif defined(__DJGPP__)
1088  /*
1089  * Some error (in Watt-32 or djgpp's crt?) causes the INT 1B
1090  * vector not always to be restored when running with CWSDPMI. This
1091  * causes a page fault in CWSDPMI. Not nice, but circumvent this by
1092  * calling _exit(). Not sure if toggling the exceptions will help, so
1093  * leave them alone. NTVDM doesn't seem to mind we calling _exit()...
1094  */
1095 /* __djgpp_exception_toggle(); */
1096  sig = 0;
1097 
1098 #elif !defined(__WATCOMC__)
1099  sig = 0;
1100 #endif
1101 
1102 #if (defined(__BORLANDC__) || defined(__TURBOC__)) && !defined(__FLAT__)
1103  if (_stklen < 0x1000)
1104  _stklen = 0x1000; /* avoid stack-overflow during exit() */
1105 #endif
1106 
1107 #if !defined(__POCC__)
1108  if (sig == SIGINT)
1109  _exit (-1);
1110  else
1111 #endif
1112  exit (-1);
1113 }
1114 
1115 
1116 /*
1117  * Make sure user links the correct C-libs
1118  */
1119 #if defined(WATCOM386)
1120  #if defined(__SW_3R)
1121  #pragma library ("clib3r.lib");
1122  #pragma library ("math387r.lib");
1123 
1124  #else /* __SW_3S */
1125  #pragma library ("clib3s.lib");
1126  #pragma library ("math387s.lib");
1127  #endif
1128 
1129 #elif defined(_MSC_VER) && (_MSC_VER >= 1200) && 0
1130  #if defined(_DEBUG)
1131  #pragma comment (library, "wattcpvc_imp_d.lib")
1132  #else
1133  #pragma comment (library, "wattcpvc_imp.lib")
1134  #endif
1135 
1136 #elif defined(_MSC_VER) && (_MSC_VER >= 700) && 0
1137  #if defined(__SMALL__)
1138  #pragma comment (library, "wattcpMS.lib")
1139  #elif defined(__LARGE__)
1140  #pragma comment (library, "wattcpML.lib")
1141  #elif defined(__386__)
1142  #pragma comment (library, "wattcpMF.lib")
1143  #endif
1144 
1145 #elif defined(__DMC__) && 0
1146  #if defined(WIN32)
1147  #pragma comment (lib, "wattcpd_imp.lib")
1148  #elif defined(__SMALL32__)
1149  #pragma comment (lib, "wattcpDF.lib")
1150  #elif defined(__SMALL__)
1151  #pragma comment (lib, "wattcpDS.lib")
1152  #elif defined(__LARGE__)
1153  #pragma comment (lib, "wattcpDL.lib")
1154  #endif
1155 #endif
1156 
void W32_CALL _arp_init(void)
Setup config-table parse function and add background ARP deamon.
Definition: pcarp.c:1547
void DHCP_init(void)
Initialises the DHCP config-parser.
Definition: pcdhcp.c:1380
int W32_CALL _arp_check_gateways(void)
Return number of default gateways.
Definition: pcarp.c:1752
void W32_CALL DHCP_release(BOOL force)
Possibly send a DHCP release.
Definition: pcdhcp.c:707
BOOL survive_dhcp
Survive a failed DHCP attempt.
Definition: sock_ini.c:151
void echo_discard_init(void)
Called from watt_sock_init(): Setup config-file parser for "echo..." and "discard.." keywords.
Definition: echo.c:117
static BOOL sock_init_called
The main initialisation routine.
Definition: sock_ini.c:747
int _printk_safe
Definition: printk.c:55
int _get_machine_name(char *buf, int size)
Try asking a LAN extension of DOS for a host-name.
Definition: bsdname.c:351
BOOL _watt_is_init
watt_sock_init() done (but with possible failed boot)
Definition: sock_ini.c:157
int tftp_init(void)
Initialize config-hook for TFTP protocol.
Definition: tftp.c:570
BOOL _watt_no_config
run with no config file (embedded/diskless)
Definition: sock_ini.c:135
BOOL survive_rarp
Don't survive a failed RARP attempt.
Definition: sock_ini.c:156
_udp_Socket * _udp_allsocs
list of udp-sockets
Definition: pctcp.c:73
DWORD tcp_recv_win
RWIN for BSD sockets only.
Definition: pctcp.c:135
BOOL survive_eth
GvB 2002-09, allows us to survive without a (working) packet driver at all - in cases where life stil...
Definition: sock_ini.c:139
int reverse_lookup_myip(void)
Do a reverse lookup on `my_ip_addr'.
Definition: udp_rev.c:176
BOOL _eth_ndis3pkt
for DOS-programs only
Definition: pcsed.c:57
void pppoe_init(void)
Set config-parser hook and initial values.
Definition: pppoe.c:166
volatile int _watt_cbroke
Definition: pc_cbrk.c:47
BOOL _dhcp6_on
Try booting using DHCP6 ?
Definition: sock_ini.c:131
static void except_handler(int sig)
Definition: sock_ini.c:266
void MS_CDECL sock_exit(void)
Our only atexit() handler.
Definition: sock_ini.c:1039
Core definitions.
static void setup_sig_handlers(void)
Install signal-handlers for fatal errors; SIGSEGV, SIGILL, SIGTRAP, SIGFPE etc.
Definition: sock_ini.c:372
void pppoe_exit(void)
Close down PPPoE by sending a PADT.
Definition: pppoe.c:209
void echo_discard_start(void)
Starts the echo/discard services (udp/tcp).
Definition: echo.c:129
static int old_break
Original state of DOS's BREAK handler.
Definition: sock_ini.c:160
static BOOL tcp_is_init
tcp_init() called okay.
Definition: sock_ini.c:159
int BOOTP_do_boot(void)
Main BOOTP initialisation.
Definition: pcbootp.c:60
WattUserConfigFunc W32_CALL _watt_user_config(WattUserConfigFunc fn)
A user application may call the `_watt_user_config()' function prior to calling sock_init() to inject...
Definition: sock_ini.c:199
int W32_CALL watt_sock_init(size_t tcp_Sock_size, size_t udp_Sock_size, size_t time_t_size)
Definition: sock_ini.c:749
static int tcp_init(void)
Initialise the PKTDRVR (calls _eth_init()).
Definition: sock_ini.c:499
WORD init_localport(void)
Allocate the "lport_inuse" bit-array from heap.
Definition: ports.c:52
BOOL survive_bootp
Survive a failed BOOTP attempt.
Definition: sock_ini.c:145
DWORD sin_mask
our net-mask, 255.255.255.0
Definition: pctcp.c:71
static BOOL use_except
Some target dependent functions.
Definition: sock_ini.c:223
int pkt_get_mtu(void)
Return PKTDRVR maximum-transmit-units (MTU).
Definition: pcpkt.c:489
BOOL _rarp_on
Try booting using RARP ?
Definition: sock_ini.c:132
int W32_CALL DHCP_read_config(void)
Called from watt_sock_init() after "\c WATTCP.CFG" has been parsed.
Definition: pcdhcp.c:1774
void W32_CALL sock_sig_exit(const char *msg, int sig)
Exit handler for unhandled signals.
Definition: sock_ini.c:1057
BOOL _watt_do_exit
exit program when all boot attempts failed
Definition: sock_ini.c:134
int pppoe_start(void)
Start PPPoE by doing a Discovery.
Definition: pppoe.c:184
BOOL _dhcp_on
Try booting using DHCP ?
Definition: sock_ini.c:130
char hostname[MAX_HOSTLEN+1]
Our configured hostname.
Definition: pctcp.c:59
Definition: zinftree.h:24
static int do_exit(int code)
Exit application if _watt_do_exit is TRUE (the default).
Definition: sock_ini.c:211
struct pkt_info * _pkt_inf
module data that will be locked
Definition: pcpkt.c:64
int W32_CALL tcp_cbreak(int mode)
Sets our break mode.
Definition: pc_cbrk.c:207
int set_cbreak(int want_brk)
Sets normal and extended BREAK mode.
Definition: pc_cbrk.c:129
DWORD my_ip_addr
our IP address
Definition: pctcp.c:70
BOOL _watt_fatal_error
Definition: misc.c:60
static int tcp_do_bootp(BOOL try_bootp, BOOL try_dhcp, BOOL try_rarp)
Try to boot-up the stack using BOOTP, DHCP or RARP.
Definition: sock_ini.c:593
int W32_CALL _eth_init(void)
Initialize the network driver interface.
Definition: pcsed.c:659
static void tcp_shutdown(void)
Abort all TCP sockets, release DHCP lease and restore signal handlers.
Definition: sock_ini.c:462
int DHCP_do_boot(void)
Our first time DHCP handler.
Definition: pcdhcp.c:1056
BOOL iconv_init(WORD code_page)
Initialise iconv; find codepage and mapping functions to use.
Definition: idna.c:158
void W32_CALL init_misc(void)
Initialise various stuff.
Definition: misc.c:324
_tcp_Socket * _tcp_allsocs
list of tcp-sockets
Definition: pctcp.c:137
BOOL _do_mask_req
do an "ICMP Mask Request" when configured
Definition: sock_ini.c:133
char *W32_CALL _inet_ntoa(char *s, DWORD ip)
Convert an IP-address 'ip' into a string.
Definition: netaddr.c:43
BOOL _bootp_on
Try booting using BOOTP ?
Definition: sock_ini.c:129
static void tcp_post_init(void)
Initialise stuff based on configured values.
Definition: sock_ini.c:528
W32_FUNC void W32_CALL ReadEthersFile(void)
Read the /etc/ethers file.
Definition: geteth.c:104