Example #1
0
void tracker_addOutputBytes(Tracker* tracker, Packet* packet, gint handle) {
    MAGIC_ASSERT(tracker);

    TrackerFlags flags = _tracker_getFlags(tracker);
    if(!(flags & TRACKER_FLAGS_NODE) && !(flags & TRACKER_FLAGS_SOCKET)) {
        return;
    }

    gboolean isLocal = packet_getSourceIP(packet) == htonl(INADDR_LOOPBACK);
    gsize header = (gsize)packet_getHeaderSize(packet);
    gsize payload = (gsize)packet_getPayloadLength(packet);
    PacketDeliveryStatusFlags status = packet_getDeliveryStatus(packet);

    if(flags & TRACKER_FLAGS_NODE) {
        if(isLocal) {
            _tracker_updateCounters(&tracker->local.outCounters, header, payload, status);
        } else {
            _tracker_updateCounters(&tracker->remote.outCounters, header, payload, status);
        }
    }

    if(flags & TRACKER_FLAGS_SOCKET) {
        SocketStats* ss = g_hash_table_lookup(tracker->socketStats, &handle);
        if(ss) {
            if(isLocal) {
                _tracker_updateCounters(&ss->local.outCounters, header, payload, status);
            } else {
                _tracker_updateCounters(&ss->remote.outCounters, header, payload, status);
            }
        }
    }
}
Example #2
0
static void _networkinterface_scheduleNextReceive(NetworkInterface* interface) {
	/* the next packets need to be received and processed */
	SimulationTime batchTime = worker_getConfig()->interfaceBatchTime;

	/* receive packets in batches */
	while(!g_queue_is_empty(interface->inBuffer) &&
			interface->receiveNanosecondsConsumed <= batchTime) {
		/* get the next packet */
		Packet* packet = g_queue_pop_head(interface->inBuffer);
		utility_assert(packet);

		/* successfully received */
		packet_addDeliveryStatus(packet, PDS_RCV_INTERFACE_RECEIVED);
		_networkinterface_pcapWritePacket(interface, packet);

		/* free up buffer space */
		guint length = packet_getPayloadLength(packet) + packet_getHeaderSize(packet);
		interface->inBufferLength -= length;

		/* calculate how long it took to 'receive' this packet */
		interface->receiveNanosecondsConsumed += (length * interface->timePerByteDown);

		/* hand it off to the correct socket layer */
		gint key = packet_getDestinationAssociationKey(packet);
		Socket* socket = g_hash_table_lookup(interface->boundSockets, GINT_TO_POINTER(key));

		/* if the socket closed, just drop the packet */
		gint socketHandle = -1;
		if(socket) {
			socketHandle = *descriptor_getHandleReference((Descriptor*)socket);
			socket_pushInPacket(socket, packet);
		} else {
			packet_addDeliveryStatus(packet, PDS_RCV_INTERFACE_DROPPED);
		}

		packet_unref(packet);

		/* count our bandwidth usage by interface, and by socket handle if possible */
		tracker_addInputBytes(host_getTracker(worker_getCurrentHost()),(guint64)length, socketHandle);
	}

	/*
	 * we need to call back and try to receive more, even if we didnt consume all
	 * of our batch time, because we might have more packets to receive then.
	 */
	SimulationTime receiveTime = (SimulationTime) floor(interface->receiveNanosecondsConsumed);
	if(receiveTime >= SIMTIME_ONE_NANOSECOND) {
		/* we are 'receiving' the packets */
		interface->flags |= NIF_RECEIVING;
		/* call back when the packets are 'received' */
		InterfaceReceivedEvent* event = interfacereceived_new(interface);
		/* event destination is our node */
		worker_scheduleEvent((Event*)event, receiveTime, 0);
	}
}
static void _networkinterface_scheduleNextReceive(NetworkInterface* interface) {
	/* the next packets need to be received and processed */
	SimulationTime batchTime = worker_getConfig()->interfaceBatchTime;

	/* receive packets in batches */
	while(!g_queue_is_empty(interface->inBuffer) &&
			interface->receiveNanosecondsConsumed <= batchTime) {
		/* get the next packet */
		Packet* packet = g_queue_pop_head(interface->inBuffer);
		g_assert(packet);

		/* free up buffer space */
		guint length = packet_getPayloadLength(packet) + packet_getHeaderSize(packet);
		interface->inBufferLength -= length;

		/* hand it off to the correct socket layer */
		gint key = packet_getDestinationAssociationKey(packet);
		Socket* socket = g_hash_table_lookup(interface->boundSockets, GINT_TO_POINTER(key));

		gchar* packetString = packet_getString(packet);
		debug("packet in: %s", packetString);
		g_free(packetString);

		_networkinterface_pcapWritePacket(interface, packet);

		/* if the socket closed, just drop the packet */
		gint socketHandle = -1;
		if(socket) {
			socketHandle = *descriptor_getHandleReference((Descriptor*)socket);
			gboolean needsRetransmit = socket_pushInPacket(socket, packet);
			if(needsRetransmit) {
				/* socket can not handle it now, so drop it */
				_networkinterface_dropInboundPacket(interface, packet);
			}
		}

		/* successfully received, calculate how long it took to 'receive' this packet */
		interface->receiveNanosecondsConsumed += (length * interface->timePerByteDown);
		tracker_addInputBytes(node_getTracker(worker_getPrivate()->cached_node),(guint64)length, socketHandle);
	}

	/*
	 * we need to call back and try to receive more, even if we didnt consume all
	 * of our batch time, because we might have more packets to receive then.
	 */
	SimulationTime receiveTime = (SimulationTime) floor(interface->receiveNanosecondsConsumed);
	if(receiveTime >= SIMTIME_ONE_NANOSECOND) {
		/* we are 'receiving' the packets */
		interface->flags |= NIF_RECEIVING;
		/* call back when the packets are 'received' */
		InterfaceReceivedEvent* event = interfacereceived_new(interface);
		/* event destination is our node */
		worker_scheduleEvent((Event*)event, receiveTime, 0);
	}
}
void networkinterface_packetArrived(NetworkInterface* interface, Packet* packet) {
	MAGIC_ASSERT(interface);

	/* a packet arrived. lets try to receive or buffer it */
	guint length = packet_getPayloadLength(packet) + packet_getHeaderSize(packet);
	gssize space = interface->inBufferSize - interface->inBufferLength;
	g_assert(space >= 0);

	if(length <= space) {
		/* we have space to buffer it */
		g_queue_push_tail(interface->inBuffer, packet);
		interface->inBufferLength += length;

		/* we need a trigger if we are not currently receiving */
		if(!(interface->flags & NIF_RECEIVING)) {
			_networkinterface_scheduleNextReceive(interface);
		}
	} else {
		/* buffers are full, drop packet */
		_networkinterface_dropInboundPacket(interface, packet);
	}
}
Example #5
0
void networkinterface_packetArrived(NetworkInterface* interface, Packet* packet) {
	MAGIC_ASSERT(interface);

	/* a packet arrived. lets try to receive or buffer it */
	guint length = packet_getPayloadLength(packet) + packet_getHeaderSize(packet);
	gssize space = interface->inBufferSize - interface->inBufferLength;
	utility_assert(space >= 0);

	if(length <= space) {
		/* we have space to buffer it */
		packet_ref(packet);
		g_queue_push_tail(interface->inBuffer, packet);
		interface->inBufferLength += length;
		packet_addDeliveryStatus(packet, PDS_RCV_INTERFACE_BUFFERED);

		/* we need a trigger if we are not currently receiving */
		if(!(interface->flags & NIF_RECEIVING)) {
			_networkinterface_scheduleNextReceive(interface);
		}
	} else {
		/* buffers are full, drop packet */
		packet_addDeliveryStatus(packet, PDS_RCV_INTERFACE_DROPPED);
	}
}
Example #6
0
void pcapwriter_writePacket(PCapWriter* pcap, Packet* packet) {
    if(!pcap || !pcap->pcapFile || !packet) {
        return;
    }

    guint32 ts_sec;         /* timestamp seconds */
    guint32 ts_usec;        /* timestamp microseconds */
    guint32 incl_len;       /* number of octets of packet saved in file */
    guint32 orig_len;       /* actual length of packet */

    /* get the current time that the packet is being sent/received */
    SimulationTime now = worker_getCurrentTime();
    ts_sec = now / SIMTIME_ONE_SECOND;
    ts_usec = (now % SIMTIME_ONE_SECOND) / SIMTIME_ONE_MICROSECOND;

    /* get the header and payload lengths */
    guint headerSize = packet_getHeaderSize(packet);
    guint payloadLength = packet_getPayloadLength(packet);
    incl_len = headerSize + payloadLength;
    orig_len = headerSize + payloadLength;

    /* get the TCP header and the payload */
    PacketTCPHeader tcpHeader;
    guchar *payload = g_new0(guchar, payloadLength);
    packet_getTCPHeader(packet, &tcpHeader);
    packet_copyPayload(packet, 0, payload, payloadLength);

    /* write the PCAP packet header to the pcap file */
    fwrite(&ts_sec, sizeof(ts_sec), 1, pcap->pcapFile);
    fwrite(&ts_usec, sizeof(ts_usec), 1, pcap->pcapFile);
    fwrite(&incl_len, sizeof(incl_len), 1, pcap->pcapFile);
    fwrite(&orig_len, sizeof(orig_len), 1, pcap->pcapFile);

    /* write the ethernet header */
    guint8 destinationMAC[6] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB};
    guint8 sourceMAC[6] = {0xA1, 0xB2, 0xC3, 0xD4, 0xE5, 0xF6};
    guint16 type = htons(0x0800);

    fwrite(destinationMAC, 1, sizeof(destinationMAC), pcap->pcapFile);
    fwrite(sourceMAC, 1, sizeof(sourceMAC), pcap->pcapFile);
    fwrite(&type, 1, sizeof(type), pcap->pcapFile);

    /* write the IP header */
    guint8 versionAndHeaderLength = 0x45;
    guint8 fields = 0x00;
    guint16 totalLength = htons(orig_len - 14);
    guint16 identification = 0x0000;
    guint16 flagsAndFragment = 0x0040;
    guint8 timeToLive = 64;
    guint8 protocol = 6;  /* TCP */
    guint16 headerChecksum = 0x0000;
    guint32 sourceIP = tcpHeader.sourceIP;
    guint32 destinationIP = tcpHeader.destinationIP;

    fwrite(&versionAndHeaderLength, 1, sizeof(versionAndHeaderLength), pcap->pcapFile);
    fwrite(&fields, 1, sizeof(fields), pcap->pcapFile);
    fwrite(&totalLength, 1, sizeof(totalLength), pcap->pcapFile);
    fwrite(&identification, 1, sizeof(identification), pcap->pcapFile);
    fwrite(&flagsAndFragment, 1, sizeof(flagsAndFragment), pcap->pcapFile);
    fwrite(&timeToLive, 1, sizeof(timeToLive), pcap->pcapFile);
    fwrite(&protocol, 1, sizeof(protocol), pcap->pcapFile);
    fwrite(&headerChecksum, 1, sizeof(headerChecksum), pcap->pcapFile);
    fwrite(&sourceIP, 1, sizeof(sourceIP), pcap->pcapFile);
    fwrite(&destinationIP, 1, sizeof(destinationIP), pcap->pcapFile);


    /* write the TCP header */
    guint16 sourcePort = tcpHeader.sourcePort;
    guint16 destinationPort = tcpHeader.destinationPort;
    guint32 sequence = tcpHeader.sequence;
    guint32 acknowledgement = 0;
    if(tcpHeader.flags & PTCP_ACK) {
        acknowledgement = htonl(tcpHeader.acknowledgment);
    }
    guint8 headerLength = 0x80;
    guint8 tcpFlags = 0;
    if(tcpHeader.flags & PTCP_RST) tcpFlags |= 0x04;
    if(tcpHeader.flags & PTCP_SYN) tcpFlags |= 0x02;
    if(tcpHeader.flags & PTCP_ACK) tcpFlags |= 0x10;
    if(tcpHeader.flags & PTCP_FIN) tcpFlags |= 0x01;
    guint16 window = tcpHeader.window;
    guint16 tcpChecksum = 0x0000;
    guint8 options[14] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

    fwrite(&sourcePort, 1, sizeof(sourcePort), pcap->pcapFile);
    fwrite(&destinationPort, 1, sizeof(destinationPort), pcap->pcapFile);
    fwrite(&sequence, 1, sizeof(sequence), pcap->pcapFile);
    fwrite(&acknowledgement, 1, sizeof(acknowledgement), pcap->pcapFile);
    fwrite(&headerLength, 1, sizeof(headerLength), pcap->pcapFile);
    fwrite(&tcpFlags, 1, sizeof(tcpFlags), pcap->pcapFile);
    fwrite(&window, 1, sizeof(window), pcap->pcapFile);
    fwrite(&tcpChecksum, 1, sizeof(tcpChecksum), pcap->pcapFile);
    fwrite(options, 1, sizeof(options), pcap->pcapFile);

    /* write payload data */
    if(payloadLength > 0) {
        fwrite(payload, 1, payloadLength, pcap->pcapFile);
    }

    g_free(payload);
}
Example #7
0
static void _networkinterface_scheduleNextSend(NetworkInterface* interface) {
	/* the next packet needs to be sent according to bandwidth limitations.
	 * we need to spend time sending it before sending the next. */
	SimulationTime batchTime = worker_getConfig()->interfaceBatchTime;

	/* loop until we find a socket that has something to send */
	while(interface->sendNanosecondsConsumed <= batchTime) {
		gint socketHandle = -1;

		/* choose which packet to send next based on our queuing discipline */
		Packet* packet;
		switch(interface->qdisc) {
			case NIQ_RR: {
				packet = _networkinterface_selectRoundRobin(interface, &socketHandle);
				break;
			}
			case NIQ_FIFO:
			default: {
				packet = _networkinterface_selectFirstInFirstOut(interface, &socketHandle);
				break;
			}
		}
		if(!packet) {
			break;
		}

		packet_addDeliveryStatus(packet, PDS_SND_INTERFACE_SENT);

		/* now actually send the packet somewhere */
		if(networkinterface_getIPAddress(interface) == packet_getDestinationIP(packet)) {
			/* packet will arrive on our own interface */
			PacketArrivedEvent* event = packetarrived_new(packet);
			/* event destination is our node */
			worker_scheduleEvent((Event*)event, 1, 0);
		} else {
			/* let the worker schedule with appropriate delays */
			worker_schedulePacket(packet);
		}

		/* successfully sent, calculate how long it took to 'send' this packet */
		guint length = packet_getPayloadLength(packet) + packet_getHeaderSize(packet);

		interface->sendNanosecondsConsumed += (length * interface->timePerByteUp);
		tracker_addOutputBytes(host_getTracker(worker_getCurrentHost()),(guint64)length, socketHandle);
		_networkinterface_pcapWritePacket(interface, packet);

		/* sending side is done with its ref */
		packet_unref(packet);
	}

	/*
	 * we need to call back and try to send more, even if we didnt consume all
	 * of our batch time, because we might have more packets to send then.
	 */
	SimulationTime sendTime = (SimulationTime) floor(interface->sendNanosecondsConsumed);
	if(sendTime >= SIMTIME_ONE_NANOSECOND) {
		/* we are 'sending' the packets */
		interface->flags |= NIF_SENDING;
		/* call back when the packets are 'sent' */
		InterfaceSentEvent* event = interfacesent_new(interface);
		/* event destination is our node */
		worker_scheduleEvent((Event*)event, sendTime, 0);
	}
}