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); } }
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); }
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 */
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); }
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; } }
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; }
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; }
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; }
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); }
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); }
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(ð->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; }
void handle_raw(const u_char * pkt, int len, void *userdata) { handle_ip((struct ip *)pkt, len, userdata); }
dns_message * handle_raw(const u_char * pkt, int len) { return handle_ip((struct ip *) pkt, len); }