Пример #1
0
status_t
arp_init_protocol(net_interface* interface, net_domain* domain,
	net_datalink_protocol** _protocol)
{
	// We currently only support a single family and type!
	if (interface->device->type != IFT_ETHER
		|| domain->family != AF_INET)
		return B_BAD_TYPE;

	status_t status = sStackModule->register_device_handler(interface->device,
		B_NET_FRAME_TYPE(IFT_ETHER, ETHER_TYPE_ARP), &arp_receive, NULL);
	if (status != B_OK)
		return status;

	status = sStackModule->register_domain_device_handler(
		interface->device, B_NET_FRAME_TYPE(IFT_ETHER, ETHER_TYPE_IP), domain);
	if (status != B_OK)
		return status;

	arp_protocol* protocol = new(std::nothrow) arp_protocol;
	if (protocol == NULL)
		return B_NO_MEMORY;

	memset(&protocol->hardware_address, 0, sizeof(sockaddr_dl));
	protocol->local_address = 0;

	*_protocol = protocol;
	return B_OK;
}
Пример #2
0
status_t
arp_uninit_protocol(net_datalink_protocol *protocol)
{
	sStackModule->unregister_device_handler(protocol->interface->device,
		B_NET_FRAME_TYPE(IFT_ETHER, ETHER_TYPE_ARP));
	sStackModule->unregister_device_handler(protocol->interface->device,
		B_NET_FRAME_TYPE(IFT_ETHER, ETHER_TYPE_IP));

	delete protocol;
	return B_OK;
}
Пример #3
0
int32
ethernet_deframe(net_device* device, net_buffer* buffer)
{
	//dprintf("asked to deframe buffer for device %s\n", device->name);

	NetBufferHeaderRemover<ether_header> bufferHeader(buffer);
	if (bufferHeader.Status() != B_OK)
		return bufferHeader.Status();

	ether_header& header = bufferHeader.Data();
	uint16 type = B_BENDIAN_TO_HOST_INT16(header.type);

	struct sockaddr_dl& source = *(struct sockaddr_dl*)buffer->source;
	struct sockaddr_dl& destination = *(struct sockaddr_dl*)buffer->destination;

	source.sdl_len = sizeof(sockaddr_dl);
	source.sdl_family = AF_LINK;
	source.sdl_index = device->index;
	source.sdl_type = IFT_ETHER;
	source.sdl_e_type = header.type;
	source.sdl_nlen = source.sdl_slen = 0;
	source.sdl_alen = ETHER_ADDRESS_LENGTH;
	memcpy(source.sdl_data, header.source, ETHER_ADDRESS_LENGTH);

	destination.sdl_len = sizeof(sockaddr_dl);
	destination.sdl_family = AF_LINK;
	destination.sdl_index = device->index;
	destination.sdl_type = IFT_ETHER;
	destination.sdl_e_type = header.type;
	destination.sdl_nlen = destination.sdl_slen = 0;
	destination.sdl_alen = ETHER_ADDRESS_LENGTH;
	memcpy(destination.sdl_data, header.destination, ETHER_ADDRESS_LENGTH);

	// Mark buffer if it was a broadcast/multicast packet
	if (!memcmp(header.destination, kBroadcastAddress, ETHER_ADDRESS_LENGTH))
		buffer->flags |= MSG_BCAST;
	else if ((header.destination[0] & 0x01) != 0)
		buffer->flags |= MSG_MCAST;

	// Translate the ethernet specific type to a generic one if possible
	switch (type) {
		case ETHER_TYPE_IP:
			buffer->type = B_NET_FRAME_TYPE_IPV4;
			break;
		case ETHER_TYPE_IPV6:
			buffer->type = B_NET_FRAME_TYPE_IPV6;
			break;
		case ETHER_TYPE_IPX:
			buffer->type = B_NET_FRAME_TYPE_IPX;
			break;

		default:
			buffer->type = B_NET_FRAME_TYPE(IFT_ETHER, type);
			break;
	}

	return B_OK;
}
Пример #4
0
status_t
ppp_frame_init(struct net_interface* interface, net_domain* domain,
	net_datalink_protocol** _protocol)
{
	// We only support a single type!
	dprintf("in function: %s::%s\n", __FILE__, __func__);
	if (interface->device->type != IFT_PPP)
		return B_BAD_TYPE;

	ppp_frame_protocol* protocol;

	status_t status = sStackModule->register_device_deframer(interface->device,
		&ppp_deframe);
	if (status != B_OK)
		return status;

	status = sStackModule->register_domain_device_handler(
		interface->device, B_NET_FRAME_TYPE(IFT_ETHER, ETHER_TYPE_PPPOE), domain);
	if (status != B_OK)
		return status;

	status = sStackModule->register_domain_device_handler(
		interface->device, B_NET_FRAME_TYPE_IPV4, domain);
	if (status != B_OK)
		return status;

	// Locally received buffers don't need a domain device handler, as the
	// buffer reception is handled internally.

	protocol = new(std::nothrow) ppp_frame_protocol;
	if (protocol == NULL) {
		sStackModule->unregister_device_deframer(interface->device);
		return B_NO_MEMORY;
	}

	*_protocol = protocol;
	return B_OK;
}
Пример #5
0
status_t
pppoe_input(void *cookie, net_device *_device, net_buffer *packet)
{
	if (!packet)
		return B_ERROR;

	NetBufferHeaderReader<pppoe_header> bufferheader(packet);
	if (bufferheader.Status() != B_OK)
		return B_ERROR;

	pppoe_header &header = bufferheader.Data();

	// remove the following lines when pppoe server is enabled
	if (header.code == PADI) {
		TRACE("PADI packet received, ignoreing!\n");
		gBufferModule->free(packet);
		return B_OK;
	}

	if (header.code == PADO || header.code == PADR || header.code == PADS || header.code == PADT)
	{
		uint8 peerEtherAddr[ETHER_ADDRESS_LENGTH];
		struct sockaddr_dl& source = *(struct sockaddr_dl*)packet->source;
		memcpy(peerEtherAddr, source.sdl_data, ETHER_ADDRESS_LENGTH);
		const char *str = header.code == PADI ? "PADI" :
			header.code == PADO ? "PADO" :
			header.code == PADR ? "PADR" :
			header.code == PADS ? "PADS" :
			"PADT" ;

		dprintf("%s from:%02x:%02x:%02x:%02x:%02x:%02x code:%02x\n", str,
			peerEtherAddr[0], peerEtherAddr[1], peerEtherAddr[2],
			peerEtherAddr[3], peerEtherAddr[4], peerEtherAddr[5],
			header.code);
	}

	PPPoEDevice *device;
	pppoe_query *query;

	sockaddr_dl& linkAddress = *(sockaddr_dl*)packet->source;
	int32 specificType = B_NET_FRAME_TYPE(linkAddress.sdl_type,
				ntohs(linkAddress.sdl_e_type));

	// MutexLocker locker(sLock);

	if (specificType == B_NET_FRAME_TYPE_PPPOE_DISCOVERY
			&& ntohs(header.length) <= PPPoE_QUERY_REPORT_SIZE) {
		for (int32 index = 0; index < sDevices->CountItems(); index++) {
			query = sQueries->ItemAt(index);

			if (query) {// && query->ethernetIfnet == sourceIfnet) {
				if (header.code == PADO) {
					DiscoveryPacket discovery(packet, ETHER_HDR_LEN);
					if (discovery.InitCheck() != B_OK) {
						ERROR("PPPoE: received corrupted discovery packet!\n");
						// gBufferModule->free(packet);
						return B_ERROR;
					}

					pppoe_tag *hostTag = discovery.TagWithType(HOST_UNIQ);
					if (hostTag && hostTag->length == 4
							&& *((uint32*)hostTag->data) == query->hostUniq) {
						SendQueryPacket(query, discovery);
						// gBufferModule->free(packet);
						return B_ERROR;
					}
				}
			}
		}
	}

	TRACE("in pppoed processing sDevices->CountItems(): %ld\n", sDevices->CountItems());

	for (int32 index = 0; index < sDevices->CountItems(); index++) {
		device = sDevices->ItemAt(index);

		TRACE("device->SessionID() %d, header.sessionID: %d\n", device->SessionID(),
						header.sessionID);

		if (device) { // && device->EthernetIfnet() == sourceIfnet) {
			if (specificType == B_NET_FRAME_TYPE_PPPOE
					&& header.sessionID == device->SessionID()) {
				TRACE("PPPoE: session packet\n");
				device->Receive(packet);
				return B_OK;
			}

			if (specificType == B_NET_FRAME_TYPE_PPPOE_DISCOVERY
					&& header.code != PADI
					&& header.code != PADR
					&& !device->IsDown()) {
				TRACE("PPPoE: discovery packet\n");

				DiscoveryPacket discovery(packet, ETHER_HDR_LEN);
				if (discovery.InitCheck() != B_OK) {
					ERROR("PPPoE: received corrupted discovery packet!\n");
					gBufferModule->free(packet);
					return B_OK;
				}

				pppoe_tag *tag = discovery.TagWithType(HOST_UNIQ);
				if (header.code == PADT || (tag && tag->length == 4
					&& *((uint32*)tag->data) == device->HostUniq())) {
					device->Receive(packet);
					return B_OK;
				}
			}
		}
	}

	ERROR("PPPoE: No device found for packet from: %s\n", "ethernet");
	// gBufferModule->free(packet);
	return B_ERROR;
}