Example #1
0
/**
 * Dump LACP packet
 *
 * @v iobuf		I/O buffer
 * @v netdev		Network device
 * @v label		"RX" or "TX"
 */
static void eth_slow_lacp_dump ( struct io_buffer *iobuf,
				 struct net_device *netdev,
				 const char *label ) {
	union eth_slow_packet *eth_slow = iobuf->data;
	struct eth_slow_lacp *lacp = &eth_slow->lacp;

	DBGC ( netdev,
	       "SLOW %s %s LACP actor (%04x,%s,%04x,%02x,%04x) [%s]\n",
	       netdev->name, label, ntohs ( lacp->actor.system_priority ),
	       eth_ntoa ( lacp->actor.system ),
	       ntohs ( lacp->actor.key ),
	       ntohs ( lacp->actor.port_priority ),
	       ntohs ( lacp->actor.port ),
	       eth_slow_lacp_state_name ( lacp->actor.state ) );
	DBGC ( netdev,
	       "SLOW %s %s LACP partner (%04x,%s,%04x,%02x,%04x) [%s]\n",
	       netdev->name, label, ntohs ( lacp->partner.system_priority ),
	       eth_ntoa ( lacp->partner.system ),
	       ntohs ( lacp->partner.key ),
	       ntohs ( lacp->partner.port_priority ),
	       ntohs ( lacp->partner.port ),
	       eth_slow_lacp_state_name ( lacp->partner.state ) );
	DBGC ( netdev, "SLOW %s %s LACP collector %04x (%d us)\n",
	       netdev->name, label, ntohs ( lacp->collector.max_delay ),
	       ( ntohs ( lacp->collector.max_delay ) * 10 ) );
	DBGC2_HDA ( netdev, 0, iobuf->data, iob_len ( iobuf ) );
}
Example #2
0
static PyObject *
ethernet_ntoa(PyObject *self, PyObject *args)
{
	char *nstr;
	char *astr;
	eth_addr_t eth_a;
	int rval;
	int nsize;
	struct intf_entry *entry = NULL;

	rval = PyArg_ParseTuple(args, "s#:eth_ntoa",
					&nstr, &nsize);

	if (!rval) return NULL;
	
	/* printf("Got addresses %s, %s\n", astr, bstr); */
	if (nsize != ETH_ADDR_LEN)
		myerror("Address is wrong length");

	memcpy(&eth_a, nstr, nsize);

	astr = eth_ntoa(&eth_a);
	if (!astr)
		myerror("Could not convert address");

	return Py_BuildValue("s", astr);
}
Example #3
0
/**
 * Fetch MAC address from EEPROM
 *
 * @v smsc95xx		SMSC95xx device
 * @v hw_addr		Hardware address to fill in
 * @ret rc		Return status code
 */
static int smsc95xx_fetch_mac_eeprom ( struct smsc95xx_device *smsc95xx,
				       uint8_t *hw_addr ) {
	int rc;

	/* Read MAC address from EEPROM */
	if ( ( rc = smsc95xx_eeprom_read ( smsc95xx, SMSC95XX_EEPROM_MAC,
					   hw_addr, ETH_ALEN ) ) != 0 )
		return rc;

	/* Check that EEPROM is physically present */
	if ( ! is_valid_ether_addr ( hw_addr ) ) {
		DBGC ( smsc95xx, "SMSC95XX %p has no EEPROM (%s)\n",
		       smsc95xx, eth_ntoa ( hw_addr ) );
		return -ENODEV;
	}

	DBGC ( smsc95xx, "SMSC95XX %p using EEPROM MAC %s\n",
	       smsc95xx, eth_ntoa ( hw_addr ) );
	return 0;
}
Example #4
0
/**
 * Handle AoE configuration command response
 *
 * @v aoe		AoE session
 * @v ll_source		Link-layer source address
 * @ret rc		Return status code
 */
static int aoe_rx_cfg ( struct aoe_session *aoe, const void *ll_source ) {

	/* Record target MAC address */
	memcpy ( aoe->target, ll_source, sizeof ( aoe->target ) );
	DBGC ( aoe, "AoE %p target MAC address %s\n",
	       aoe, eth_ntoa ( aoe->target ) );

	/* Mark config request as complete */
	aoe_done ( aoe, 0 );

	return 0;
}
Example #5
0
/**
 * Dump marker packet
 *
 * @v iobuf		I/O buffer
 * @v netdev		Network device
 * @v label		"RX" or "TX"
 */
static void eth_slow_marker_dump ( struct io_buffer *iobuf,
				   struct net_device *netdev,
				   const char *label ) {
	union eth_slow_packet *eth_slow = iobuf->data;
	struct eth_slow_marker *marker = &eth_slow->marker;

	DBGC ( netdev, "SLOW %s %s marker %s port %04x system %s xact %08x\n",
	       netdev->name, label,
	       eth_slow_marker_tlv_name ( marker->marker.tlv.type ),
	       ntohs ( marker->marker.port ),
	       eth_ntoa ( marker->marker.system ),
	       ntohl ( marker->marker.xact ) );
	DBGC2_HDA ( netdev, 0, iobuf->data, iob_len ( iobuf ) );
}
Example #6
0
/**
 * Fetch MAC address
 *
 * @v smsc95xx		SMSC95xx device
 * @v hw_addr		Hardware address to fill in
 * @ret rc		Return status code
 */
static int smsc95xx_fetch_mac ( struct smsc95xx_device *smsc95xx,
				uint8_t *hw_addr ) {
	int rc;

	/* Read MAC address from EEPROM, if present */
	if ( ( rc = smsc95xx_fetch_mac_eeprom ( smsc95xx, hw_addr ) ) == 0 )
		return 0;

	/* Construct MAC address for Honeywell VM3, if applicable */
	if ( ( rc = smsc95xx_fetch_mac_vm3 ( smsc95xx, hw_addr ) ) == 0 )
		return 0;

	/* Otherwise, generate a random MAC address */
	eth_random_addr ( hw_addr );
	DBGC ( smsc95xx, "SMSC95XX %p using random MAC %s\n",
	       smsc95xx, eth_ntoa ( hw_addr ) );
	return 0;
}
Example #7
0
/**
 * Fill in NIC portion of iBFT
 *
 * @v nic		NIC portion of iBFT
 * @v strings		iBFT string block descriptor
 * @v netdev		Network device
 * @ret rc		Return status code
 */
static int ibft_fill_nic ( struct ibft_nic *nic,
			   struct ibft_string_block *strings,
			   struct net_device *netdev ) {
	struct ll_protocol *ll_protocol = netdev->ll_protocol;
	struct in_addr netmask_addr = { 0 };
	unsigned int netmask_count = 0;
	int rc;

	/* Extract values from DHCP configuration */
	ibft_set_ipaddr_option ( &nic->ip_address, &ip_setting );
	DBG ( "iBFT NIC IP = %s\n", ibft_ipaddr ( &nic->ip_address ) );
	ibft_set_ipaddr_option ( &nic->gateway, &gateway_setting );
	DBG ( "iBFT NIC gateway = %s\n", ibft_ipaddr ( &nic->gateway ) );
	ibft_set_ipaddr_option ( &nic->dns[0], &dns_setting );
	DBG ( "iBFT NIC DNS = %s\n", ibft_ipaddr ( &nic->dns[0] ) );
	if ( ( rc = ibft_set_string_option ( strings, &nic->hostname,
					     &hostname_setting ) ) != 0 )
		return rc;
	DBG ( "iBFT NIC hostname = %s\n",
	      ibft_string ( strings, &nic->hostname ) );

	/* Derive subnet mask prefix from subnet mask */
	fetch_ipv4_setting ( NULL, &netmask_setting, &netmask_addr );
	while ( netmask_addr.s_addr ) {
		if ( netmask_addr.s_addr & 0x1 )
			netmask_count++;
		netmask_addr.s_addr >>= 1;
	}
	nic->subnet_mask_prefix = netmask_count;
	DBG ( "iBFT NIC subnet = /%d\n", nic->subnet_mask_prefix );

	/* Extract values from net-device configuration */
	if ( ( rc = ll_protocol->eth_addr ( netdev->ll_addr,
					    nic->mac_address ) ) != 0 ) {
		DBG ( "Could not determine iBFT MAC: %s\n", strerror ( rc ) );
		return rc;
	}
	DBG ( "iBFT NIC MAC = %s\n", eth_ntoa ( nic->mac_address ) );
	nic->pci_bus_dev_func = netdev->dev->desc.location;
	DBG ( "iBFT NIC PCI = %04x\n", nic->pci_bus_dev_func );

	return 0;
}
Example #8
0
/**
 * Try to fetch initial MAC address
 *
 * @v intel		Intel device
 * @v ral0		RAL0 register address
 * @v hw_addr		Hardware address to fill in
 * @ret rc		Return status code
 */
static int intelx_try_fetch_mac ( struct intel_nic *intel, unsigned int ral0,
				  uint8_t *hw_addr ) {
	union intel_receive_address mac;

	/* Read current address from RAL0/RAH0 */
	mac.reg.low = cpu_to_le32 ( readl ( intel->regs + ral0 ) );
	mac.reg.high = cpu_to_le32 ( readl ( intel->regs + ral0 +
					     ( INTELX_RAH0 - INTELX_RAL0 ) ) );

	/* Use current address if valid */
	if ( is_valid_ether_addr ( mac.raw ) ) {
		DBGC ( intel, "INTEL %p has autoloaded MAC address %s at "
		       "%#05x\n", intel, eth_ntoa ( mac.raw ), ral0 );
		memcpy ( hw_addr, mac.raw, ETH_ALEN );
		return 0;
	}

	return -ENOENT;
}
Example #9
0
/**
 * Construct MAC address for Honeywell VM3
 *
 * @v smsc95xx		SMSC95xx device
 * @v hw_addr		Hardware address to fill in
 * @ret rc		Return status code
 */
static int smsc95xx_fetch_mac_vm3 ( struct smsc95xx_device *smsc95xx,
				    uint8_t *hw_addr ) {
	struct smbios_structure structure;
	struct smbios_system_information system;
	struct {
		char manufacturer[ 10 /* "Honeywell" + NUL */ ];
		char product[ 4 /* "VM3" + NUL */ ];
		char mac[ base16_encoded_len ( ETH_ALEN ) + 1 /* NUL */ ];
	} strings;
	int len;
	int rc;

	/* Find system information */
	if ( ( rc = find_smbios_structure ( SMBIOS_TYPE_SYSTEM_INFORMATION, 0,
					    &structure ) ) != 0 ) {
		DBGC ( smsc95xx, "SMSC95XX %p could not find system "
		       "information: %s\n", smsc95xx, strerror ( rc ) );
		return rc;
	}

	/* Read system information */
	if ( ( rc = read_smbios_structure ( &structure, &system,
					    sizeof ( system ) ) ) != 0 ) {
		DBGC ( smsc95xx, "SMSC95XX %p could not read system "
		       "information: %s\n", smsc95xx, strerror ( rc ) );
		return rc;
	}

	/* NUL-terminate all strings to be fetched */
	memset ( &strings, 0, sizeof ( strings ) );

	/* Fetch system manufacturer name */
	len = read_smbios_string ( &structure, system.manufacturer,
				   strings.manufacturer,
				   ( sizeof ( strings.manufacturer ) - 1 ) );
	if ( len < 0 ) {
		rc = len;
		DBGC ( smsc95xx, "SMSC95XX %p could not read manufacturer "
		       "name: %s\n", smsc95xx, strerror ( rc ) );
		return rc;
	}

	/* Fetch system product name */
	len = read_smbios_string ( &structure, system.product, strings.product,
				   ( sizeof ( strings.product ) - 1 ) );
	if ( len < 0 ) {
		rc = len;
		DBGC ( smsc95xx, "SMSC95XX %p could not read product name: "
		       "%s\n", smsc95xx, strerror ( rc ) );
		return rc;
	}

	/* Ignore non-VM3 devices */
	if ( ( strcmp ( strings.manufacturer, "Honeywell" ) != 0 ) ||
	     ( strcmp ( strings.product, "VM3" ) != 0 ) )
		return -ENOTTY;

	/* Find OEM strings */
	if ( ( rc = find_smbios_structure ( SMBIOS_TYPE_OEM_STRINGS, 0,
					    &structure ) ) != 0 ) {
		DBGC ( smsc95xx, "SMSC95XX %p could not find OEM strings: %s\n",
		       smsc95xx, strerror ( rc ) );
		return rc;
	}

	/* Fetch MAC address */
	len = read_smbios_string ( &structure, SMSC95XX_VM3_OEM_STRING_MAC,
				   strings.mac, ( sizeof ( strings.mac ) - 1 ));
	if ( len < 0 ) {
		rc = len;
		DBGC ( smsc95xx, "SMSC95XX %p could not read OEM string: %s\n",
		       smsc95xx, strerror ( rc ) );
		return rc;
	}

	/* Sanity check */
	if ( len != ( ( int ) ( sizeof ( strings.mac ) - 1 ) ) ) {
		DBGC ( smsc95xx, "SMSC95XX %p invalid MAC address \"%s\"\n",
		       smsc95xx, strings.mac );
		return -EINVAL;
	}

	/* Decode MAC address */
	len = base16_decode ( strings.mac, hw_addr, ETH_ALEN );
	if ( len < 0 ) {
		rc = len;
		DBGC ( smsc95xx, "SMSC95XX %p invalid MAC address \"%s\"\n",
		       smsc95xx, strings.mac );
		return rc;
	}

	DBGC ( smsc95xx, "SMSC95XX %p using VM3 MAC %s\n",
	       smsc95xx, eth_ntoa ( hw_addr ) );
	return 0;
}
Example #10
0
/**
 * Probe device
 *
 * @v pci	PCI device
 * @v id	Matching entry in ID table
 * @ret rc	Return status code
 */
static int b44_probe(struct pci_device *pci, const struct pci_device_id *id)
{
	struct net_device *netdev;
	struct b44_private *bp;
	int rc;

	/*
	 * Bail out if more than 1GB of physical RAM is installed.
	 * This limitation will be removed later when dma mapping
	 * is merged into mainline.
	 */
	if (!phys_ram_within_limit(B44_30BIT_DMA_MASK)) {
		DBG("Sorry, this version of the driver does not\n"
		    "support systems with more than 1GB of RAM.\n");
		return -ENOMEM;
	}

	/* Set up netdev */
	netdev = alloc_etherdev(sizeof(*bp));
	if (!netdev)
		return -ENOMEM;

	netdev_init(netdev, &b44_operations);
	pci_set_drvdata(pci, netdev);
	netdev->dev = &pci->dev;

	/* Set up private data */
	bp = netdev_priv(netdev);
	memset(bp, 0, sizeof(*bp));
	bp->netdev = netdev;
	bp->pci = pci;

	/* Map device registers */
	bp->regs = ioremap(pci->membase, B44_REGS_SIZE);
	if (!bp->regs) {
		netdev_put(netdev);
		return -ENOMEM;
	}

	/* Enable PCI bus mastering */
	adjust_pci_device(pci);

	b44_load_mac_and_phy_addr(bp);

	/* Link management currently not implemented */
	netdev_link_up(netdev);

	rc = register_netdev(netdev);
	if (rc != 0) {
		iounmap(bp->regs);
		netdev_put(netdev);
		return rc;
	}

	b44_chip_reset(bp, B44_CHIP_RESET_FULL);

	DBG("b44 %s (%04x:%04x) regs=%p MAC=%s\n", id->name, id->vendor,
	    id->device, bp->regs, eth_ntoa(netdev->ll_addr));

	return 0;
}
Example #11
0
int main (int argc, char *argv[]) {
	if(argc !=2){
		printf("USAGE: ./executable [input file]\n");
		return(-1);
	}

	/* Variable declarations */
	int fd, count = 0;
	pcap_file_header *phdr;
	my_pkthdr *mypkt;
	timev *ts;
	struct eth_hdr *myeth;
	struct ip_hdr *myip;
	struct tcp_hdr *mytcp;
	//struct eth_addr *myethadr;

	/* Mallocing */
	phdr = malloc(sizeof(pcap_file_header));
	mypkt = malloc(sizeof(my_pkthdr));
	ts = malloc(sizeof(timev));
	myeth = malloc(sizeof(struct eth_hdr));
	myip = malloc(sizeof(struct ip_hdr));
	mytcp = malloc(sizeof(struct tcp_hdr));
	//myethadr = malloc(sizeof(struct eth_addr));

	/* READS----------------------- */
	fd = open(argv[1], O_RDONLY);
	if(fd < 0) {
		fprintf(stderr,"ERROR: open failed on %s\n", argv[1]);
		return(-1);
	}
	if(read(fd, phdr, sizeof(pcap_file_header)) !=sizeof(pcap_file_header)){
		fprintf(stderr,"ERROR: read on %s failed, with call to pcap_file_header *phdr\n", argv[1]);
		close(fd);
		return(-1);
	}
	if(read(fd, mypkt, sizeof(my_pkthdr)) !=sizeof(my_pkthdr)){
		fprintf(stderr,"ERROR: read on %s failed, with call to my_pkthdr *mypkt\n", argv[1]);
		close(fd);
		return(-1);
	}
	if(read(fd, ts, sizeof(timev)) !=sizeof(timev)){
		fprintf(stderr,"ERROR: read on %s failed, with call to timev *ts\n", argv[1]);
		close(fd);
		return(-1);
	}
	if(read(fd, myeth, sizeof(struct eth_hdr)) !=sizeof(struct eth_hdr)){
		fprintf(stderr,"ERROR: read on %s failed, with call to eth_hdr myeth\n", argv[1]);
		close(fd);
		return(-1);
	}
	if(read(fd, myip, sizeof(struct ip_hdr)) !=sizeof(struct ip_hdr)){
		fprintf(stderr,"ERROR: read on %s failed, with call to ip_hdr myip\n", argv[1]);
		close(fd);
		return(-1);
	}
	if(read(fd, mytcp, sizeof(struct tcp_hdr)) !=sizeof(struct tcp_hdr)){
		fprintf(stderr, "ERROR: read on %s failed, with call to tcp_hdr mytcp\n", argv[1]);
		close(fd);
		return(-1);
	}
	/*
	if(read(fd, myethadr, sizeof(struct eth_addr)) !=sizeof(struct eth_addr)){
		fprintf(stderr, "ERROR: read on %s failed, with call to eth_addr myethadr\n", argv[1]);
		close(fd);
		return(-1);
	}
	*/

	fprintf(stdout,"PCAP_MAGIC\n\tVersion major number %d\n\tVersion minor number %d\n\tGMT to local correction %d\n\tTimestamp accuracy %d\n\tSnaplen %d\n\tLinktype %d\n\n",phdr->version_major,phdr->version_minor,phdr->thiszone,phdr->sigfigs,phdr->snaplen,phdr->linktype);
	fprintf(stdout,"Packet %d\n\tCaptured Packet Length: %d\n\tActual Packet Length: %d\n"
			,count,mypkt->caplen,mypkt->len);
	fprintf(stdout,"Ethernet Header\n\teth_src %s\n\teth_dst %s\n\teth_type %d\n"
			,eth_ntoa(&myeth->eth_src),eth_ntoa(&myeth->eth_dst),myeth->eth_type);
	fprintf(stdout,"IP\n\tip len %d\n\tip src %s\n\tip dst %s\n"
			,myip->ip_len,ip_ntoa(&myip->ip_src),ip_ntoa(&myip->ip_dst));
	fprintf(stdout,"TCP\n\tSrc Port %d\n\tDst Port %d\n\tSeq %d\n\tAck %d\n"
			,mytcp->th_sport,mytcp->th_dport,mytcp->th_seq,mytcp->th_ack);
	

	free(phdr);
	free(mypkt);
	free(ts);
	free(myeth);
	free(myip);
	free(mytcp);
	close(fd);
	return(0);
}
Example #12
0
/**************************************************************************
 NE_PROBE - Initialize an adapter ???
 **************************************************************************/
static int ne_probe(struct nic *nic, struct isa_device *isa) {
	int i;
	unsigned char c;
	unsigned char romdata[16];
	unsigned char testbuf[32];

	eth_vendor = VENDOR_NONE;
	eth_drain_receiver = 0;

	nic->irqno = 0;
	nic->ioaddr = isa->ioaddr;
	eth_nic_base = isa->ioaddr;

	/******************************************************************
	 Search for NE1000/2000 if no WD/SMC or 3com cards
	 ******************************************************************/
	if (eth_vendor == VENDOR_NONE) {

		static unsigned char test[] = "NE*000 memory";

		eth_bmem = 0; /* No shared memory */

		eth_flags = FLAG_PIO;
		eth_asic_base = eth_nic_base + NE_ASIC_OFFSET;
		eth_memsize = MEM_16384;
		eth_tx_start = 32;
		eth_rx_start = 32 + D8390_TXBUF_SIZE;
		c = inb(eth_asic_base + NE_RESET);
		outb(c, eth_asic_base + NE_RESET);
		(void) inb(0x84);
		outb(D8390_COMMAND_STP | D8390_COMMAND_RD2, eth_nic_base
				+ D8390_P0_COMMAND);
		outb(D8390_RCR_MON, eth_nic_base + D8390_P0_RCR);
		outb(D8390_DCR_FT1 | D8390_DCR_LS, eth_nic_base + D8390_P0_DCR);
		outb(MEM_8192, eth_nic_base + D8390_P0_PSTART);
		outb(MEM_16384, eth_nic_base + D8390_P0_PSTOP);
		eth_pio_write((unsigned char *) test, 8192, sizeof(test));
		eth_pio_read(8192, testbuf, sizeof(test));
		if (!memcmp(test, testbuf, sizeof(test)))
			goto out;
		eth_flags |= FLAG_16BIT;
		eth_memsize = MEM_32768;
		eth_tx_start = 64;
		eth_rx_start = 64 + D8390_TXBUF_SIZE;
		outb(D8390_DCR_WTS | D8390_DCR_FT1 | D8390_DCR_LS, eth_nic_base
				+ D8390_P0_DCR);
		outb(MEM_16384, eth_nic_base + D8390_P0_PSTART);
		outb(MEM_32768, eth_nic_base + D8390_P0_PSTOP);
		eth_pio_write((unsigned char *) test, 16384, sizeof(test));
		eth_pio_read(16384, testbuf, sizeof(test));
		if (!memcmp(testbuf, test, sizeof(test)))
			goto out;


out:
		if (eth_nic_base == 0)
			return (0);
		if (eth_nic_base > ISA_MAX_ADDR) /* PCI probably */
			eth_flags |= FLAG_16BIT;
		eth_vendor = VENDOR_NOVELL;
		eth_pio_read(0, romdata, sizeof(romdata));
		for (i = 0; i < ETH_ALEN; i++) {
			nic->node_addr[i] = romdata[i + ((eth_flags & FLAG_16BIT) ? i : 0)];
		}
		nic->ioaddr = eth_nic_base;
		DBG("\nNE%c000 base %4.4x, MAC Addr %s\n",
				(eth_flags & FLAG_16BIT) ? '2' : '1', eth_nic_base, eth_ntoa(
						nic->node_addr));
	}

	if (eth_vendor == VENDOR_NONE)
		return (0);

	if (eth_vendor != VENDOR_3COM)
		eth_rmem = eth_bmem;

	ne_reset(nic, isa);
	nic->nic_op = &ne_operations;
	return 1;
}
Example #13
0
main (int argc, char *argv[])
{
    int sd, ret;
    struct ethhdr ethd, *ethdp;
    struct arphdr arphd, *arphdp;
    char ethsaddr[ETH_ALEN], ethdaddr[ETH_ALEN];
    unsigned long ipaddr;
    struct sockaddr_ll haddr;
    char pktbuf[1024];
    fd_set fds;
    struct timeval tv;

    if (argc != 2)
    {
        printf ("Uzycie:\n%s IP\n", argv[0]);
        exit (1);
    }

    if ((ipaddr = inet_addr (argv[1])) < 0)
    {
        perror ("inet_addr()");
        exit (1);
    }

    bcopy (SRCETHADDR, ethsaddr, ETH_ALEN);
    bcopy (DSTETHADDR, ethdaddr, ETH_ALEN);

    sd = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ARP));
    if (sd < 0)
    {
        perror ("socket()");
        exit (1);
    }

    memset (pktbuf, 0, sizeof (pktbuf));
    memcpy (ethd.h_dest, ethdaddr, ETH_ALEN);
    memcpy (ethd.h_source, ethsaddr, ETH_ALEN);
    ethd.h_proto = htons (ETH_P_ARP);
    memcpy (pktbuf, &ethd, sizeof (ethd));

    memset (&arphd, 0, sizeof (arphd));
    arphd.ar_hrd = htons (ARPHRD_ETHER);
    arphd.ar_pro = htons (ETH_P_IP);
    arphd.ar_hln = ETH_ALEN;
    arphd.ar_pln = 4;
    arphd.ar_op = htons (ARPOP_REQUEST);
    memcpy ((char *) &arphd + sizeof (arphd), ethsaddr, ETH_ALEN);
    memset ((char *) &arphd + sizeof (arphd) + ETH_ALEN, 0, 4);
    memset ((char *) &arphd + sizeof (arphd) + ETH_ALEN + 4, 0, ETH_ALEN);
    memcpy ((char *) &arphd + sizeof (arphd) + ETH_ALEN + 4 + ETH_ALEN, &ipaddr,
            4);
    memcpy (pktbuf + 14, &arphd, sizeof (arphd) + 2 * 4 + 2 * ETH_ALEN);

    memset (&haddr, 0, sizeof (haddr));
    haddr.sll_family = AF_PACKET;
    haddr.sll_protocol = htons (ETH_P_ARP);
    haddr.sll_ifindex = 2;

    if (sendto
            (sd, pktbuf, sizeof (ethd) + sizeof (arphd) + 2 * 4 + 2 * ETH_ALEN, 0,
             (struct sockaddr *) &haddr, sizeof (haddr)) < 0)
    {
        perror ("sendto()");
        exit (1);
    }

    FD_ZERO (&fds);
    FD_SET (sd, &fds);

    tv.tv_sec = TIMEOUT;
    tv.tv_usec = 0;

    ret = select (sd + 1, &fds, NULL, NULL, &tv);
    if (ret < 0)
    {
        perror ("select()");
        exit (1);
    }
    else if (ret == 0)
        printf ("Uplynal limit czasu.\n");
    else
    {
        recv (sd, pktbuf, sizeof (pktbuf), 0);

        ethdp = (struct ethhdr *) pktbuf;
        arphdp = (struct arphdr *) (pktbuf + sizeof (struct ethhdr));

        if (ntohs (arphdp->ar_op) == ARPOP_REPLY
                && !memcmp ((char *) arphdp + sizeof (struct arphdr) + ETH_ALEN,
                            &ipaddr, 4))
        {
            printf ("IP\t: %s\n", argv[1]);
            printf ("MAC\t: %s\n", eth_ntoa (ethdp->h_source));
        }
    }

    exit (0);
}