From 5658c1d96012ec697d4a8f0930111ab9c9a6c9f4 Mon Sep 17 00:00:00 2001 From: Christophe Massiot Date: Mon, 4 Mar 2002 23:56:38 +0000 Subject: [PATCH] * IPv6 network module, courtesy of Alexis Guillard , for BT ; * --6 and --4 options to force IPv6 or IPv4 (FIXME: it should be -6 and -4 but I don't know how to do it with the new configuration module) ; * Channel manager now uses a socket from the network plug-in and is more portable (and probably broken, too :) ; * input_ReadPS and input_ReadTS are now in mpeg_system.c to be more easily reused by plug-ins other than mpeg_ps and mpeg_ts. That's all for tonight. --- AUTHORS | 4 + Makefile | 1 + configure | 140 ++++++++------- configure.in | 6 + include/common.h | 6 +- include/config.h | 3 + include/input_ext-plugins.h | 7 +- plugins/access/http.c | 10 +- plugins/access/udp.c | 30 +++- plugins/mpeg_system/mpeg_ps.c | 113 +----------- plugins/mpeg_system/mpeg_ts.c | 49 +---- plugins/network/Makefile | 1 + plugins/network/ipv4.c | 15 +- plugins/network/ipv6.c | 325 ++++++++++++++++++++++++++++++++++ src/input/mpeg_system.c | 163 ++++++++++++++++- src/interface/main.c | 4 +- src/misc/modules_plugin.h | 4 +- src/misc/netutils.c | 152 ++++------------ 18 files changed, 689 insertions(+), 344 deletions(-) create mode 100644 plugins/network/ipv6.c diff --git a/AUTHORS b/AUTHORS index 6e1b85fa6f..a9786400e6 100644 --- a/AUTHORS +++ b/AUTHORS @@ -125,6 +125,10 @@ E: jeanphi@via.ecp.fr C: jeanphi D: Bug fixes +N: Alexis Guillard +E: alexis.guillard@bt.com +D: IPv6 + N: Shane Harper E: shanegh@optusnet.com.au D: SDL plugin fixes and enhancements diff --git a/Makefile b/Makefile index 1b94c638c3..6859762499 100644 --- a/Makefile +++ b/Makefile @@ -125,6 +125,7 @@ PLUGINS_TARGETS := ac3_adec/ac3_adec \ mpeg_adec/mpeg_adec \ mpeg_vdec/mpeg_vdec \ network/ipv4 \ + network/ipv6 \ qnx/qnx \ qt/qt \ sdl/sdl \ diff --git a/configure b/configure index 8e4e8c4cbb..a774fb803b 100755 --- a/configure +++ b/configure @@ -6576,6 +6576,20 @@ then PLUGINS="${PLUGINS} null" fi +cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "in6_addr" >/dev/null 2>&1; then + rm -rf conftest* + + PLUGINS="${PLUGINS} ipv6" +fi +rm -f conftest* + + # Check whether --enable-rc or --disable-rc was given. if test "${enable_rc+set}" = set; then enableval="$enable_rc" @@ -6606,17 +6620,17 @@ if test "${with_mad+set}" = set; then do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:6610: checking for $ac_hdr" >&5 +echo "configure:6624: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:6620: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:6634: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -6646,7 +6660,7 @@ fi done echo $ac_n "checking for mad_bit_init in -lmad""... $ac_c" 1>&6 -echo "configure:6650: checking for mad_bit_init in -lmad" >&5 +echo "configure:6664: checking for mad_bit_init in -lmad" >&5 ac_lib_var=`echo mad'_'mad_bit_init | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -6654,7 +6668,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lmad $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6683: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -6722,17 +6736,17 @@ then do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:6726: checking for $ac_hdr" >&5 +echo "configure:6740: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:6736: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:6750: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -6755,7 +6769,7 @@ EOF PLUGINS="${PLUGINS} dsp" echo $ac_n "checking for main in -lossaudio""... $ac_c" 1>&6 -echo "configure:6759: checking for main in -lossaudio" >&5 +echo "configure:6773: checking for main in -lossaudio" >&5 ac_lib_var=`echo ossaudio'_'main | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -6763,14 +6777,14 @@ else ac_save_LIBS="$LIBS" LIBS="-lossaudio $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6788: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -6806,7 +6820,7 @@ if test "${enable_esd+set}" = set; then # Extract the first word of "esd-config", so it can be a program name with args. set dummy esd-config; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:6810: checking for $ac_word" >&5 +echo "configure:6824: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_ESD_CONFIG'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -6857,7 +6871,7 @@ if test "${enable_arts+set}" = set; then # Extract the first word of "artsc-config", so it can be a program name with args. set dummy artsc-config; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:6861: checking for $ac_word" >&5 +echo "configure:6875: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_ARTS_CONFIG'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -6915,17 +6929,17 @@ else do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:6919: checking for $ac_hdr" >&5 +echo "configure:6933: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:6929: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:6943: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -6970,17 +6984,17 @@ fi do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:6974: checking for $ac_hdr" >&5 +echo "configure:6988: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:6984: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:6998: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -7023,17 +7037,17 @@ if test "x$enableval" != "xno" -a x$SYS != xmingw32 do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:7027: checking for $ac_hdr" >&5 +echo "configure:7041: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:7037: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:7051: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -7121,7 +7135,7 @@ fi # Extract the first word of "sdl12-config", so it can be a program name with args. set dummy sdl12-config; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:7125: checking for $ac_word" >&5 +echo "configure:7139: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_SDL12_CONFIG'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -7161,7 +7175,7 @@ fi # Extract the first word of "sdl11-config", so it can be a program name with args. set dummy sdl11-config; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:7165: checking for $ac_word" >&5 +echo "configure:7179: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_SDL11_CONFIG'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -7202,7 +7216,7 @@ fi # Extract the first word of "sdl-config", so it can be a program name with args. set dummy sdl-config; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:7206: checking for $ac_word" >&5 +echo "configure:7220: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_SDL_CONFIG'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -7248,17 +7262,17 @@ fi do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:7252: checking for $ac_hdr" >&5 +echo "configure:7266: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:7262: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:7276: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -7328,17 +7342,17 @@ fi do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:7332: checking for $ac_hdr" >&5 +echo "configure:7346: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:7342: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:7356: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -7367,7 +7381,7 @@ done else echo $ac_n "checking for directX headers in ${withval}""... $ac_c" 1>&6 -echo "configure:7371: checking for directX headers in ${withval}" >&5 +echo "configure:7385: checking for directX headers in ${withval}" >&5 if test -f ${withval}/ddraw.h then PLUGINS="${PLUGINS} directx" @@ -7476,7 +7490,7 @@ if test "${enable_gnome+set}" = set; then # Extract the first word of "gnome-config", so it can be a program name with args. set dummy gnome-config; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:7480: checking for $ac_word" >&5 +echo "configure:7494: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_GNOME_CONFIG'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -7521,17 +7535,17 @@ fi do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:7525: checking for $ac_hdr" >&5 +echo "configure:7539: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:7535: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:7549: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -7591,7 +7605,7 @@ fi # Extract the first word of "gtk12-config", so it can be a program name with args. set dummy gtk12-config; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:7595: checking for $ac_word" >&5 +echo "configure:7609: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_GTK12_CONFIG'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -7630,7 +7644,7 @@ fi # Extract the first word of "gtk-config", so it can be a program name with args. set dummy gtk-config; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:7634: checking for $ac_word" >&5 +echo "configure:7648: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_GTK_CONFIG'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -7680,17 +7694,17 @@ fi do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:7684: checking for $ac_hdr" >&5 +echo "configure:7698: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:7694: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:7708: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -7748,17 +7762,17 @@ if test x$enable_x11 != xno && do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:7752: checking for $ac_hdr" >&5 +echo "configure:7766: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:7762: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:7776: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -7811,17 +7825,17 @@ if test x$enable_xvideo != xno && do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:7815: checking for $ac_hdr" >&5 +echo "configure:7829: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:7825: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:7839: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -7845,7 +7859,7 @@ EOF saved_CFLAGS=$CFLAGS CFLAGS="$CFLAGS -L$x_libraries -lX11 -lXext" echo $ac_n "checking for XvSetPortAttribute in -lXv_pic""... $ac_c" 1>&6 -echo "configure:7849: checking for XvSetPortAttribute in -lXv_pic" >&5 +echo "configure:7863: checking for XvSetPortAttribute in -lXv_pic" >&5 ac_lib_var=`echo Xv_pic'_'XvSetPortAttribute | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -7853,7 +7867,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lXv_pic $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7882: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -7911,17 +7925,17 @@ if test x$enable_lirc = xyes then ac_safe=`echo "lirc/lirc_client.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for lirc/lirc_client.h""... $ac_c" 1>&6 -echo "configure:7915: checking for lirc/lirc_client.h" >&5 +echo "configure:7929: checking for lirc/lirc_client.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:7925: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:7939: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -7938,7 +7952,7 @@ fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 echo $ac_n "checking for lirc_init in -llirc_client""... $ac_c" 1>&6 -echo "configure:7942: checking for lirc_init in -llirc_client" >&5 +echo "configure:7956: checking for lirc_init in -llirc_client" >&5 ac_lib_var=`echo lirc_client'_'lirc_init | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -7946,7 +7960,7 @@ else ac_save_LIBS="$LIBS" LIBS="-llirc_client $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7975: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -7997,17 +8011,17 @@ if test "${enable_alsa+set}" = set; then then ac_safe=`echo "alsa/asoundlib.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for alsa/asoundlib.h""... $ac_c" 1>&6 -echo "configure:8001: checking for alsa/asoundlib.h" >&5 +echo "configure:8015: checking for alsa/asoundlib.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:8011: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:8025: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -8024,7 +8038,7 @@ fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 echo $ac_n "checking for main in -lasound""... $ac_c" 1>&6 -echo "configure:8028: checking for main in -lasound" >&5 +echo "configure:8042: checking for main in -lasound" >&5 ac_lib_var=`echo asound'_'main | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -8032,14 +8046,14 @@ else ac_save_LIBS="$LIBS" LIBS="-lasound $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8057: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else diff --git a/configure.in b/configure.in index 72d8048344..b5bca45d81 100644 --- a/configure.in +++ b/configure.in @@ -960,6 +960,12 @@ then PLUGINS="${PLUGINS} null" fi +dnl +dnl ipv6 plugin +dnl +AC_EGREP_HEADER(in6_addr,netinet/in.h,[ + PLUGINS="${PLUGINS} ipv6"]) + dnl dnl rc plugin dnl diff --git a/include/common.h b/include/common.h index 6449069fc9..c5b7572893 100644 --- a/include/common.h +++ b/include/common.h @@ -3,7 +3,7 @@ * Collection of useful common types and macros definitions ***************************************************************************** * Copyright (C) 1998, 1999, 2000 VideoLAN - * $Id: common.h,v 1.83 2002/03/03 04:37:29 sam Exp $ + * $Id: common.h,v 1.84 2002/03/04 23:56:37 massiot Exp $ * * Authors: Samuel Hocevar * Vincent Seguin @@ -552,8 +552,12 @@ typedef struct module_symbols_s struct pes_packet_s * ); struct es_descriptor_s * ( * input_ParsePS ) ( struct input_thread_s *, struct data_packet_s * ); + ssize_t ( * input_ReadPS ) ( struct input_thread_s *, + struct data_packet_s ** ); void ( * input_DemuxPS ) ( struct input_thread_s *, struct data_packet_s * ); + ssize_t ( * input_ReadTS ) ( struct input_thread_s *, + struct data_packet_s ** ); void ( * input_DemuxTS ) ( struct input_thread_s *, struct data_packet_s * ); void ( * input_DemuxPSI ) ( struct input_thread_s *, diff --git a/include/config.h b/include/config.h index a042409a50..f4aeddaf94 100644 --- a/include/config.h +++ b/include/config.h @@ -346,6 +346,9 @@ #define INPUT_DVD_DEVICE_VAR "dvd_device" /* VCD defaults */ #define INPUT_VCD_DEVICE_VAR "vcd_device" +/* IPv6, IPv4 */ +#define INPUT_IPV6_VAR "6" +#define INPUT_IPV4_VAR "4" /* * Decoders option names diff --git a/include/input_ext-plugins.h b/include/input_ext-plugins.h index 57cd0f27e0..f83e04376c 100644 --- a/include/input_ext-plugins.h +++ b/include/input_ext-plugins.h @@ -3,7 +3,7 @@ * but exported to plug-ins ***************************************************************************** * Copyright (C) 1999-2002 VideoLAN - * $Id: input_ext-plugins.h,v 1.20 2002/03/02 03:53:54 xav Exp $ + * $Id: input_ext-plugins.h,v 1.21 2002/03/04 23:56:37 massiot Exp $ * * Authors: Christophe Massiot * @@ -193,6 +193,7 @@ static __inline__ void input_NullPacket( input_thread_t * p_input, * Constants *****************************************************************************/ #define TS_PACKET_SIZE 188 /* Size of a TS packet */ +#define TS_SYNC_CODE 0x47 /* First byte of a TS packet */ #define PSI_SECTION_SIZE 4096 /* Maximum size of a PSI section */ #define PAT_UNINITIALIZED (1 << 6) @@ -286,8 +287,10 @@ typedef struct stream_ps_data_s void input_ParsePES ( struct input_thread_s *, struct es_descriptor_s * ); void input_GatherPES ( struct input_thread_s *, struct data_packet_s *, struct es_descriptor_s *, boolean_t, boolean_t ); +ssize_t input_ReadPS ( struct input_thread_s *, struct data_packet_s ** ); es_descriptor_t * input_ParsePS( struct input_thread_s *, struct data_packet_s * ); +ssize_t input_ReadTS ( struct input_thread_s *, struct data_packet_s ** ); void input_DemuxPS ( struct input_thread_s *, struct data_packet_s * ); void input_DemuxTS ( struct input_thread_s *, struct data_packet_s * ); void input_DemuxPSI ( struct input_thread_s *, struct data_packet_s *, @@ -295,8 +298,10 @@ void input_DemuxPSI ( struct input_thread_s *, struct data_packet_s *, #else # define input_ParsePES p_symbols->input_ParsePES # define input_GatherPES p_symbols->input_GatherPES +# define input_ReadPS p_symbols->input_ReadPS # define input_ParsePS p_symbols->input_ParsePS # define input_DemuxPS p_symbols->input_DemuxPS +# define input_ReadTS p_symbols->input_ReadTS # define input_DemuxTS p_symbols->input_DemuxTS # define input_DemuxPSI p_symbols->input_DemuxPSI #endif diff --git a/plugins/access/http.c b/plugins/access/http.c index befd1b240e..47144b7c80 100644 --- a/plugins/access/http.c +++ b/plugins/access/http.c @@ -2,7 +2,7 @@ * http.c: HTTP access plug-in ***************************************************************************** * Copyright (C) 2001, 2002 VideoLAN - * $Id: http.c,v 1.1 2002/03/01 00:33:18 massiot Exp $ + * $Id: http.c,v 1.2 2002/03/04 23:56:37 massiot Exp $ * * Authors: Christophe Massiot * @@ -230,6 +230,14 @@ static int HTTPOpen( input_thread_t * p_input ) } p_access_data->psz_network = NULL; + if( config_GetIntVariable( INPUT_IPV4_VAR ) ) + { + p_access_data->psz_network = "ipv4"; + } + if( config_GetIntVariable( INPUT_IPV6_VAR ) ) + { + p_access_data->psz_network = "ipv6"; + } if( p_input->psz_access != NULL ) { /* Find out which shortcut was used */ diff --git a/plugins/access/udp.c b/plugins/access/udp.c index 307383e139..3be691f39c 100644 --- a/plugins/access/udp.c +++ b/plugins/access/udp.c @@ -2,7 +2,7 @@ * udp.c: raw UDP access plug-in ***************************************************************************** * Copyright (C) 2001, 2002 VideoLAN - * $Id: udp.c,v 1.1 2002/03/01 00:33:18 massiot Exp $ + * $Id: udp.c,v 1.2 2002/03/04 23:56:37 massiot Exp $ * * Authors: Christophe Massiot * @@ -107,6 +107,15 @@ static int UDPOpen( input_thread_t * p_input ) int i_bind_port = 0, i_server_port = 0; network_socket_t socket_desc; + if( config_GetIntVariable( INPUT_IPV4_VAR ) ) + { + psz_network = "ipv4"; + } + if( config_GetIntVariable( INPUT_IPV6_VAR ) ) + { + psz_network = "ipv6"; + } + if( p_input->psz_access != NULL ) { /* Find out which shortcut was used */ @@ -130,6 +139,14 @@ static int UDPOpen( input_thread_t * p_input ) while( *psz_parser && *psz_parser != ':' && *psz_parser != '@' ) { + if( *psz_parser == '[' ) + { + /* IPv6 address */ + while( *psz_parser && *psz_parser != ']' ) + { + psz_parser++; + } + } psz_parser++; } @@ -150,7 +167,8 @@ static int UDPOpen( input_thread_t * p_input ) if( *psz_parser == '@' ) { /* Found bind address or bind port */ - *psz_parser = '\0'; /* Terminate server port or name if necessary */ psz_parser++; + *psz_parser = '\0'; /* Terminate server port or name if necessary */ + psz_parser++; if( *psz_parser && *psz_parser != ':' ) { @@ -159,6 +177,14 @@ static int UDPOpen( input_thread_t * p_input ) while( *psz_parser && *psz_parser != ':' ) { + if( *psz_parser == '[' ) + { + /* IPv6 address */ + while( *psz_parser && *psz_parser != ']' ) + { + psz_parser++; + } + } psz_parser++; } } diff --git a/plugins/mpeg_system/mpeg_ps.c b/plugins/mpeg_system/mpeg_ps.c index 16526811e4..3944ad9653 100644 --- a/plugins/mpeg_system/mpeg_ps.c +++ b/plugins/mpeg_system/mpeg_ps.c @@ -2,7 +2,7 @@ * mpeg_ps.c : Program Stream input module for vlc ***************************************************************************** * Copyright (C) 2000-2001 VideoLAN - * $Id: mpeg_ps.c,v 1.4 2002/03/01 00:33:18 massiot Exp $ + * $Id: mpeg_ps.c,v 1.5 2002/03/04 23:56:37 massiot Exp $ * * Authors: Christophe Massiot * @@ -83,113 +83,6 @@ static void input_getfunctions( function_list_t * p_function_list ) #undef input } -/* - * Data reading functions - */ - -/***************************************************************************** - * PSRead: reads one PS packet - *****************************************************************************/ -#define PEEK( SIZE ) \ - i_error = input_Peek( p_input, &p_peek, SIZE ); \ - if( i_error == -1 ) \ - { \ - return( -1 ); \ - } \ - else if( i_error < SIZE ) \ - { \ - /* EOF */ \ - return( 0 ); \ - } - -static __inline__ ssize_t PSRead( input_thread_t * p_input, - data_packet_t ** pp_data ) -{ - byte_t * p_peek; - size_t i_packet_size; - ssize_t i_error, i_read; - - /* Read what we believe to be a packet header. */ - PEEK( 4 ); - - if( *p_peek || *(p_peek + 1) || *(p_peek + 2) != 1 ) - { - if( *p_peek || *(p_peek + 1) || *(p_peek + 2) ) - { - /* It is common for MPEG-1 streams to pad with zeros - * (although it is forbidden by the recommendation), so - * don't bother everybody in this case. */ - intf_WarnMsg( 3, "input warning: garbage at input (0x%x%x%x%x)", - *p_peek, *(p_peek + 1), *(p_peek + 2), *(p_peek + 3) ); - } - - /* This is not the startcode of a packet. Read the stream - * until we find one. */ - while( *p_peek || *(p_peek + 1) || *(p_peek + 2) != 1 ) - { - p_input->p_current_data++; - PEEK( 4 ); - } - /* Packet found. */ - } - - /* 0x1B9 == SYSTEM_END_CODE, it is only 4 bytes long. */ - if( p_peek[3] != 0xB9 ) - { - /* The packet is at least 6 bytes long. */ - PEEK( 6 ); - - if( p_peek[3] != 0xBA ) - { - /* That's the case for all packets, except pack header. */ - i_packet_size = (p_peek[4] << 8) | p_peek[5]; - } - else - { - /* Pack header. */ - if( (p_peek[4] & 0xC0) == 0x40 ) - { - /* MPEG-2 */ - i_packet_size = 8; - } - else if( (p_peek[4] & 0xF0) == 0x20 ) - { - /* MPEG-1 */ - i_packet_size = 6; - } - else - { - intf_ErrMsg( "Unable to determine stream type" ); - return( -1 ); - } - } - } - else - { - /* System End Code */ - i_packet_size = -2; - } - - /* Fetch a packet of the appropriate size. */ - i_read = input_SplitBuffer( p_input, pp_data, i_packet_size + 6 ); - if( i_read <= 0 ) - { - return( i_read ); - } - - /* In MPEG-2 pack headers we still have to read stuffing bytes. */ - if( ((*pp_data)->p_demux_start[3] == 0xBA) && (i_packet_size == 8) ) - { - size_t i_stuffing = ((*pp_data)->p_demux_start[13] & 0x7); - /* Force refill of the input buffer - though we don't care - * about p_peek. Please note that this is unoptimized. */ - PEEK( i_stuffing ); - p_input->p_current_data += i_stuffing; - } - - return( 1 ); -} - /***************************************************************************** * PSInit: initializes PS structures *****************************************************************************/ @@ -266,7 +159,7 @@ static int PSInit( input_thread_t * p_input ) ssize_t i_result; data_packet_t * p_data; - i_result = PSRead( p_input, &p_data ); + i_result = input_ReadPS( p_input, &p_data ); if( i_result == 0 ) { @@ -413,7 +306,7 @@ static int PSDemux( input_thread_t * p_input ) data_packet_t * p_data; ssize_t i_result; - i_result = PSRead( p_input, &p_data ); + i_result = input_ReadPS( p_input, &p_data ); if( i_result <= 0 ) { diff --git a/plugins/mpeg_system/mpeg_ts.c b/plugins/mpeg_system/mpeg_ts.c index d918f2680d..809bf9cf07 100644 --- a/plugins/mpeg_system/mpeg_ts.c +++ b/plugins/mpeg_system/mpeg_ts.c @@ -2,7 +2,7 @@ * mpeg_ts.c : Transport Stream input module for vlc ***************************************************************************** * Copyright (C) 2000-2001 VideoLAN - * $Id: mpeg_ts.c,v 1.4 2002/03/01 00:33:18 massiot Exp $ + * $Id: mpeg_ts.c,v 1.5 2002/03/04 23:56:37 massiot Exp $ * * Authors: Henri Fallon * @@ -39,8 +39,6 @@ * Constants *****************************************************************************/ #define TS_READ_ONCE 200 -#define TS_PACKET_SIZE 188 -#define TS_SYNC_CODE 0x47 /***************************************************************************** * Local prototypes @@ -163,18 +161,6 @@ static void TSEnd( input_thread_t * p_input ) * Returns -1 in case of error, 0 in case of EOF, otherwise the number of * packets. *****************************************************************************/ -#define PEEK( SIZE ) \ - i_error = input_Peek( p_input, &p_peek, SIZE ); \ - if( i_error == -1 ) \ - { \ - return( -1 ); \ - } \ - else if( i_error < SIZE ) \ - { \ - /* EOF */ \ - return( 0 ); \ - } - static int TSDemux( input_thread_t * p_input ) { int i_read_once = (p_input->i_mtu ? @@ -185,38 +171,13 @@ static int TSDemux( input_thread_t * p_input ) for( i = 0; i < i_read_once; i++ ) { data_packet_t * p_data; - ssize_t i_read, i_error; - byte_t * p_peek; - - PEEK( 1 ); - - if( *p_peek != TS_SYNC_CODE ) - { - intf_WarnMsg( 3, "input warning: garbage at input (%x)", *p_peek ); - - if( p_input->i_mtu ) - { - /* Try to resync on next packet. */ - PEEK( TS_PACKET_SIZE ); - p_input->p_current_data += TS_PACKET_SIZE; - } - else - { - /* Move forward until we find 0x47 (and hope it's the good - * one... FIXME) */ - while( *p_peek != TS_SYNC_CODE ) - { - p_input->p_current_data++; - PEEK( 1 ); - } - } - } + ssize_t i_result; - i_read = input_SplitBuffer( p_input, &p_data, TS_PACKET_SIZE ); + i_result = input_ReadTS( p_input, &p_data ); - if( i_read <= 0 ) + if( i_result <= 0 ) { - return( i_read ); + return( i_result ); } input_DemuxTS( p_input, p_data ); diff --git a/plugins/network/Makefile b/plugins/network/Makefile index 2046f8792d..6c75b41efc 100644 --- a/plugins/network/Makefile +++ b/plugins/network/Makefile @@ -1 +1,2 @@ ipv4_SOURCES = ipv4.c +ipv6_SOURCES = ipv6.c diff --git a/plugins/network/ipv4.c b/plugins/network/ipv4.c index 293276f3d2..bae150a6d3 100644 --- a/plugins/network/ipv4.c +++ b/plugins/network/ipv4.c @@ -2,9 +2,10 @@ * ipv4.c: IPv4 network abstraction layer ***************************************************************************** * Copyright (C) 2001, 2002 VideoLAN - * $Id: ipv4.c,v 1.3 2002/03/02 03:53:55 xav Exp $ + * $Id: ipv4.c,v 1.4 2002/03/04 23:56:37 massiot Exp $ * * Authors: Christophe Massiot + * Mathias Kretschmer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -153,7 +154,9 @@ static int OpenUDP( network_socket_t * p_socket ) int i_bind_port = p_socket->i_bind_port; char * psz_server_addr = p_socket->psz_server_addr; int i_server_port = p_socket->i_server_port; - char * psz_bind_win32; /* WIN32 multicast kludge */ +#ifdef WIN32 + char * psz_bind_win32; /* WIN32 multicast kludge */ +#endif int i_handle, i_opt, i_opt_size; struct sockaddr_in sock; @@ -226,12 +229,12 @@ static int OpenUDP( network_socket_t * p_socket ) if (IN_MULTICAST( ntohl( inet_addr(psz_bind_addr) ) ) ) { - psz_bind_win32 = NULL ; + psz_bind_win32 = NULL ; } if ( BuildAddr( &sock, psz_bind_win32, i_bind_port ) == -1 ) #else - if ( BuildAddr( &sock, psz_bind_addr, i_bind_port ) == -1 ) -#endif + if ( BuildAddr( &sock, psz_bind_addr, i_bind_port ) == -1 ) +#endif { close( i_handle ); return( -1 ); @@ -275,7 +278,7 @@ static int OpenUDP( network_socket_t * p_socket ) struct ip_mreq imr; imr.imr_interface.s_addr = INADDR_ANY; imr.imr_multiaddr.s_addr = inet_addr(psz_bind_addr); -#endif +#endif if( setsockopt( i_handle, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&imr, sizeof(struct ip_mreq) ) == -1 ) { diff --git a/plugins/network/ipv6.c b/plugins/network/ipv6.c new file mode 100644 index 0000000000..209bf68d43 --- /dev/null +++ b/plugins/network/ipv6.c @@ -0,0 +1,325 @@ +/***************************************************************************** + * ipv6.c: IPv6 network abstraction layer + ***************************************************************************** + * Copyright (C) 2002 VideoLAN + * $Id: ipv6.c,v 1.1 2002/03/04 23:56:37 massiot Exp $ + * + * Authors: Alexis Guillard + * Christophe Massiot + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + *****************************************************************************/ + +/***************************************************************************** + * Preamble + *****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_UNISTD_H +# include +#elif defined( _MSC_VER ) && defined( _WIN32 ) +# include +#endif + +#ifdef WIN32 +# include +# include +#elif !defined( SYS_BEOS ) && !defined( SYS_NTO ) +# include /* hostent ... */ +# include +# include +# ifdef HAVE_ARPA_INET_H +# include /* inet_ntoa(), inet_aton() */ +# endif +#endif + +#include "network.h" + +/* Default MTU used for UDP socket. FIXME: we should issue some ioctl() + * call to get that value from the interface driver. */ +#define DEFAULT_MTU 1500 + +/***************************************************************************** + * Local prototypes + *****************************************************************************/ +static void getfunctions( function_list_t * ); +static int NetworkOpen( struct network_socket_s * ); + +/***************************************************************************** + * Build configuration tree. + *****************************************************************************/ +MODULE_CONFIG_START +MODULE_CONFIG_STOP + +MODULE_INIT_START + SET_DESCRIPTION( "IPv6 network abstraction layer" ) + ADD_CAPABILITY( NETWORK, 40 ) + ADD_SHORTCUT( "ipv6" ) +MODULE_INIT_STOP + +MODULE_ACTIVATE_START + getfunctions( &p_module->p_functions->network ); +MODULE_ACTIVATE_STOP + +MODULE_DEACTIVATE_START +MODULE_DEACTIVATE_STOP + +/***************************************************************************** + * Functions exported as capabilities. They are declared as static so that + * we don't pollute the namespace too much. + *****************************************************************************/ +static void getfunctions( function_list_t * p_function_list ) +{ +#define f p_function_list->functions.network + f.pf_open = NetworkOpen; +#undef f +} + +/***************************************************************************** + * BuildAddr: utility function to build a struct sockaddr_in6 + *****************************************************************************/ +static int BuildAddr( struct sockaddr_in6 * p_socket, + char * psz_address, int i_port ) +{ + /* Reset struct */ + memset( p_socket, 0, sizeof( struct sockaddr_in6 ) ); + p_socket->sin6_family = AF_INET6; /* family */ + p_socket->sin6_port = htons( i_port ); + if( psz_address == NULL ) + { + p_socket->sin6_addr = in6addr_any; + } + else if( *psz_address != '[' + || psz_address[strlen(psz_address) - 1] != ']' ) + { + intf_ErrMsg( "ipv6: IPv6 address is invalid, discarding" ); + return( -1 ); + } + else + { + psz_address++; + psz_address[strlen(psz_address) - 1] = '\0' ; + inet_pton(AF_INET6, psz_address, &p_socket->sin6_addr.s6_addr); + } + return( 0 ); +} + +/***************************************************************************** + * OpenUDP: open a UDP socket + ***************************************************************************** + * psz_bind_addr, i_bind_port : address and port used for the bind() + * system call. If psz_bind_addr == NULL, the socket is bound to + * in6addr_any and broadcast reception is enabled. If i_bind_port == 0, + * 1234 is used. If psz_bind_addr is a multicast (class D) address, + * join the multicast group. + * psz_server_addr, i_server_port : address and port used for the connect() + * system call. It can avoid receiving packets from unauthorized IPs. + * Its use leads to great confusion and is currently discouraged. + * This function returns -1 in case of error. + *****************************************************************************/ +static int OpenUDP( network_socket_t * p_socket ) +{ + char * psz_bind_addr = p_socket->psz_bind_addr; + int i_bind_port = p_socket->i_bind_port; + char * psz_server_addr = p_socket->psz_server_addr; + int i_server_port = p_socket->i_server_port; + + int i_handle, i_opt, i_opt_size; + struct sockaddr_in6 sock; + + if( i_bind_port == 0 ) + { + i_bind_port = config_GetIntVariable( INPUT_PORT_VAR ); + } + + /* Open a SOCK_DGRAM (UDP) socket, in the AF_INET6 domain, automatic (0) + * protocol */ + if( (i_handle = socket( AF_INET6, SOCK_DGRAM, 0 )) == -1 ) + { + intf_ErrMsg( "ipv6 error: cannot create socket (%s)", strerror(errno) ); + return( -1 ); + } + + /* We may want to reuse an already used socket */ + i_opt = 1; + if( setsockopt( i_handle, SOL_SOCKET, SO_REUSEADDR, + (void *) &i_opt, sizeof( i_opt ) ) == -1 ) + { + intf_ErrMsg( "ipv6 error: cannot configure socket (SO_REUSEADDR: %s)", + strerror(errno)); + close( i_handle ); + return( -1 ); + } + + /* Increase the receive buffer size to 1/2MB (8Mb/s during 1/2s) to avoid + * packet loss caused by scheduling problems */ + i_opt = 0x80000; + if( setsockopt( i_handle, SOL_SOCKET, SO_RCVBUF, + (void *) &i_opt, sizeof( i_opt ) ) == -1 ) + { + intf_WarnMsg( 1, + "ipv6 warning: cannot configure socket (SO_RCVBUF: %s)", + strerror(errno)); + } + + /* Check if we really got what we have asked for, because Linux, etc. + * will silently limit the max buffer size to net.core.rmem_max which + * is typically only 65535 bytes */ + i_opt = 0; + i_opt_size = sizeof( i_opt ); + if( getsockopt( i_handle, SOL_SOCKET, SO_RCVBUF, + (void*) &i_opt, &i_opt_size ) == -1 ) + { + intf_WarnMsg( 1, "ipv6 warning: cannot query socket (SO_RCVBUF: %s)", + strerror(errno)); + } + else if( i_opt < 0x80000 ) + { + intf_WarnMsg( 1, "ipv6 warning: socket buffer size is 0x%x" + " instead of 0x%x", i_opt, 0x80000 ); + } + + /* Build the local socket */ + if ( BuildAddr( &sock, psz_bind_addr, i_bind_port ) == -1 ) + { + close( i_handle ); + return( -1 ); + } + + /* Bind it */ + if( bind( i_handle, (struct sockaddr *)&sock, sizeof( sock ) ) < 0 ) + { + intf_ErrMsg( "ipv6 error: cannot bind socket (%s)", strerror(errno) ); + close( i_handle ); + return( -1 ); + } + + /* Allow broadcast reception if we bound on in6addr_any */ + if( psz_bind_addr == NULL ) + { + i_opt = 1; + if( setsockopt( i_handle, SOL_SOCKET, SO_BROADCAST, + (void*) &i_opt, sizeof( i_opt ) ) == -1 ) + { + intf_WarnMsg( 1, + "ipv6 warning: cannot configure socket (SO_BROADCAST: %s)", + strerror(errno)); + } + } + + /* Join the multicast group if the socket is a multicast address */ + /* FIXME: To be written */ + + if( psz_server_addr != NULL ) + { + /* Build socket for remote connection */ + if ( BuildAddr( &sock, psz_server_addr, i_server_port ) == -1 ) + { + intf_ErrMsg( "ipv6 error: cannot build remote address" ); + close( i_handle ); + return( -1 ); + } + + /* Connect the socket */ + if( connect( i_handle, (struct sockaddr *) &sock, + sizeof( sock ) ) == (-1) ) + { + intf_ErrMsg( "ipv6 error: cannot connect socket (%s)", + strerror(errno) ); + close( i_handle ); + return( -1 ); + } + } + + p_socket->i_handle = i_handle; + p_socket->i_mtu = DEFAULT_MTU; + return( 0 ); +} + +/***************************************************************************** + * OpenTCP: open a TCP socket + ***************************************************************************** + * psz_server_addr, i_server_port : address and port used for the connect() + * system call. If i_server_port == 0, 80 is used. + * Other parameters are ignored. + * This function returns -1 in case of error. + *****************************************************************************/ +static int OpenTCP( network_socket_t * p_socket ) +{ + char * psz_server_addr = p_socket->psz_server_addr; + int i_server_port = p_socket->i_server_port; + + int i_handle; + struct sockaddr_in6 sock; + + if( i_server_port == 0 ) + { + i_server_port = 80; + } + + /* Open a SOCK_STREAM (TCP) socket, in the AF_INET6 domain, automatic (0) + * protocol */ + if( (i_handle = socket( AF_INET6, SOCK_STREAM, 0 )) == -1 ) + { + intf_ErrMsg( "ipv6 error: cannot create socket (%s)", strerror(errno) ); + return( -1 ); + } + + /* Build remote address */ + if ( BuildAddr( &sock, psz_server_addr, i_server_port ) == -1 ) + { + close( i_handle ); + return( -1 ); + } + + /* Connect the socket */ + if( connect( i_handle, (struct sockaddr *) &sock, + sizeof( sock ) ) == (-1) ) + { + intf_ErrMsg( "ipv6 error: cannot connect socket (%s)", + strerror(errno) ); + close( i_handle ); + return( -1 ); + } + + p_socket->i_handle = i_handle; + p_socket->i_mtu = 0; /* There is no MTU notion in TCP */ + + return( 0 ); +} + +/***************************************************************************** + * NetworkOpen: wrapper around OpenUDP and OpenTCP + *****************************************************************************/ +static int NetworkOpen( network_socket_t * p_socket ) +{ + if( p_socket->i_type == NETWORK_UDP ) + { + return OpenUDP( p_socket ); + } + else + { + return OpenTCP( p_socket ); + } +} + + diff --git a/src/input/mpeg_system.c b/src/input/mpeg_system.c index bf58fc0a96..8b594aba47 100644 --- a/src/input/mpeg_system.c +++ b/src/input/mpeg_system.c @@ -2,7 +2,7 @@ * mpeg_system.c: TS, PS and PES management ***************************************************************************** * Copyright (C) 1998-2001 VideoLAN - * $Id: mpeg_system.c,v 1.81 2002/03/01 00:33:18 massiot Exp $ + * $Id: mpeg_system.c,v 1.82 2002/03/04 23:56:37 massiot Exp $ * * Authors: Christophe Massiot * Michel Lespinasse @@ -639,6 +639,110 @@ static void DecodePSM( input_thread_t * p_input, data_packet_t * p_data ) vlc_mutex_unlock( &p_input->stream.stream_lock ); } +/***************************************************************************** + * input_ReadPS: store a PS packet into a data_buffer_t + *****************************************************************************/ +#define PEEK( SIZE ) \ + i_error = input_Peek( p_input, &p_peek, SIZE ); \ + if( i_error == -1 ) \ + { \ + return( -1 ); \ + } \ + else if( i_error < SIZE ) \ + { \ + /* EOF */ \ + return( 0 ); \ + } + +ssize_t input_ReadPS( input_thread_t * p_input, data_packet_t ** pp_data ) +{ + byte_t * p_peek; + size_t i_packet_size; + ssize_t i_error, i_read; + + /* Read what we believe to be a packet header. */ + PEEK( 4 ); + + if( *p_peek || *(p_peek + 1) || *(p_peek + 2) != 1 ) + { + if( *p_peek || *(p_peek + 1) || *(p_peek + 2) ) + { + /* It is common for MPEG-1 streams to pad with zeros + * (although it is forbidden by the recommendation), so + * don't bother everybody in this case. */ + intf_WarnMsg( 3, "input warning: garbage at input (0x%x%x%x%x)", + *p_peek, *(p_peek + 1), *(p_peek + 2), *(p_peek + 3) ); + } + + /* This is not the startcode of a packet. Read the stream + * until we find one. */ + while( *p_peek || *(p_peek + 1) || *(p_peek + 2) != 1 ) + { + p_input->p_current_data++; + PEEK( 4 ); + } + /* Packet found. */ + } + + /* 0x1B9 == SYSTEM_END_CODE, it is only 4 bytes long. */ + if( p_peek[3] != 0xB9 ) + { + /* The packet is at least 6 bytes long. */ + PEEK( 6 ); + + if( p_peek[3] != 0xBA ) + { + /* That's the case for all packets, except pack header. */ + i_packet_size = (p_peek[4] << 8) | p_peek[5]; + } + else + { + /* Pack header. */ + if( (p_peek[4] & 0xC0) == 0x40 ) + { + /* MPEG-2 */ + i_packet_size = 8; + } + else if( (p_peek[4] & 0xF0) == 0x20 ) + { + /* MPEG-1 */ + i_packet_size = 6; + } + else + { + intf_ErrMsg( "Unable to determine stream type" ); + return( -1 ); + } + } + } + else + { + /* System End Code */ + i_packet_size = -2; + } + + /* Fetch a packet of the appropriate size. */ + i_read = input_SplitBuffer( p_input, pp_data, i_packet_size + 6 ); + if( i_read <= 0 ) + { + return( i_read ); + } + + /* In MPEG-2 pack headers we still have to read stuffing bytes. */ + if( ((*pp_data)->p_demux_start[3] == 0xBA) && (i_packet_size == 8) ) + { + size_t i_stuffing = ((*pp_data)->p_demux_start[13] & 0x7); + /* Force refill of the input buffer - though we don't care + * about p_peek. Please note that this is unoptimized. */ + PEEK( i_stuffing ); + p_input->p_current_data += i_stuffing; + } + + return( 1 ); +} + +#undef PEEK + /***************************************************************************** * input_ParsePS: read the PS header *****************************************************************************/ @@ -923,6 +1027,63 @@ void input_DemuxPS( input_thread_t * p_input, data_packet_t * p_data ) * TS Demultiplexing */ +/***************************************************************************** + * input_ReadTS: store a TS packet into a data_buffer_t + *****************************************************************************/ +#define PEEK( SIZE ) \ + i_error = input_Peek( p_input, &p_peek, SIZE ); \ + if( i_error == -1 ) \ + { \ + return( -1 ); \ + } \ + else if( i_error < SIZE ) \ + { \ + /* EOF */ \ + return( 0 ); \ + } + +ssize_t input_ReadTS( input_thread_t * p_input, data_packet_t ** pp_data ) +{ + byte_t * p_peek; + ssize_t i_error, i_read; + + PEEK( 1 ); + + if( *p_peek != TS_SYNC_CODE ) + { + intf_WarnMsg( 3, "input warning: garbage at input (%x)", *p_peek ); + + if( p_input->i_mtu ) + { + while( *p_peek != TS_SYNC_CODE ) + { + /* Try to resync on next packet. */ + PEEK( TS_PACKET_SIZE ); + p_input->p_current_data += TS_PACKET_SIZE; + PEEK( 1 ); + } + } + else + { + /* Move forward until we find 0x47 (and hope it's the good + * one... FIXME) */ + while( *p_peek != TS_SYNC_CODE ) + { + p_input->p_current_data++; + PEEK( 1 ); + } + } + } + + i_read = input_SplitBuffer( p_input, pp_data, TS_PACKET_SIZE ); + if( i_read <= 0 ) + { + return( i_read ); + } + + return( 1 ); +} + /***************************************************************************** * input_DemuxTS: first step of demultiplexing: the TS header *****************************************************************************/ diff --git a/src/interface/main.c b/src/interface/main.c index 7609d806c8..f8e41ab550 100644 --- a/src/interface/main.c +++ b/src/interface/main.c @@ -4,7 +4,7 @@ * and spawn threads. ***************************************************************************** * Copyright (C) 1998-2001 VideoLAN - * $Id: main.c,v 1.159 2002/03/04 22:18:25 gbazin Exp $ + * $Id: main.c,v 1.160 2002/03/04 23:56:38 massiot Exp $ * * Authors: Vincent Seguin * Samuel Hocevar @@ -169,6 +169,8 @@ ADD_INTEGER ( INPUT_SUBTITLE_VAR, -1, NULL, "choose subtitles", NULL ) ADD_STRING ( INPUT_DVD_DEVICE_VAR, "/dev/dvd", NULL, "DVD device", NULL ) ADD_STRING ( INPUT_VCD_DEVICE_VAR, "/dev/cdrom", NULL, "VCD device", NULL ) +ADD_BOOL ( INPUT_IPV6_VAR, NULL, "force IPv6", NULL ) +ADD_BOOL ( INPUT_IPV4_VAR, NULL, "force IPv4", NULL ) /* Decoder options */ ADD_CATEGORY_HINT( "Decoders Options", NULL ) diff --git a/src/misc/modules_plugin.h b/src/misc/modules_plugin.h index fcf23b1c09..e7af760dc9 100644 --- a/src/misc/modules_plugin.h +++ b/src/misc/modules_plugin.h @@ -2,7 +2,7 @@ * modules_plugin.h : Plugin management functions used by the core application. ***************************************************************************** * Copyright (C) 2001 VideoLAN - * $Id: modules_plugin.h,v 1.13 2002/03/01 00:33:18 massiot Exp $ + * $Id: modules_plugin.h,v 1.14 2002/03/04 23:56:38 massiot Exp $ * * Authors: Samuel Hocevar * @@ -209,8 +209,10 @@ module_error( void ) (p_symbols)->input_ParsePES = input_ParsePES; \ (p_symbols)->input_GatherPES = input_GatherPES; \ (p_symbols)->input_DecodePES = input_DecodePES; \ + (p_symbols)->input_ReadPS = input_ReadPS; \ (p_symbols)->input_ParsePS = input_ParsePS; \ (p_symbols)->input_DemuxPS = input_DemuxPS; \ + (p_symbols)->input_ReadTS = input_ReadTS; \ (p_symbols)->input_DemuxTS = input_DemuxTS; \ (p_symbols)->input_DemuxPSI = input_DemuxPSI; \ (p_symbols)->input_ClockManageControl = input_ClockManageControl; \ diff --git a/src/misc/netutils.c b/src/misc/netutils.c index c7e1347aa2..e31e2fd9d0 100644 --- a/src/misc/netutils.c +++ b/src/misc/netutils.c @@ -2,7 +2,7 @@ * netutils.c: various network functions ***************************************************************************** * Copyright (C) 1999-2001 VideoLAN - * $Id: netutils.c,v 1.58 2002/02/27 04:49:55 sam Exp $ + * $Id: netutils.c,v 1.59 2002/03/04 23:56:38 massiot Exp $ * * Authors: Vincent Seguin * Benoit Steiner @@ -35,10 +35,6 @@ #include -#ifdef STRNCASECMP_IN_STRINGS_H -# include -#endif - #ifdef HAVE_UNISTD_H # include /* gethostname() */ #elif defined( _MSC_VER ) && defined( _WIN32 ) @@ -81,6 +77,7 @@ #include "netutils.h" #include "intf_playlist.h" +#include "network.h" /***************************************************************************** * input_channel_t: channel library data @@ -104,53 +101,6 @@ static int GetMacAddress ( int i_fd, char *psz_mac ); static int GetAdapterInfo ( int i_adapter, char *psz_string ); #endif -/***************************************************************************** - * network_BuildAddr : fill a sockaddr_in structure - *****************************************************************************/ -int network_BuildAddr( struct sockaddr_in * p_socket, - char * psz_address, int i_port ) -{ -#if 0 - intf_ErrMsg( "error: networking is not yet supported under BeOS" ); - return( 1 ); - -#else - /* Reset struct */ - memset( p_socket, 0, sizeof( struct sockaddr_in ) ); - p_socket->sin_family = AF_INET; /* family */ - p_socket->sin_port = htons( i_port ); - if( psz_address == NULL ) - { - p_socket->sin_addr.s_addr = INADDR_ANY; - } - else - { - struct hostent * p_hostent; - - /* Try to convert address directly from in_addr - this will work if - * psz_broadcast is dotted decimal. */ -#ifdef HAVE_ARPA_INET_H - if( !inet_aton( psz_address, &p_socket->sin_addr) ) -#else - if( (p_socket->sin_addr.s_addr = inet_addr( psz_address )) == -1 ) -#endif - { - /* We have a fqdn, try to find its address */ - if ( (p_hostent = gethostbyname( psz_address )) == NULL ) - { - intf_ErrMsg( "BuildLocalAddr: unknown host %s", psz_address ); - return( -1 ); - } - - /* Copy the first address of the host in the socket address */ - memcpy( &p_socket->sin_addr, p_hostent->h_addr_list[0], - p_hostent->h_length ); - } - } - return( 0 ); -#endif -} - /***************************************************************************** * network_ChannelCreate: initialize global channel method data ***************************************************************************** @@ -160,7 +110,10 @@ int network_BuildAddr( struct sockaddr_in * p_socket, *****************************************************************************/ int network_ChannelCreate( void ) { -#if defined( SYS_LINUX ) || defined( WIN32 ) +#if !defined( SYS_LINUX ) && !defined( WIN32 ) + intf_ErrMsg( "channel warning: VLAN-based channels are not supported" + " under this architecture" ); +#endif /* Allocate structure */ p_main->p_channel = malloc( sizeof( input_channel_t ) ); @@ -176,12 +129,6 @@ int network_ChannelCreate( void ) intf_WarnMsg( 2, "network: channels initialized" ); return( 0 ); - -#else - intf_ErrMsg( "network error : channels not supported on this platform" ); - return( 1 ); - -#endif } /***************************************************************************** @@ -197,17 +144,16 @@ int network_ChannelCreate( void ) *****************************************************************************/ int network_ChannelJoin( int i_channel ) { -#if defined( SYS_LINUX ) || defined( WIN32 ) - #define VLCS_VERSION 13 #define MESSAGE_LENGTH 256 + struct module_s * p_network; + char * psz_network = NULL; + network_socket_t socket_desc; char psz_mess[ MESSAGE_LENGTH ]; char psz_mac[ 40 ]; - int i_fd, i_dummy, i_port; + int i_fd, i_port; char *psz_vlcs; - struct sockaddr_in sa_server; - struct sockaddr_in sa_client; struct timeval delay; fd_set fds; @@ -223,26 +169,18 @@ int network_ChannelJoin( int i_channel ) { intf_WarnMsg( 2, "network: waiting before changing channel" ); /* XXX Isn't this completely brain-damaged ??? -- Sam */ + /* Yes it is. I don't think this is still justified with the new + * vlanserver --Meuuh */ mwait( p_main->p_channel->last_change + INPUT_CHANNEL_CHANGE_DELAY ); } - /* Initializing the socket */ - i_fd = socket( AF_INET, SOCK_DGRAM, 0 ); - if( i_fd < 0 ) + if( config_GetIntVariable( INPUT_IPV4_VAR ) ) { - intf_ErrMsg( "network error: unable to create vlcs socket (%s)", - strerror( errno ) ); - return -1; + psz_network = "ipv4"; } - - i_dummy = 1; - if( setsockopt( i_fd, SOL_SOCKET, SO_REUSEADDR, - (void *) &i_dummy, sizeof( i_dummy ) ) == -1 ) + if( config_GetIntVariable( INPUT_IPV6_VAR ) ) { - intf_ErrMsg( "network error: can't SO_REUSEADDR vlcs socket (%s)", - strerror(errno)); - close( i_fd ); - return -1; + psz_network = "ipv6"; } /* Getting information about the channel server */ @@ -255,31 +193,27 @@ int network_ChannelJoin( int i_channel ) i_port = config_GetIntVariable( INPUT_CHANNEL_PORT_VAR ); - intf_WarnMsg( 5, "network: socket %i, vlcs '%s', port %d", - i_fd, psz_vlcs, i_port ); - - memset( &sa_client, 0x00, sizeof(struct sockaddr_in) ); - memset( &sa_server, 0x00, sizeof(struct sockaddr_in) ); - sa_client.sin_family = AF_INET; - sa_server.sin_family = AF_INET; - sa_client.sin_port = htons( 4312 ); - sa_server.sin_port = htons( i_port ); - sa_client.sin_addr.s_addr = INADDR_ANY; -#ifdef HAVE_ARPA_INET_H - inet_aton( psz_vlcs, &sa_server.sin_addr ); -#else - sa_server.sin_addr.s_addr = inet_addr( psz_vlcs ); -#endif - free( psz_vlcs ); + intf_WarnMsg( 5, "channel: connecting to %s:%d", + psz_vlcs, i_port ); - /* Bind the socket */ - if( bind( i_fd, (struct sockaddr*)(&sa_client), sizeof(sa_client) ) ) + /* Prepare the network_socket_t structure */ + socket_desc.i_type = NETWORK_UDP; + socket_desc.psz_bind_addr = NULL; + socket_desc.i_bind_port = 4321; + socket_desc.psz_server_addr = psz_vlcs; + socket_desc.i_server_port = i_port; + + /* Find an appropriate network module */ + p_network = module_Need( MODULE_CAPABILITY_NETWORK, psz_network, + &socket_desc ); + if( p_network == NULL ) { - intf_ErrMsg( "network: unable to bind vlcs socket (%s)", - strerror( errno ) ); - close( i_fd ); - return -1; + return( -1 ); } + module_Unneed( p_network ); + + free( psz_vlcs ); /* Do we really need this ? -- Meuuh */ + i_fd = socket_desc.i_handle; /* Look for the interface MAC address */ if( GetMacAddress( i_fd, psz_mac ) ) @@ -297,8 +231,7 @@ int network_ChannelJoin( int i_channel ) psz_mac ); /* Send the message */ - sendto( i_fd, psz_mess, MESSAGE_LENGTH, 0, - (struct sockaddr *)(&sa_server), sizeof(struct sockaddr) ); + send( i_fd, psz_mess, MESSAGE_LENGTH, 0 ); intf_WarnMsg( 2, "network: attempting to join channel %d", i_channel ); @@ -327,10 +260,8 @@ int network_ChannelJoin( int i_channel ) break; } - i_dummy = sizeof( struct sockaddr ); - recvfrom( i_fd, psz_mess, MESSAGE_LENGTH, 0, - (struct sockaddr *)(&sa_client), &i_dummy); - psz_mess[ MESSAGE_LENGTH - 1 ] = 0; + recv( i_fd, psz_mess, MESSAGE_LENGTH, 0 ); + psz_mess[ MESSAGE_LENGTH - 1 ] = '\0'; if( !strncasecmp( psz_mess, "E: ", 3 ) ) { @@ -366,12 +297,6 @@ int network_ChannelJoin( int i_channel ) close( i_fd ); return 0; - -#else - intf_ErrMsg( "network error: channels not supported on this platform" ); - return -1; - -#endif } /* Following functions are local */ @@ -444,7 +369,8 @@ static int GetMacAddress( int i_fd, char *psz_mac ) return( i_ret ); #else - return( -1); + strcpy( psz_mac, "00:00:00:00:00:00" ); + return( 0 ); #endif } -- 2.39.2