* Added a set_to_defaults() function to the address module: it can be used
to retrieve the default settings for the netmask/broadcast depending on the specified address/netmask. * interface_protocol_control() now uses this to reset the broadcast/netmask to their default values on SIOCSIFADDR resp. the former only on SIOCSIFNETMASK. * This fixes bug #1861. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24170 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
487b83f327
commit
b5a5aebc90
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2006, Haiku, Inc. All Rights Reserved.
|
||||
* Copyright 2006-2008, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef NET_DATALINK_H
|
||||
@ -67,7 +67,7 @@ struct net_datalink_module_info {
|
||||
size_t *_length);
|
||||
status_t (*send_data)(struct net_route *route, struct net_buffer *buffer);
|
||||
status_t (*send_datagram)(struct net_protocol *protocol,
|
||||
struct net_domain *domain, struct net_buffer *buffer);
|
||||
struct net_domain *domain, struct net_buffer *buffer);
|
||||
|
||||
bool (*is_local_address)(struct net_domain *domain,
|
||||
const struct sockaddr *address,
|
||||
@ -75,7 +75,7 @@ struct net_datalink_module_info {
|
||||
uint32 *_matchedType);
|
||||
net_interface *(*get_interface)(struct net_domain *domain, uint32 index);
|
||||
net_interface *(*get_interface_with_address)(struct net_domain *domain,
|
||||
const struct sockaddr *address);
|
||||
const struct sockaddr *address);
|
||||
|
||||
// routes
|
||||
status_t (*add_route)(struct net_domain *domain,
|
||||
@ -85,7 +85,7 @@ struct net_datalink_module_info {
|
||||
struct net_route *(*get_route)(struct net_domain *domain,
|
||||
const struct sockaddr *address);
|
||||
status_t (*get_buffer_route)(struct net_domain *domain,
|
||||
struct net_buffer *buffer, struct net_route **_route);
|
||||
struct net_buffer *buffer, struct net_route **_route);
|
||||
void (*put_route)(struct net_domain *domain, struct net_route *route);
|
||||
|
||||
status_t (*register_route_info)(struct net_domain *domain,
|
||||
@ -100,7 +100,7 @@ struct net_address_module_info {
|
||||
module_info info;
|
||||
|
||||
status_t (*copy_address)(const sockaddr *from, sockaddr **to,
|
||||
bool replaceWithZeros /* = false */, const sockaddr *mask /* = NULL*/);
|
||||
bool replaceWithZeros, const sockaddr *mask);
|
||||
|
||||
status_t (*mask_address)(const sockaddr *address, const sockaddr *mask,
|
||||
sockaddr *result);
|
||||
@ -110,7 +110,7 @@ struct net_address_module_info {
|
||||
bool (*equal_addresses_and_ports)(const sockaddr *a, const sockaddr *b);
|
||||
bool (*equal_masked_addresses)(const sockaddr *a, const sockaddr *b,
|
||||
const sockaddr *mask);
|
||||
bool (*is_empty_address)(const sockaddr *address, bool checkPort /* = true */);
|
||||
bool (*is_empty_address)(const sockaddr *address, bool checkPort);
|
||||
|
||||
int32 (*first_mask_bit)(const sockaddr *mask);
|
||||
|
||||
@ -126,6 +126,9 @@ struct net_address_module_info {
|
||||
|
||||
status_t (*set_to)(sockaddr *address, const sockaddr *from);
|
||||
status_t (*set_to_empty_address)(sockaddr *address);
|
||||
status_t (*set_to_defaults)(sockaddr *defaultMask,
|
||||
sockaddr *defaultBroadcast, sockaddr *address,
|
||||
sockaddr *netmask);
|
||||
|
||||
status_t (*update_to)(sockaddr *address, const sockaddr *from);
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2006-2007, Haiku, Inc. All Rights Reserved.
|
||||
* Copyright 2006-2008, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
@ -388,6 +388,55 @@ ipv4_set_to_empty_address(sockaddr *address)
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
ipv4_set_to_defaults(sockaddr *_defaultMask, sockaddr *_defaultBroadcast,
|
||||
sockaddr *_address, sockaddr *_mask)
|
||||
{
|
||||
sockaddr_in *defaultMask = (sockaddr_in *)_defaultMask;
|
||||
sockaddr_in *defaultBroadcast = (sockaddr_in *)_defaultBroadcast;
|
||||
sockaddr_in *address = (sockaddr_in *)_address;
|
||||
sockaddr_in *mask = (sockaddr_in *)_mask;
|
||||
|
||||
if (address == NULL || (defaultMask == NULL && defaultBroadcast == NULL))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
in_addr_t net;
|
||||
if (mask == NULL) {
|
||||
// choose default netmask depending on the class of the address
|
||||
net = address->sin_addr.s_addr;
|
||||
if (IN_CLASSA(net)
|
||||
|| (ntohl(net) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) {
|
||||
// class A, or loopback
|
||||
net = IN_CLASSA_NET;
|
||||
} else if (IN_CLASSB(net)) {
|
||||
// class B
|
||||
net = IN_CLASSB_NET;
|
||||
} else {
|
||||
// class C and rest
|
||||
net = IN_CLASSC_NET;
|
||||
}
|
||||
} else
|
||||
net = mask->sin_addr.s_addr;
|
||||
|
||||
if (defaultMask != NULL) {
|
||||
defaultMask->sin_len = sizeof(sockaddr_in);
|
||||
defaultMask->sin_family = AF_INET;
|
||||
defaultMask->sin_port = 0;
|
||||
defaultMask->sin_addr.s_addr = net;
|
||||
}
|
||||
|
||||
if (defaultBroadcast != NULL) {
|
||||
defaultBroadcast->sin_len = sizeof(sockaddr_in);
|
||||
defaultBroadcast->sin_family = AF_INET;
|
||||
defaultBroadcast->sin_port = 0;
|
||||
defaultBroadcast->sin_addr.s_addr = (address->sin_addr.s_addr & net)
|
||||
| ~net;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Computes a hash-value of the given addresses \a ourAddress
|
||||
and \a peerAddress.
|
||||
@ -441,6 +490,7 @@ net_address_module_info gIPv4AddressModule = {
|
||||
ipv4_set_port,
|
||||
ipv4_set_to,
|
||||
ipv4_set_to_empty_address,
|
||||
ipv4_set_to_defaults,
|
||||
ipv4_update_to,
|
||||
ipv4_hash_address_pair,
|
||||
ipv4_checksum_address,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2006-2007, Haiku, Inc. All Rights Reserved.
|
||||
* Copyright 2006-2008, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
@ -164,6 +164,26 @@ add_default_routes(net_interface_private *interface, int32 option)
|
||||
}
|
||||
|
||||
|
||||
sockaddr *
|
||||
reallocate_address(sockaddr **_address, uint32 size)
|
||||
{
|
||||
sockaddr *address = *_address;
|
||||
|
||||
size = max_c(size, sizeof(struct sockaddr));
|
||||
if (address != NULL && address->sa_len >= size)
|
||||
return address;
|
||||
|
||||
address = (sockaddr *)malloc(size);
|
||||
if (address == NULL)
|
||||
return NULL;
|
||||
|
||||
free(*_address);
|
||||
*_address = address;
|
||||
|
||||
return address;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
datalink_control_interface(net_domain_private *domain, int32 option,
|
||||
void *value, size_t *_length, size_t expected, bool getByName)
|
||||
@ -624,27 +644,32 @@ interface_protocol_control(net_datalink_protocol *_protocol,
|
||||
if (_address == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
sockaddr *address = *_address;
|
||||
sockaddr *original = address;
|
||||
|
||||
// allocate new address if needed
|
||||
if (address == NULL
|
||||
|| (address->sa_len < request.ifr_addr.sa_len
|
||||
&& request.ifr_addr.sa_len > sizeof(struct sockaddr))) {
|
||||
address = (sockaddr *)malloc(
|
||||
max_c(request.ifr_addr.sa_len, sizeof(struct sockaddr)));
|
||||
}
|
||||
sockaddr *address = reallocate_address(_address,
|
||||
request.ifr_addr.sa_len);
|
||||
|
||||
// copy new address over
|
||||
if (address != NULL) {
|
||||
remove_default_routes(interface, option);
|
||||
memcpy(address, &request.ifr_addr, request.ifr_addr.sa_len);
|
||||
|
||||
if (original != address) {
|
||||
free(original);
|
||||
*_address = address;
|
||||
if (option == SIOCSIFADDR || option == SIOCSIFNETMASK) {
|
||||
// reset netmask and broadcast addresses to defaults
|
||||
sockaddr *netmask = NULL;
|
||||
sockaddr *oldNetmask = NULL;
|
||||
if (option == SIOCSIFADDR) {
|
||||
netmask = reallocate_address(&interface->mask,
|
||||
request.ifr_addr.sa_len);
|
||||
} else
|
||||
oldNetmask = address;
|
||||
|
||||
sockaddr *broadcast = reallocate_address(
|
||||
&interface->destination, request.ifr_addr.sa_len);
|
||||
|
||||
interface->domain->address_module->set_to_defaults(
|
||||
netmask, broadcast, interface->address, oldNetmask);
|
||||
}
|
||||
|
||||
memcpy(address, &request.ifr_addr, request.ifr_addr.sa_len);
|
||||
add_default_routes(interface, option);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user