static int play_with_context(const char *uri, htsmsg_t *meta) { const char *parentid, *id; upnp_service_t *us; parentid = htsmsg_get_str_multi(meta, "DIDL-Lite", "item", "parentID", NULL); if(parentid == NULL) return 1; id = htsmsg_get_str_multi(meta, "DIDL-Lite", "item", "id", NULL); if(id == NULL) return 1; UPNP_TRACE("Playing %s (id: %s, parent: %s)", uri, id, parentid); hts_mutex_lock(&upnp_lock); us = upnp_service_guess(uri); if(us != NULL) { UPNP_TRACE("Using controlpoint %s", us->us_control_url); prop_t *model = prop_create_root(NULL); prop_t *nodes = prop_create(model, "nodes"); prop_t *t = NULL; if(upnp_browse_children(us->us_control_url, parentid, nodes, id, &t) || t == NULL) { prop_destroy(model); } else { playqueue_load_with_source(t, model, PQ_PAUSED); hts_mutex_unlock(&upnp_lock); return 0; } } hts_mutex_unlock(&upnp_lock); return 1; }
/* IsValidIPAddress() -- Reject the IP addresses that are reserved for other things */ bool IsValidIPAddress(const struct in_addr ip) { if( (ip.s_addr == 0) || // 0.0.0.0 is of course not valid:) (ip.s_addr & ntohl(0xFF000000)) == ntohl(0x7F000000) || // 127.x.x.x, loop-back (ip.s_addr & ntohl(0xFF000000)) >= ntohl(0xE0000000) ) // 224-239.x.x.x == multicasting { // 240-254.x.x.x == reserved, experimental // 255.x.x.x == broadcast UPNP_TRACE(("Is valid ip Address, false, 0x%x\n", (uint) ip.s_addr)); return FALSE; } UPNP_TRACE(("Is valid ip Address, true, 0x%x\n", (uint) ip.s_addr)); return TRUE; }
/* IsContiguousSubnet() - verify that a subnet mask no holes in it. */ bool IsContiguousSubnet(const struct in_addr mask) { // Convert aaa.bbb.ccc.ddd into ddd.ccc.bbb.aaa bool bContinuous; uint32 i, dwContiguousMask; uint32 hmask = ntohl(mask.s_addr); // Find out where the first '1' is in binary going right to left dwContiguousMask = 0; for (i = 0; i < sizeof(mask.s_addr)*8; i++) { dwContiguousMask |= ntohl(1<<i); if (dwContiguousMask & hmask) { break; } } // At this point, dwContiguousMask is 000...0111... If we inverse it, // we get a mask that can be or'd with dwMask to fill in all of // the holes. dwContiguousMask = hmask | ~dwContiguousMask; bContinuous = (hmask == dwContiguousMask); UPNP_TRACE(("Is contiguous subnet, %s\n", (bContinuous ? "true" : "false"))); return bContinuous; }
/////////////////////////////////////////////////////////////////////////////// // IsValidIPConfig() -- Determine if the given IPAddress, mask, and gateway // make sense. /////////////////////////////////////////////////////////////////////////////// bool IsValidIPConfig(const struct in_addr address, const struct in_addr mask, const struct in_addr gateway) { bool bIsValid = FALSE; do { // First make sure that the address, and the gateway don't have // reserved addresses. if (!IsValidIPAddress(address) || !IsValidIPAddress(gateway)) { UPNP_TRACE(("Is valid IP config, address, or gateway was invalid (reserved) IP\n")); break; } if (!IsContiguousSubnet(mask)) { UPNP_TRACE(("Is valid IP Config, mask was not contiguous\n")); break; } if ((address.s_addr & mask.s_addr) != (gateway.s_addr & mask.s_addr)) { UPNP_TRACE(("ip and gw not on the same subnet, not valid ip config\n")); break; } // Now check to make sure that the ip address is not at 0, or 255. if (address.s_addr == (address.s_addr & mask.s_addr)) { UPNP_TRACE(("You can't have an IP address at zero(s) relative to subnet mask\n")); break; } if ( (~mask.s_addr) + (address.s_addr & mask.s_addr) == address.s_addr) { UPNP_TRACE(("You can't have an IP address at 255\n")); break; } bIsValid = TRUE; } while (0); return bIsValid; }