📄 ipv4.c
字号:
/* Bind it */ if( bind( i_handle, (struct sockaddr *)&loc, sizeof( loc ) ) < 0 ) { msg_Warn( p_this, "cannot bind socket (%s)", strerror(errno) ); close( i_handle ); return 0; }#if !defined( SYS_BEOS ) /* Allow broadcast reception if we bound on INADDR_ANY */ if( loc.sin_addr.s_addr == INADDR_ANY ) { i_opt = 1; if( setsockopt( i_handle, SOL_SOCKET, SO_BROADCAST, (void*) &i_opt, sizeof( i_opt ) ) == -1 ) msg_Warn( p_this, "cannot configure socket (SO_BROADCAST: %s)", strerror(errno) ); }#endif#if !defined( SYS_BEOS ) /* Join the multicast group if the socket is a multicast address */ if( IN_MULTICAST( ntohl(loc.sin_addr.s_addr) ) ) { /* Determine interface to be used for multicast */ char * psz_if_addr = config_GetPsz( p_this, "miface-addr" ); /* If we have a source address, we use IP_ADD_SOURCE_MEMBERSHIP so that IGMPv3 aware OSes running on IGMPv3 aware networks will do an IGMPv3 query on the network */ if (( rem.sin_addr.s_addr != INADDR_ANY ) /*&& ((ntohl (loc.sin_addr.s_addr) >> 24) == 232)*/) {#ifndef IP_ADD_SOURCE_MEMBERSHIP errno = ENOSYS;#else struct ip_mreq_source imr; imr.imr_multiaddr.s_addr = loc.sin_addr.s_addr; imr.imr_sourceaddr.s_addr = rem.sin_addr.s_addr; if( psz_if_addr != NULL && *psz_if_addr && inet_addr(psz_if_addr) != INADDR_NONE ) imr.imr_interface.s_addr = inet_addr(psz_if_addr); else imr.imr_interface.s_addr = INADDR_ANY; if( psz_if_addr != NULL ) free( psz_if_addr ); msg_Dbg( p_this, "IP_ADD_SOURCE_MEMBERSHIP multicast request" ); /* Join Multicast group with source filter */ if( setsockopt( i_handle, IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP, (char*)&imr, sizeof(struct ip_mreq_source) ) == 0 ) do_connect = VLC_FALSE; else#endif { msg_Warn( p_this, "Source specific multicast failed (%s) -" " check if your OS really supports IGMPv3", strerror(errno) ); goto igmpv2; } } /* If there is no source address, we use IP_ADD_MEMBERSHIP */ elseigmpv2: { struct ip_mreq imr; imr.imr_interface.s_addr = INADDR_ANY; imr.imr_multiaddr.s_addr = loc.sin_addr.s_addr; if( psz_if_addr != NULL && *psz_if_addr && inet_addr(psz_if_addr) != INADDR_NONE ) { imr.imr_interface.s_addr = inet_addr(psz_if_addr); }#if defined (WIN32) || defined (UNDER_CE) else { typedef DWORD (CALLBACK * GETBESTINTERFACE) ( IPAddr, PDWORD ); typedef DWORD (CALLBACK * GETIPADDRTABLE) ( PMIB_IPADDRTABLE, PULONG, BOOL ); GETBESTINTERFACE OurGetBestInterface; GETIPADDRTABLE OurGetIpAddrTable; HINSTANCE hiphlpapi = LoadLibrary(_T("Iphlpapi.dll")); DWORD i_index; if( hiphlpapi ) { OurGetBestInterface = (void *)GetProcAddress( hiphlpapi, _T("GetBestInterface") ); OurGetIpAddrTable = (void *)GetProcAddress( hiphlpapi, _T("GetIpAddrTable") ); } if( hiphlpapi && OurGetBestInterface && OurGetIpAddrTable && OurGetBestInterface( loc.sin_addr.s_addr, &i_index ) == NO_ERROR ) { PMIB_IPADDRTABLE p_table; DWORD i = 0; msg_Dbg( p_this, "Winsock best interface is %lu", (unsigned long)i_index ); OurGetIpAddrTable( NULL, &i, 0 ); p_table = (PMIB_IPADDRTABLE)malloc( i ); if( p_table != NULL ) { if( OurGetIpAddrTable( p_table, &i, 0 ) == NO_ERROR ) { for( i = 0; i < p_table->dwNumEntries; i-- ) { if( p_table->table[i].dwIndex == i_index ) { imr.imr_interface.s_addr = p_table->table[i].dwAddr; msg_Dbg( p_this, "using interface 0x%08x", p_table->table[i].dwAddr ); } } } else msg_Warn( p_this, "GetIpAddrTable failed" ); free( p_table ); } } else msg_Dbg( p_this, "GetBestInterface failed" ); if( hiphlpapi ) FreeLibrary( hiphlpapi ); }#endif if( psz_if_addr != NULL ) free( psz_if_addr ); msg_Dbg( p_this, "IP_ADD_MEMBERSHIP multicast request" ); /* Join Multicast group without source filter */ if( setsockopt( i_handle, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&imr, sizeof(struct ip_mreq) ) == -1 ) { msg_Err( p_this, "failed to join IP multicast group (%s)", strerror(errno) ); close( i_handle ); return 0; } } }#if !defined (__linux__) && !defined (WIN32) else#endif#endif /* !defined SYS_BEOS */ if( rem.sin_addr.s_addr != INADDR_ANY ) { /* Connect the socket */ if( do_connect && connect( i_handle, (struct sockaddr *) &rem, sizeof( rem ) ) ) { msg_Warn( p_this, "cannot connect socket (%s)", strerror(errno) ); close( i_handle ); return 0; }#if !defined( SYS_BEOS ) if( IN_MULTICAST( ntohl(rem.sin_addr.s_addr) ) ) { /* set the time-to-live */ int i_ttl = p_socket->i_ttl; /* set the multicast interface */ char * psz_mif_addr = config_GetPsz( p_this, "miface-addr" ); if( psz_mif_addr ) { struct in_addr intf; intf.s_addr = inet_addr(psz_mif_addr); free( psz_mif_addr ); if( setsockopt( i_handle, IPPROTO_IP, IP_MULTICAST_IF, &intf, sizeof( intf ) ) < 0 ) { msg_Dbg( p_this, "failed to set multicast interface (%s).", strerror(errno) ); close( i_handle ); return 0; } } if( i_ttl <= 0 ) i_ttl = config_GetInt( p_this, "ttl" ); if( i_ttl > 0 ) { unsigned char ttl = (unsigned char) i_ttl; /* There is some confusion in the world whether IP_MULTICAST_TTL * takes a byte or an int as an argument. * BSD seems to indicate byte so we are going with that and use * int as a fallback to be safe */ if( setsockopt( i_handle, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof( ttl ) ) < 0 ) { msg_Dbg( p_this, "failed to set ttl (%s). Let's try it " "the integer way.", strerror(errno) ); if( setsockopt( i_handle, IPPROTO_IP, IP_MULTICAST_TTL, &i_ttl, sizeof( i_ttl ) ) <0 ) { msg_Err( p_this, "failed to set ttl (%s)", strerror(errno) ); close( i_handle ); return 0; } } } }#endif } p_socket->i_handle = i_handle; if( var_Get( p_this, "mtu", &val ) != VLC_SUCCESS ) { var_Create( p_this, "mtu", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); var_Get( p_this, "mtu", &val ); } p_socket->i_mtu = val.i_int; return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -