Skip to content

Commit

Permalink
Changed ipttl to ttl to be resolved as IP_TTL or IP_MULTICAST_TTL (#164)
Browse files Browse the repository at this point in the history
* Changed ipttl to be resolved as IP_TTL or IP_MULTICAST_TTL
* Option renamed to 'ttl'. Both options are set
  • Loading branch information
ethouris authored and rndi committed Nov 20, 2017
1 parent 6c3fa95 commit 35c1335
Showing 1 changed file with 39 additions and 2 deletions.
41 changes: 39 additions & 2 deletions apps/stransmit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1270,12 +1270,19 @@ Iface* CreateConsole() { return new typename Console<Iface>::type (); }

// More options can be added in future.
SocketOption udp_options [] {
{ "ipttl", IPPROTO_IP, IP_TTL, SocketOption::INT, SocketOption::PRE },
{ "iptos", IPPROTO_IP, IP_TOS, SocketOption::INT, SocketOption::PRE },
{ "mcttl", IPPROTO_IP, IP_MULTICAST_TTL, SocketOption::INT, SocketOption::PRE },
// IP_TTL and IP_MULTICAST_TTL are handled separately by a common option, "ttl".
{ "mcloop", IPPROTO_IP, IP_MULTICAST_LOOP, SocketOption::INT, SocketOption::PRE }
};


static inline bool IsMulticast(in_addr adr)
{
unsigned char* abytes = (unsigned char*)&adr.s_addr;
unsigned char c = abytes[0];
return c >= 224 && c <= 239;
}

class UdpCommon
{
protected:
Expand All @@ -1294,7 +1301,22 @@ class UdpCommon
}
sadr = CreateAddrInet(host, port);

bool is_multicast = false;

if ( attr.count("multicast") )
{
if (!IsMulticast(sadr.sin_addr))
{
throw std::runtime_error("UdpCommon: requested multicast for a non-multicast-type IP address");
}
is_multicast = true;
}
else if (IsMulticast(sadr.sin_addr))
{
is_multicast = true;
}

if (is_multicast)
{
adapter = attr.count("adapter") ? attr.at("adapter") : string();
sockaddr_in maddr;
Expand Down Expand Up @@ -1343,6 +1365,21 @@ class UdpCommon
attr.erase("adapter");
}

// The "ttl" options is handled separately, it maps to either IP_TTL
// or IP_MULTICAST_TTL, depending on whether the address is sc or mc.
if (attr.count("ttl"))
{
int ttl = stoi(attr.at("ttl"));
int res = setsockopt(m_sock, IPPROTO_IP, IP_TTL, (const char*)&ttl, sizeof ttl);
if (res == -1)
cout << "WARNING: failed to set 'ttl' (IP_TTL) to " << ttl << endl;
res = setsockopt(m_sock, IPPROTO_IP, IP_MULTICAST_TTL, (const char*)&ttl, sizeof ttl);
if (res == -1)
cout << "WARNING: failed to set 'ttl' (IP_MULTICAST_TTL) to " << ttl << endl;

attr.erase("ttl");
}

m_options = attr;

for (auto o: udp_options)
Expand Down

0 comments on commit 35c1335

Please sign in to comment.