コード例 #1
0
int
Secondary_Ipaddr_Handler::init_netlink_request (
                                                char* const ip_slash_netmask,
                                                const char *const if_name,
                                                Netlink_Request& net_req,
                                                bool action)
{
  ACE_OS::memset (&net_req, 0, sizeof(net_req));

  // fill the request header
  net_req.nhdr_.nlmsg_len =
    NLMSG_LENGTH (sizeof(struct ifaddrmsg));
  net_req.nhdr_.nlmsg_flags = NLM_F_REQUEST;
  net_req.nhdr_.nlmsg_type = action ? RTM_NEWADDR : RTM_DELADDR;
  net_req.ifa_.ifa_family = AF_INET;

  int interface_index = -1;
  if (get_if_index (if_name,
                    interface_index) == -1 || interface_index < 0)
    {
      ACE_OS::fprintf (stderr, "get_if_index () - failed\n");
      return -1;
    }
  net_req.ifa_.ifa_index = interface_index;

  Inet_Prefix local_prefix;

  if (fill_inet_prefix (local_prefix,
                        ip_slash_netmask) == -1)
    {
      ACE_OS::fprintf (stderr, "fill_inet_prefix () - failed\n");
      return -1;
    }

  fill_rtnetlink_request (net_req.nhdr_,
                          IFA_LOCAL,
                          &local_prefix.data,
                          local_prefix.bytelen);

  net_req.ifa_.ifa_prefixlen = local_prefix.bitlen; // number of bits in netmask
  net_req.ifa_.ifa_scope = 0;

  return 0;
}
コード例 #2
0
ファイル: ethercap.c プロジェクト: fengyikil/ethernet
int main(int argc, char *argv[])
{
    struct sockaddr_ll srcethaddr;  /* man 7 packet    */
    struct sockaddr_ll bindethaddr; /* man 7 packet    */
    struct packet_mreq mr;          /* man 7 packet    */
    struct ifreq ifr;               /* man 7 netdevice */
    int nbytes;
    socklen_t addrlen;

    /* how big should the buffer be?
     *
     * This can be determined by MTU. MTU can be obtained by an ioctl call:
     *
     *         ioctl(socket, SIOCGIFMTU, &ifr)
     *
     * where socket is a socket descriptor, ifr is of type struct ifreq.
     * More information can be found at manual page netdevice(7). Note that
     * one needs to give ifr_name to invoke the ioctl call. If a program 
     * retrieves frames from more than one device, the maximum MTU among
     * the devices should be used. 
     *
     * In Linux, available network devices can be obtained in multiple
     * methods, commonly, 
     * (1) by walking through the /proc/net/dev file. 
     * (2) by calling ioctl(...) with request SIOCGIFCONF
     * (3) via rtnetlink socket
     *
     * MTU does not include header/trailer. For capturing Ethernet frames,
     * the buffer size should be set no less than 
     * 6 + 6 + 2 + MTU = ETHER_HDR_LEN + MTU.
     *
     * Question: how does IEEE 802.1Q affect the required buffer size?
     * */

    int bufsize;      /* how big should the buffer be? */
    int ifindex;      /* interface index               */

    setupsignal(SIGINT, cleanup);    /* capture CTRL-C */

    if (argc < 2) {
        usage(argv[0]);
        exit(1);
    }

    /* open a raw packet socket to capture all types of ethernet frames */
    sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
    if (sockfd < 0) {
        perror("socket(AF_PACKET, SOCK_RAW, ETH_P_ALL) failed");
        exit(1);
    }

    /* obtain interface index from interface name */
    if ((ifindex = get_if_index(sockfd, argv[1])) == -1) {
        fprintf(stderr, 
                "failed to obtain interface index for interface %s\n", 
                argv[1]);
        exit(1);
    }

    /* put the interface into promiscuous mode. man 7 packet */
    memset(&mr, 0, sizeof(mr));
    mr.mr_ifindex = ifindex;
    mr.mr_type =  PACKET_MR_PROMISC;
    if (setsockopt(sockfd, SOL_PACKET, 
            PACKET_ADD_MEMBERSHIP, (char *)&mr, sizeof(mr)) != 0) {
        perror("setsockopt(sockfd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, ...)");
        exit(1);
    }
    

    /* bind the socket to the interface. see bind(2) and packet(7) */
    memset(&bindethaddr, 0, sizeof(bindethaddr));
    bindethaddr.sll_family = AF_PACKET;
    bindethaddr.sll_protocol = htons(ETH_P_ALL);
    bindethaddr.sll_ifindex = ifindex;
    if (bind(sockfd, 
		(struct sockaddr*)&bindethaddr, sizeof(bindethaddr)) != 0) {
        perror("bind(sockfd, &bindethaddr, sizeof(bindethaddr))");
        exit(1);
    }

    /* obtain MTU. see netdevice(7) */
    ifr.ifr_addr.sa_family = AF_PACKET;
    safe_strncpy(ifr.ifr_name, argv[1], IFNAMSIZ);
    if (ioctl(sockfd, SIOCGIFMTU, &ifr) != 0) {
        perror("ioctl(sockfd, SIOCGIFMTU, &ifr)");
        exit (1);
    }

    /* allocate buffer */
    bufsize = ifr.ifr_mtu + ETHER_HDR_LEN;
    if ((buf = malloc(bufsize)) == NULL) {
        fprintf(stderr, "insufficient memory\n");
        exit(1);
    }

    /* begin capturing */
    memset(&srcethaddr, 0, sizeof(srcethaddr));
    while (1) {

        addrlen = sizeof(srcethaddr);
        nbytes = recvfrom(sockfd, buf, bufsize, 
                0, (struct sockaddr*)&srcethaddr, &addrlen);

        if (nbytes < 0) {
            perror("recv(sockfd ...) failed");
            exit (1);
        }
    
        /* dump captured frame */
        printf("Captured at interface: %s frame from ", argv[1]);
        dump_physical_address(srcethaddr.sll_halen, srcethaddr.sll_addr);
        printf("\n");
        dumpbuf(buf, nbytes);
        /**
         * flush the buffer so that we don't have to rely on stdbuf, as in
         *     sudo stdbuf -o 0 ./ethercap eth0 | tee frame_captured.txt
         */
        fflush(stdout);
    }

    /* remove the interface's promiscuous mode */
    setsockopt(sockfd, SOL_PACKET, 
            PACKET_DROP_MEMBERSHIP, (char *)&mr, sizeof(mr));

    free(buf);
    close(sockfd);

    return 0;
}