Exemple #1
0
void
handle_ether(const u_char * pkt, int len, void *userdata)
{
    struct ether_header *e = (struct ether_header *)pkt;
    unsigned short etype;
    if (len < ETHER_HDR_LEN)
	return;
    etype = nptohs(&e->ether_type);
    if (callback_ether)
	if (0 != callback_ether(pkt, len, userdata))
	    return;
    pkt += ETHER_HDR_LEN;
    len -= ETHER_HDR_LEN;
    if (ETHERTYPE_8021Q == etype) {
	unsigned short vlan = nptohs((unsigned short *) pkt);
	if (callback_vlan)
	    if (0 != callback_vlan(vlan, userdata))
		return;
	etype = nptohs((unsigned short *)(pkt + 2));
	pkt += 4;
	len -= 4;
    }
    if (len < 0)
	return;
    /* fprintf(stderr, "Ethernet packet of len %d ethertype %#04x\n", len, etype); */
    if (is_ethertype_ip(etype)) {
	handle_ip((struct ip *)pkt, len, userdata);
    }
}
Exemple #2
0
void
handle_loop(const u_char * pkt, int len, void *userdata)
{
    unsigned int family = nptohl(pkt);
    if (is_family_inet(family))
	handle_ip((struct ip *)(pkt + 4), len - 4, userdata);
}
Exemple #3
0
void sr_handlepacket(struct sr_instance* sr,
        uint8_t * packet/* lent */,
        unsigned int len,
        char* interface/* lent */)
{
  /* REQUIRES */
  assert(sr);
  assert(packet);
  assert(interface);

  printf("*** -> Received packet of length %d \n",len);

  uint8_t *pkt = malloc(len);
  memcpy(pkt, packet, len);

  sr_ethernet_hdr_t *hdr = get_ethernet_hdr(pkt);
  
  enum sr_ethertype type = ntohs(hdr->ether_type);
  
  if (type == ethertype_arp) {
    char *inf_cpy = malloc(sr_IFACE_NAMELEN);
    memcpy(inf_cpy, interface, sr_IFACE_NAMELEN);
    handle_arp(sr, pkt, inf_cpy, len);
  } else if (type == ethertype_ip) {
    handle_ip(sr, pkt, len);
  } else {
    fprintf(stderr, "invalid packet type id in ethernet header\n");
  }

}/* end sr_ForwardPacket */
Exemple #4
0
void
handle_ppp(const u_char * pkt, int len, void *userdata)
{
    char buf[PCAP_SNAPLEN];
    unsigned short proto;
    if (len < 2)
	return NULL;
    if (*pkt == PPP_ADDRESS_VAL && *(pkt + 1) == PPP_CONTROL_VAL) {
	pkt += 2;		/* ACFC not used */
	len -= 2;
    }
    if (len < 2)
	return NULL;
    if (*pkt % 2) {
	proto = *pkt;		/* PFC is used */
	pkt++;
	len--;
    } else {
	proto = nptohs(pkt);
	pkt += 2;
	len -= 2;
    }
    if (is_ethertype_ip(proto))
	handle_ip((struct ip *)pkt, len, userdata);
}
Exemple #5
0
void handle_ether(const struct timeval& t, WifipcapCallbacks *cbs, const u_char *ptr, int len)
{
    ether_hdr_t hdr;

    hdr.da = ether2MAC(ptr);
    hdr.sa = ether2MAC(ptr+6);
    hdr.type = EXTRACT_16BITS(ptr + 12);

    ptr += 14;
    len -= 14;

    cbs->HandleEthernet(t, &hdr, ptr, len);

    switch (hdr.type) {
    case ETHERTYPE_IP:
	handle_ip(t, cbs, ptr, len);
	return;
    case ETHERTYPE_IPV6:
	handle_ip6(t, cbs, ptr, len);
	return;
    case ETHERTYPE_ARP:
	handle_arp(t, cbs, ptr, len);
	return;
    default:
	cbs->HandleL2Unknown(t, hdr.type, ptr, len);
	return;
    }
}
Exemple #6
0
dns_message *
handle_ether(const u_char * pkt, int len)
{
    char buf[PCAP_SNAPLEN];
    struct ether_header *e = (void *) pkt;
    unsigned short etype = ntohs(e->ether_type);
    if (len < ETHER_HDR_LEN)
	return NULL;
    pkt += ETHER_HDR_LEN;
    len -= ETHER_HDR_LEN;
    if (ETHERTYPE_8021Q == etype) {
	if (!match_vlan(pkt))
	    return NULL;
	etype = ntohs(*(unsigned short *) (pkt + 2));
	pkt += 4;
	len -= 4;
    }
    if (len < 0)
	return NULL;
    if (is_ethertype_ip(etype)) {
	memcpy(buf, pkt, len);
	return handle_ip((struct ip *) buf, len);
    }
    return NULL;
}
Exemple #7
0
dns_message *
handle_ppp(const u_char * pkt, int len)
{
    char buf[PCAP_SNAPLEN];
    unsigned short us;
    unsigned short proto;
    if (len < 2)
	return NULL;
    if (*pkt == PPP_ADDRESS_VAL && *(pkt + 1) == PPP_CONTROL_VAL) {
	pkt += 2;		/* ACFC not used */
	len -= 2;
    }
    if (len < 2)
	return NULL;
    if (*pkt % 2) {
	proto = *pkt;		/* PFC is used */
	pkt++;
	len--;
    } else {
	memcpy(&us, pkt, sizeof(us));
	proto = ntohs(us);
	pkt += 2;
	len -= 2;
    }
    if (is_ethertype_ip(proto)) {
        memcpy(buf, pkt, len);
        return handle_ip((struct ip *) buf, len);
    }
    return NULL;
}
Exemple #8
0
dns_message *
handle_loop(const u_char * pkt, int len)
{
    unsigned int family;
    memcpy(&family, pkt, sizeof(family));
    if (is_family_inet(family))
	return handle_ip((struct ip *) (pkt + 4), len - 4);
    return NULL;
}
Exemple #9
0
void
handle_linux_sll(const u_char * pkt, int len, void *userdata)
{
    struct sll_header *s = (struct sll_header *)pkt;
    unsigned short etype, eproto;

    if (len < SLL_HDR_LEN)
	return;
    etype = nptohs(&s->sll_pkttype);
    if (etype == LINUX_SLL_BROADCAST || etype == LINUX_SLL_MULTICAST)
	return;
    eproto = nptohs(&s->sll_protocol);
    if (eproto != ETHERTYPE_IP)
	return;
    pkt += SLL_HDR_LEN;
    len -= SLL_HDR_LEN;
    /* fprintf(stderr, "linnux cooked packet of len %d type %#04x proto %#04x\n", len, etype, eproto); */
    handle_ip((struct ip *)pkt, len, userdata);
}
Exemple #10
0
void
handle_gre(const u_char * gre, int len, void *userdata)
{
    int grelen = 4;
    unsigned short flags = nptohs(gre);
    unsigned short etype = nptohs(gre + 2);
    if (len < grelen)
	return;
    if (callback_gre)
	callback_gre(gre, len, userdata);
    if (flags & 0x0001)		/* checksum present? */
	grelen += 4;
    if (flags & 0x0004)		/* key present? */
	grelen += 4;
    if (flags & 0x0008)		/* sequence number present? */
	grelen += 4;
    if (is_ethertype_ip(etype))
	handle_ip((struct ip *) (gre + grelen), len - grelen, userdata);
}
Exemple #11
0
static void read_packet(unsigned char* buf, uint16_t len) {
  if (len < sizeof(struct ether_header)) {
    lput_str("Ethernet header was too short");
    return;
  }
  struct ether_header* eth = (struct ether_header*)buf;
  if (memcmp(eth->dest, MAC_ADDRESS, ETHER_ADDR_LEN) != 0 &&
      memcmp(eth->dest, BROADCAST_ADDRESS, ETHER_ADDR_LEN) != 0) {
    lput_str("Ignoring packet not meant for me");
    return;
  } 
  uint16_t payload_len = len - sizeof(struct ether_header);
  unsigned char* payload = (unsigned char*)(eth + 1);
  ntohs(&eth->type);
  switch (eth->type) {
    case ETHERTYPE_IP:
      if (payload_len < sizeof(struct ip_header)) {
        lput_str("IP header was too short");
        return;
      }
      unsigned char* ip_payload = payload + sizeof(struct ip_header);
      uint16_t ip_payload_len = payload_len - sizeof(struct ip_header);
      handle_ip((struct ip_header*)payload, ip_payload, ip_payload_len);
      break;
    case ETHERTYPE_ARP:
      if (payload_len < sizeof(struct arp_header)) {
        lput_str("ARP header was too short");
        return;
      }
      handle_arp((struct arp_header*)payload);
      break;
    default:
      lput_str("Unknown ETHERTYPE:");
      lput16_hex(eth->type);
      lput_str("\r\n");
      break;
  }
}
int check_tun(const struct arguments *args,
              const struct epoll_event *ev,
              const int epoll_fd,
              int sessions, int maxsessions) {
    // Check tun error
    if (ev->events & EPOLLERR) {
        log_android(ANDROID_LOG_ERROR, "tun %d exception", args->tun);
        if (fcntl(args->tun, F_GETFL) < 0) {
            log_android(ANDROID_LOG_ERROR, "fcntl tun %d F_GETFL error %d: %s",
                        args->tun, errno, strerror(errno));
            report_exit(args, "fcntl tun %d F_GETFL error %d: %s",
                        args->tun, errno, strerror(errno));
        } else
            report_exit(args, "tun %d exception", args->tun);
        return -1;
    }

    // Check tun read
    if (ev->events & EPOLLIN) {
        uint8_t *buffer = malloc(get_mtu());
        ssize_t length = read(args->tun, buffer, get_mtu());
        if (length < 0) {
            free(buffer);

            log_android(ANDROID_LOG_ERROR, "tun %d read error %d: %s",
                        args->tun, errno, strerror(errno));
            if (errno == EINTR || errno == EAGAIN)
                // Retry later
                return 0;
            else {
                report_exit(args, "tun %d read error %d: %s",
                            args->tun, errno, strerror(errno));
                return -1;
            }
        }
        else if (length > 0) {
            // Write pcap record
            if (pcap_file != NULL)
                write_pcap_rec(buffer, (size_t) length);

            if (length > max_tun_msg) {
                max_tun_msg = length;
                log_android(ANDROID_LOG_WARN, "Maximum tun msg length %d", max_tun_msg);
            }

            // Handle IP from tun
            handle_ip(args, buffer, (size_t) length, epoll_fd, sessions, maxsessions);

            free(buffer);
        }
        else {
            // tun eof
            free(buffer);

            log_android(ANDROID_LOG_ERROR, "tun %d empty read", args->tun);
            report_exit(args, "tun %d empty read", args->tun);
            return -1;
        }
    }

    return 0;
}
Exemple #13
0
void
handle_raw(const u_char * pkt, int len, void *userdata)
{
    handle_ip((struct ip *)pkt, len, userdata);
}
Exemple #14
0
dns_message *
handle_raw(const u_char * pkt, int len)
{
    return handle_ip((struct ip *) pkt, len);
}