示例#1
0
u_int32_t
libnet_get_ipaddr4(libnet_t *l)
{
    struct ifreq ifr;
    register struct sockaddr_in *sin;
    int fd;

    if (l == NULL)
    {
        return (-1);
    }

    /* create dummy socket to perform an ioctl upon */
    fd = socket(PF_INET, SOCK_DGRAM, 0);
    if (fd == -1)
    {
        snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                "%s(): socket(): %s\n", __func__, strerror(errno));
        return (-1);
    }

    sin = (struct sockaddr_in *)&ifr.ifr_addr;

    if (l->device == NULL)
    {
        if (libnet_select_device(l) == -1)
        {
            /* error msg set in libnet_select_device() */
            close(fd);
            return (-1);
        }
    }
    strncpy(ifr.ifr_name, l->device, sizeof(ifr.ifr_name) -1);
	ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0';
	
    ifr.ifr_addr.sa_family = AF_INET;

    if (ioctl(fd, SIOCGIFADDR, (int8_t*) &ifr) < 0)
    {
        snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                "%s(): ioctl(): %s\n", __func__, strerror(errno));
        close(fd);
        return (-1);
    }
    close(fd);
    return (sin->sin_addr.s_addr);
}
示例#2
0
static void ip_validatedata(void)
{
    struct sockaddr_in sin;

    /* validation tests */
    if (iphdr.ip_src.s_addr == 0)
        iphdr.ip_src.s_addr = (u_int32_t)libnet_get_prand(PRu32);
    if (iphdr.ip_dst.s_addr == 0)
        iphdr.ip_dst.s_addr = (u_int32_t)libnet_get_prand(PRu32);

    /* if the user has supplied a source hardware addess but not a device
     * try to select a device automatically
     */
    if (memcmp(etherhdr.ether_shost, zero, 6) && !got_link && !device)
    {
        if (libnet_select_device(&sin, &device, (char *)&errbuf) < 0)
        {
            printf("ERROR: Device not specified and unable to automatically "
                    "select a device.\n");
            ip_exit(1);
        }
        else
        {
#ifdef DEBUG
            printf("DEBUG: automatically selected device: "
                    "       %s\n", device);
#endif
            got_link = 1;
        }
    }

    /* if a device was specified and the user has not specified a source 
     * hardware address, try to determine the source address automatically
     */
    if (got_link)
    { 
        if ((nemesis_check_link(&etherhdr, device)) < 0)
        {
            fprintf(stderr, "ERROR: cannot retrieve hardware address of "
                    "%s.\n", device);
            ip_exit(1);
        }

    }
    return;
}
示例#3
0
struct libnet_ether_addr *
libnet_get_hwaddr(libnet_t *l)
{
    int mib[6];
    size_t len;
    int8_t *buf, *next, *end;
    struct if_msghdr *ifm;
    struct sockaddr_dl *sdl;
    /* This implementation is not-reentrant. */
    static struct libnet_ether_addr ea;

    mib[0] = CTL_NET;
    mib[1] = AF_ROUTE;
    mib[2] = 0;
    mib[3] = AF_LINK;
    mib[4] = NET_RT_IFLIST;
    mib[5] = 0;

    if (l == NULL)
    { 
        return (NULL);
    } 

    if (l->device == NULL)
    {           
        if (libnet_select_device(l) == -1)
        {
            /* err msg set in libnet_select_device */ 
            return (NULL);
        }
    }

    if (sysctl(mib, 6, NULL, &len, NULL, 0) == -1)
    {
        snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): sysctl(): %s",
                __func__, strerror(errno));
        return (NULL);
    }

    buf = (int8_t *)malloc(len);
    if (buf == NULL)
    {
        snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): malloc(): %s",
                __func__, strerror(errno));
        return (NULL);
    }
    if (sysctl(mib, 6, buf, &len, NULL, 0) < 0)
    {
        snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): sysctl(): %s",
                __func__, strerror(errno));
        free(buf);
        return (NULL);
    }
    end = buf + len;

    for (next = buf ; next < end ; next += ifm->ifm_msglen)
    {
        ifm = (struct if_msghdr *)next;
        if (ifm->ifm_version != RTM_VERSION)
            continue;
        if (ifm->ifm_type == RTM_IFINFO)
        {
            sdl = (struct sockaddr_dl *)(ifm + 1);
            if (sdl->sdl_type != IFT_ETHER
                && sdl->sdl_type != IFT_FASTETHER
                && sdl->sdl_type != IFT_FASTETHERFX
                && sdl->sdl_type != IFT_GIGABITETHERNET
                && sdl->sdl_type != IFT_L2VLAN)
                continue;
            if (strncmp(&sdl->sdl_data[0], l->device, sdl->sdl_nlen) == 0)
            {
                memcpy(ea.ether_addr_octet, LLADDR(sdl), ETHER_ADDR_LEN);
                break;
            }
        }
    }
    free(buf);
    if (next == end) {
        snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                 "%s(): interface %s of known type not found.",
                 __func__, l->device);
        return NULL;
    }
    return (&ea);
}
示例#4
0
libnet_t *
libnet_init(int injection_type, const char *device, char *err_buf)
{
    libnet_t *l = NULL;

#if !defined(__WIN32__)
    if (getuid() && geteuid())
    {
        snprintf(err_buf, LIBNET_ERRBUF_SIZE,
                "%s(): UID or EUID of 0 required\n", __func__);
        goto bad;
    }
#else
    WSADATA wsaData;

    if ((WSAStartup(0x0202, &wsaData)) != 0)
    {
        snprintf(err_buf, LIBNET_ERRBUF_SIZE, 
                "%s(): unable to initialize winsock 2\n", __func__);
        goto bad;
    }
#endif

    l = (libnet_t *)malloc(sizeof (libnet_t));
    if (l == NULL)
    {
        snprintf(err_buf, LIBNET_ERRBUF_SIZE, "%s(): malloc(): %s\n", __func__,
                strerror(errno));
        goto bad;
    }
	
    memset(l, 0, sizeof (*l));

    l->injection_type   = injection_type;
    l->ptag_state       = LIBNET_PTAG_INITIALIZER;
    l->device           = (device ? strdup(device) : NULL);

    strncpy(l->label, LIBNET_LABEL_DEFAULT, LIBNET_LABEL_SIZE);
    l->label[sizeof(l->label)] = '\0';

    switch (l->injection_type)
    {
        case LIBNET_LINK:
        case LIBNET_LINK_ADV:
            if (libnet_select_device(l) == -1)
            {
                snprintf(err_buf, LIBNET_ERRBUF_SIZE, "%s", l->err_buf);
		goto bad;
            }
            if (libnet_open_link(l) == -1)
            {
                snprintf(err_buf, LIBNET_ERRBUF_SIZE, "%s", l->err_buf);
                goto bad;
            }
            break;
        case LIBNET_RAW4:
        case LIBNET_RAW4_ADV:
            if (libnet_open_raw4(l) == -1)
            {
                snprintf(err_buf, LIBNET_ERRBUF_SIZE, "%s", l->err_buf);
                goto bad;
            }
            break;
        case LIBNET_RAW6:
        case LIBNET_RAW6_ADV:
            if (libnet_open_raw6(l) == -1)
            {
                snprintf(err_buf, LIBNET_ERRBUF_SIZE, "%s", l->err_buf);
                goto bad;
            }
            break;
        default:
            snprintf(err_buf, LIBNET_ERRBUF_SIZE,
                    "%s(): unsupported injection type\n", __func__);
            goto bad;
            break;
    }

    return (l);

bad:
    if (l)
    {
        libnet_destroy(l);
    }
    return (NULL);
}
示例#5
0
int
main(int argc, char *argv[])
{
    int packet_size,                    /* size of our packet */
        payload_size,                   /* size of our packet */
        c;                              /* misc */
    u_long src_ip, dst_ip;              /* source ip, dest ip */
    u_short bport, eport;               /* beginning and end ports */
    u_short cport;                      /* current port */
    u_char payload[MAX_PAYLOAD_SIZE];   /* packet payload */
    u_char *packet;                     /* pointer to our packet buffer */
    char err_buf[LIBNET_ERRBUF_SIZE];   /* error buffer */
    u_char *device;                     /* pointer to the device to use */
    struct libnet_link_int *network;    /* pointer to link interface struct */
    struct libnet_plist_chain plist;    /* plist chain */
    struct libnet_plist_chain *plist_p; /* plist chain pointer */

    printf("libnet example code:\tmodule 4\n\n");
    printf("packet injection interface:\tlink layer\n");
    printf("packet type:\t\t\tUDP [with payload] using port list chaining\n");

    plist_p = NULL;
    device = NULL;
    src_ip = 0;
    dst_ip = 0;

    while ((c = getopt(argc, argv, "i:d:s:p:")) != EOF)
    {
        switch (c)
        {
            case 'd':
                if (!(dst_ip = libnet_name_resolve(optarg, LIBNET_RESOLVE)))
                {
                    libnet_error(LIBNET_ERR_FATAL,
                            "Bad destination IP address: %s\n", optarg);

                }
                break;
            case 'i':
                device = optarg;
                break;
            case 's':
                if (!(src_ip = libnet_name_resolve(optarg, LIBNET_RESOLVE)))
                {
                    libnet_error(LIBNET_ERR_FATAL,
                            "Bad source IP address: %s\n", optarg);
                }
                break;
            case 'p':
                plist_p = &plist;
                if (libnet_plist_chain_new(&plist_p, optarg) == -1)
                {
                    libnet_error(LIBNET_ERR_FATAL, "Could not build port list\n");
                }
                break;
            default:
                usage(argv[0]);
                exit(EXIT_FAILURE);
        }
    }

    if (!src_ip || !dst_ip || !plist_p)
    {
        usage(argv[0]);
        exit(EXIT_FAILURE);
    }

    c = argc - optind;
    if (c != 1)
    {
        usage(argv[0]);
        exit(EXIT_FAILURE);
    }
    memset(payload, 0, sizeof(payload));
    strncpy(payload, argv[optind], strlen(argv[optind]));


    /*
     *  Step 1: Network Initialization (interchangable with step 2).
     */
    if (device == NULL)
    {
        struct sockaddr_in sin;
        /*
         *  Try to locate a device.
         */
        if (libnet_select_device(&sin, &device, err_buf) == -1)
        {
            libnet_error(LIBNET_ERR_FATAL, "libnet_select_device failed: %s\n", err_buf);
        }
        printf("device:\t\t\t\t%s\n", device);
    }
    if ((network = libnet_open_link_interface(device, err_buf)) == NULL)
    {
        libnet_error(LIBNET_ERR_FATAL, "libnet_open_link_interface: %s\n", err_buf);
    }

    /*
     *  Get the payload from the user.  Hrm.  This might fail on a Sparc
     *  if byte alignment is off...
     */
    payload_size = strlen(payload);

    /*
     *  We're going to build a UDP packet with a payload using the
     *  link-layer API, so this time we need memory for a ethernet header
     *  as well as memory for the ICMP and IP headers and our payload.
     */
    packet_size = LIBNET_IP_H + LIBNET_ETH_H + LIBNET_UDP_H + payload_size;

    /*
     *  Step 2: Memory Initialization (interchangable with step 1).
     */
    if (libnet_init_packet(packet_size, &packet) == -1)
    {
        libnet_error(LIBNET_ERR_FATAL, "libnet_init_packet failed\n");
    }


    /*
     *  Step 3: Packet construction (ethernet header).
     */
    libnet_build_ethernet(enet_dst,
            enet_src,
            ETHERTYPE_IP,
            NULL,
            0,
            packet);

    /*
     *  Step 3: Packet construction (IP header).
     */
    libnet_build_ip(LIBNET_UDP_H + payload_size,
            0,                      /* IP tos */
            242,                    /* IP ID */
            0,                      /* Frag */
            64,                     /* TTL */
            IPPROTO_UDP,            /* Transport protocol */
            src_ip,                 /* Source IP */
            dst_ip,                 /* Destination IP */
            NULL,                   /* Pointer to payload (none) */
            0,
            packet + LIBNET_ETH_H); /* Packet header memory */


    while (libnet_plist_chain_next_pair(plist_p, &bport, &eport))
    {
        while (!(bport > eport) && bport != 0)
        {
            cport = bport++;
            /*
             *  Step 3: Packet construction (UDP header).
             */
            libnet_build_udp(242,           /* source port */
                    cport,                  /* dest. port */
                    payload,                /* payload */ 
                    payload_size,           /* payload length */ 
                    packet + LIBNET_ETH_H + LIBNET_IP_H);

            /*
             *  Step 4: Packet checksums (ICMP header *AND* IP header).
             */
            if (libnet_do_checksum(packet + ETH_H, IPPROTO_UDP, LIBNET_UDP_H + payload_size) == -1)
            {
                libnet_error(LIBNET_ERR_FATAL, "libnet_do_checksum failed\n");
            }
            if (libnet_do_checksum(packet + ETH_H, IPPROTO_IP, LIBNET_IP_H) == -1)
            {
                libnet_error(LIBNET_ERR_FATAL, "libnet_do_checksum failed\n");
            }

            /*
             *  Step 5: Packet injection.
             */
            c = libnet_write_link_layer(network, device, packet, packet_size);
            if (c < packet_size)
            {
                libnet_error(LN_ERR_WARNING, "libnet_write_link_layer only wrote %d bytes\n", c);
            }
            else
            {
                printf("construction and injection completed, wrote all %d bytes, port %d\n", c, cport);
            }
        }
    }
    /*
     *  Shut down the interface.
     */
    if (libnet_close_link_interface(network) == -1)
    {   
        libnet_error(LN_ERR_WARNING, "libnet_close_link_interface couldn't close the interface");
    }


    /*
     *  Free packet memory.
     */
    libnet_destroy_packet(&packet);

    return (c == -1 ? EXIT_FAILURE : EXIT_SUCCESS);
}
示例#6
0
struct libnet_ether_addr *
libnet_get_hwaddr(libnet_t *l)
{
    int mib[6];
    size_t len;
    int8_t *buf, *next, *end;
    struct if_msghdr *ifm;
    struct sockaddr_dl *sdl;
    struct libnet_ether_addr *ea = NULL;

    mib[0] = CTL_NET;
    mib[1] = AF_ROUTE;
    mib[2] = 0;
    mib[3] = AF_LINK;
    mib[4] = NET_RT_IFLIST;
    mib[5] = 0;

    if (l == NULL)
    { 
        return (NULL);
    } 

    if (l->device == NULL)
    {           
        if (libnet_select_device(l) == -1)
        {
            /* err msg set in libnet_select_device */ 
            return (NULL);
        }
    }

    if (sysctl(mib, 6, NULL, &len, NULL, 0) == -1)
    {
        snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): sysctl(): %s\n",
                __func__, strerror(errno));
        return (NULL);
    }

    buf = (int8_t *)malloc(len);
    if (buf == NULL)
    {
        snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): malloc(): %s\n",
                __func__, strerror(errno));
        return (NULL);
    }
    if (sysctl(mib, 6, buf, &len, NULL, 0) < 0)
    {
        snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): sysctl(): %s\n",
                __func__, strerror(errno));
        free(buf);
        return (NULL);
    }
    end = buf + len;

    for (next = buf ; next < end ; next += ifm->ifm_msglen)
    {
        ifm = (struct if_msghdr *)next;
        if (ifm->ifm_type == RTM_IFINFO)
        {
            sdl = (struct sockaddr_dl *)(ifm + 1);
            if (strncmp(&sdl->sdl_data[0], l->device, sdl->sdl_nlen) == 0)
            {
                if (!(ea = malloc(sizeof(struct libnet_ether_addr))))
                {
                    snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
                            "%s(): malloc(): %s", __func__, strerror(errno));
                    free(buf);
                    return (NULL);
                }
                memcpy(ea->ether_addr_octet, LLADDR(sdl), ETHER_ADDR_LEN);
                break;
            }
        }
    }
    free(buf);
    return (ea);
}
示例#7
0
文件: injection.c 项目: chemag/pktd
/*
 * injection_write_ip
 *
 * Description:
 *	- Write an IP packet into the wire. It can use either raw sockets 
 *		or the wire
 *
 * Inputs:
 *	- ip_packet: the IP packet
 *
 * Outputs:
 *	- return: 0 if ok, <0 if there were problems
 *
 */
int injection_write_ip (u_char *ip_packet)
{
#if defined(INJECT_USING_RAW_SOCKETS) || defined(INJECT_USING_LINK_LAYER)
	int i;
	u_int16_t packet_size = ntohs(*(u_int16_t*)(ip_packet+2));
#endif


#if defined(INJECT_USING_RAW_SOCKETS)
	int network;

	/* network initialization */
	if ((network = libnet_open_raw_sock(IPPROTO_RAW)) < 0) {
		return WIRE_ERR_PKTD_INJECTION_OPEN;

	/* packet injection */
	} else if ((i = libnet_write_ip (network, ip_packet, packet_size))
			< packet_size) {
		return WIRE_ERR_PKTD_INJECTION_WRITE_IP;

	/* shut down the interface */
	} else if (libnet_close_raw_sock (network) < 0) {
		return WIRE_ERR_PKTD_INJECTION_CLOSE;

	}

	return WIRE_ERR_NONE;

#elif defined(INJECT_USING_LINK_LAYER)

	char buffer[LIBNET_ETH_H+IP_MAXPACKET];
	struct in_addr in;
	int size = 1024;
	struct libnet_link_int *network; /* pointer to link interface struct */
	char *interface = NULL; /* pointer to the device to use */
	struct sockaddr_in sin;
	char errbuf[1024];
	struct ether_addr remote_eth, *tmp_eth;



	/* network initialization */
	if (libnet_select_device(&sin, &interface, errbuf) == -1) {
		return WIRE_ERR_PKTD_NO_WRITE_DEVICE_ACCESS;
	}
	if ((network = libnet_open_link_interface(interface, errbuf)) == NULL) {
 		return WIRE_ERR_PKTD_INJECTION_OPEN;
	}


	/* get local ethernet address */
	if ((tmp_eth = libnet_get_hwaddr(network, interface, errbuf)) == NULL) {
		(void)libnet_close_link_interface(network);
		return WIRE_ERR_PKTD_INJECTION_OPEN;
	}
	memcpy (&local_eth, tmp_eth, 6);

	debug3 ("injection_write_ip: the local ethernet address is %s\n", 
			ether_ntoa(&local_eth));


	/* get remote ethernet address (the packet is already in network order) */
	in.s_addr = *(u_int32_t*)(ip_packet+16);

	/* try to get the remote MAC address from the ARP cache */
	if (get_mac_address (in, buffer, size) < 0) {
		/* MAC address of the IP address not in ARP cache */

		/* get the gateway needed to reach the destination */
		struct in_addr gw;
		if (get_gateway (in, &gw) < 0) {
			debug3 ("injection_write_ip: can't find MAC nor gateway for %s\n", 
					inet_ntoa(in));
			(void)libnet_close_link_interface(network);
			return WIRE_ERR_PKTD_INJECTION_WRITE_IP;
		}

		/* get the gateway's ethernet address */
		if (get_mac_address (gw, buffer, size) < 0) {
			debug3 ("injection_write_ip: can't find MAC for %s's ", 
					inet_ntoa(in));
			debug3 ("gateway (%s)\n", inet_ntoa(gw));
			/* XXX: This case means typically the destination host is in 
			 * the same network than the source, but the destination MAC 
			 * address is not in the local ARP cache. Getting a local 
			 * MAC address requires implementing ARP, which we won't do 
			 * at this moment
			 */
			(void)libnet_close_link_interface(network);
			return WIRE_ERR_PKTD_INJECTION_WRITE_IP;
		}

		debug3 ("injection_write_ip: IP address %s can be reached ", inet_ntoa(in));
		debug3 ("through gateway %s (%s)\n", inet_ntoa(gw), buffer);
	} else {
		debug3 ("injection_write_ip: IP address %s corresponds to %s\n", 
				inet_ntoa(in), buffer);
	}

	if ((tmp_eth = ether_aton (buffer)) == NULL) {
		(void)libnet_close_link_interface(network);
		return WIRE_ERR_PKTD_INJECTION_WRITE_IP;
	}
	memcpy (&remote_eth, tmp_eth, 6);


  /* build ethernet header and use IP packet as payload */
#if (defined(bsdi) || defined(__NetBSD__) || defined(__OpenBSD__) ||\
		defined(__FreeBSD__))
	libnet_build_ethernet(&(remote_eth.octet[0]), 
			&(local_eth.octet[0]), ETHERTYPE_IP, NULL, 0, buffer);
#else
	libnet_build_ethernet(&(remote_eth.ether_addr_octet[0]), 
			&(local_eth.ether_addr_octet[0]), ETHERTYPE_IP, NULL, 0, buffer);
#endif
	memcpy (buffer+LIBNET_ETH_H, ip_packet, packet_size);
	packet_size += LIBNET_ETH_H;


	/* inject the packet */
	if ((i = libnet_write_link_layer (network, interface, buffer,
			packet_size)) < packet_size) {
		(void)libnet_close_link_interface(network);
		return WIRE_ERR_PKTD_INJECTION_WRITE_IP;
	}


	/* shut down the interface */
	(void)libnet_close_link_interface(network);

	return WIRE_ERR_NONE;
#else /* INJECT_USING_LINK_LAYER */
	return(0);
#endif /* INJECT_USING_LINK_LAYER */
}