/* FIXME this won't work with TCP or IPv4 data, which is probably a bug */ libnet_ptag_t libnet_build_data(const uint8_t *payload, uint32_t payload_s, libnet_t *l, libnet_ptag_t ptag) { uint32_t n, h; libnet_pblock_t *p; if (l == NULL) { return (-1); } n = payload_s; h = 0; /* no checksum on generic block */ /* * Find the existing protocol block if a ptag is specified, or create * a new one. */ p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_DATA_H); if (p == NULL) { return (-1); } /* boilerplate payload sanity check / append macro */ LIBNET_DO_PAYLOAD(l, p); return (ptag ? ptag : libnet_pblock_update(l, p, h, LIBNET_PBLOCK_DATA_H)); bad: libnet_pblock_delete(l, p); return (-1); }
libnet_ptag_t libnet_build_ospfv2(uint16_t len, uint8_t type, uint32_t rtr_id, uint32_t area_id, uint16_t sum, uint16_t autype, const uint8_t *payload, uint32_t payload_s, libnet_t *l, libnet_ptag_t ptag) { uint32_t n, h; libnet_pblock_t *p; struct libnet_ospf_hdr ospf_hdr; if (l == NULL) { return (-1); } n = LIBNET_OSPF_H + payload_s; h = LIBNET_OSPF_H + payload_s + len; /* * Find the existing protocol block if a ptag is specified, or create * a new one. */ p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_OSPF_H); if (p == NULL) { return (-1); } memset(&ospf_hdr, 0, sizeof(ospf_hdr)); ospf_hdr.ospf_v = 2; /* OSPF version 2 */ ospf_hdr.ospf_type = type; /* Type of pkt */ ospf_hdr.ospf_len = htons(h); /* Pkt len */ ospf_hdr.ospf_rtr_id.s_addr = rtr_id; /* Router ID */ ospf_hdr.ospf_area_id.s_addr = area_id; /* Area ID */ ospf_hdr.ospf_sum = sum; ospf_hdr.ospf_auth_type = htons(autype); /* Type of auth */ n = libnet_pblock_append(l, p, (uint8_t *)&ospf_hdr, LIBNET_OSPF_H); if (n == -1) { goto bad; } /* boilerplate payload sanity check / append macro */ LIBNET_DO_PAYLOAD(l, p); if (sum == 0) { /* * If checksum is zero, by default libnet will compute a checksum * for the user. The programmer can override this by calling * libnet_toggle_checksum(l, ptag, 1); */ libnet_pblock_setflags(p, LIBNET_PBLOCK_DO_CHECKSUM); } return (ptag ? ptag : libnet_pblock_update(l, p, h, LIBNET_PBLOCK_OSPF_H)); bad: libnet_pblock_delete(l, p); return (-1); }
libnet_ptag_t libnet_build_igmp(uint8_t type, uint8_t code, uint16_t sum, uint32_t ip, const uint8_t *payload, uint32_t payload_s, libnet_t *l, libnet_ptag_t ptag) { uint32_t n, h; libnet_pblock_t *p; struct libnet_igmp_hdr igmp_hdr; if (l == NULL) { return (-1); } n = LIBNET_IGMP_H + payload_s; h = LIBNET_IGMP_H; /* * Find the existing protocol block if a ptag is specified, or create * a new one. */ p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_IGMP_H); if (p == NULL) { return (-1); } memset(&igmp_hdr, 0, sizeof(igmp_hdr)); igmp_hdr.igmp_type = type; /* packet type */ igmp_hdr.igmp_code = code; /* packet code */ igmp_hdr.igmp_sum = (sum ? htons(sum) : 0); /* packet checksum */ igmp_hdr.igmp_group.s_addr = htonl(ip); n = libnet_pblock_append(l, p, (uint8_t *)&igmp_hdr, LIBNET_IGMP_H); if (n == -1) { goto bad; } /* boilerplate payload sanity check / append macro */ LIBNET_DO_PAYLOAD(l, p); if (sum == 0) { /* * If checksum is zero, by default libnet will compute a checksum * for the user. The programmer can override this by calling * libnet_toggle_checksum(l, ptag, 1); */ libnet_pblock_setflags(p, LIBNET_PBLOCK_DO_CHECKSUM); } return (ptag ? ptag : libnet_pblock_update(l, p, h, LIBNET_PBLOCK_IGMP_H)); bad: libnet_pblock_delete(l, p); return (-1); }
libnet_ptag_t libnet_build_isl(uint8_t *dhost, uint8_t type, uint8_t user, uint8_t *shost, uint16_t len, uint8_t *snap, uint16_t vid, uint16_t portindex, uint16_t reserved, const uint8_t *payload, uint32_t payload_s, libnet_t *l, libnet_ptag_t ptag) { uint32_t n, h; libnet_pblock_t *p; struct libnet_isl_hdr isl_hdr; if (l == NULL) { return (-1); } n = LIBNET_ISL_H + payload_s; /* size of memory block */ h = 0; /* * Find the existing protocol block if a ptag is specified, or create * a new one. */ p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_ISL_H); if (p == NULL) { return (-1); } memset(&isl_hdr, 0, sizeof (isl_hdr)); memcpy(&isl_hdr.isl_dhost, dhost, 5); isl_hdr.isl_type = type; isl_hdr.isl_user = user; memcpy(&isl_hdr.isl_shost, shost, 6); isl_hdr.isl_len = htons(len); memcpy(&isl_hdr.isl_dhost, snap, 6); isl_hdr.isl_vid = htons(vid); isl_hdr.isl_index = htons(portindex); isl_hdr.isl_reserved= htons(reserved); n = libnet_pblock_append(l, p, (uint8_t *)&isl_hdr, LIBNET_ISL_H); if (n == -1) { goto bad; } /* boilerplate payload sanity check / append macro */ LIBNET_DO_PAYLOAD(l, p); /* we need to compute the CRC for the ethernet frame and the ISL frame */ libnet_pblock_setflags(p, LIBNET_PBLOCK_DO_CHECKSUM); return (ptag ? ptag : libnet_pblock_update(l, p, LIBNET_ISL_H, LIBNET_PBLOCK_ISL_H)); bad: libnet_pblock_delete(l, p); return (-1); }
libnet_ptag_t libnet_build_ethernet(const uint8_t *dst, const uint8_t *src, uint16_t type, const uint8_t *payload, uint32_t payload_s, libnet_t *l, libnet_ptag_t ptag) { uint32_t n, h; libnet_pblock_t *p; struct libnet_ethernet_hdr eth_hdr; if (l == NULL) { return (-1); } /* sanity check injection type if we're not in advanced mode */ if (l->injection_type != LIBNET_LINK && !(((l->injection_type) & LIBNET_ADV_MASK))) { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): called with non-link layer wire injection primitive", __func__); p = NULL; goto bad; } n = LIBNET_ETH_H + payload_s; h = 0; /* * Find the existing protocol block if a ptag is specified, or create * a new one. */ p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_ETH_H); if (p == NULL) { return (-1); } memset(ð_hdr, 0, sizeof(eth_hdr)); memcpy(eth_hdr.ether_dhost, dst, ETHER_ADDR_LEN); /* destination address */ memcpy(eth_hdr.ether_shost, src, ETHER_ADDR_LEN); /* source address */ eth_hdr.ether_type = htons(type); /* packet type */ n = libnet_pblock_append(l, p, (uint8_t *)ð_hdr, LIBNET_ETH_H); if (n == -1) { goto bad; } /* boilerplate payload sanity check / append macro */ LIBNET_DO_PAYLOAD(l, p); return (ptag ? ptag : libnet_pblock_update(l, p, h, LIBNET_PBLOCK_ETH_H)); bad: libnet_pblock_delete(l, p); return (-1); }
libnet_ptag_t libnet_build_sebek(uint32_t magic, uint16_t version, uint16_t type, uint32_t counter, uint32_t time_sec, uint32_t time_usec, uint32_t pid, uint32_t uid, uint32_t fd, uint8_t cmd[SEBEK_CMD_LENGTH], uint32_t length, const uint8_t *payload, uint32_t payload_s, libnet_t *l, libnet_ptag_t ptag) { uint32_t n; libnet_pblock_t *p; struct libnet_sebek_hdr sebek_hdr; if (l == NULL) { return (-1); } n = LIBNET_SEBEK_H + payload_s; /* size of memory block */ /* * Find the existing protocol block if a ptag is specified, or create * a new one. */ p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_SEBEK_H); if (p == NULL) { return (-1); } memset(&sebek_hdr, 0, sizeof(sebek_hdr)); sebek_hdr.magic = htonl(magic); sebek_hdr.version = htons(version); sebek_hdr.type = htons(type); sebek_hdr.counter = htonl(counter); sebek_hdr.time_sec = htonl(time_sec); sebek_hdr.time_usec = htonl(time_usec); sebek_hdr.pid = htonl(pid); sebek_hdr.uid = htonl(uid); sebek_hdr.fd = htonl(fd); memcpy(sebek_hdr.cmd, cmd, SEBEK_CMD_LENGTH*sizeof(uint8_t)); sebek_hdr.length = htonl(length); n = libnet_pblock_append(l, p, (uint8_t *)&sebek_hdr, LIBNET_SEBEK_H); if (n == -1) { goto bad; } /* boilerplate payload sanity check / append macro */ LIBNET_DO_PAYLOAD(l, p); return (ptag ? ptag : libnet_pblock_update(l, p, 0, LIBNET_PBLOCK_SEBEK_H)); bad: libnet_pblock_delete(l, p); return (-1); }
libnet_ptag_t libnet_build_rip(uint8_t cmd, uint8_t version, uint16_t rd, uint16_t af, uint16_t rt, uint32_t addr, uint32_t mask, uint32_t next_hop, uint32_t metric, const uint8_t *payload, uint32_t payload_s, libnet_t *l, libnet_ptag_t ptag) { uint32_t n, h; libnet_pblock_t *p; struct libnet_rip_hdr rip_hdr; if (l == NULL) { return (-1); } n = LIBNET_RIP_H + payload_s; h = 0; /* * Find the existing protocol block if a ptag is specified, or create * a new one. */ p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_RIP_H); if (p == NULL) { return (-1); } memset(&rip_hdr, 0, sizeof(rip_hdr)); rip_hdr.rip_cmd = cmd; rip_hdr.rip_ver = version; rip_hdr.rip_rd = htons(rd); rip_hdr.rip_af = htons(af); rip_hdr.rip_rt = htons(rt); rip_hdr.rip_addr = addr; rip_hdr.rip_mask = mask; rip_hdr.rip_next_hop = next_hop; rip_hdr.rip_metric = htonl(metric); n = libnet_pblock_append(l, p, (uint8_t *)&rip_hdr, LIBNET_RIP_H); if (n == -1) { goto bad; } /* boilerplate payload sanity check / append macro */ LIBNET_DO_PAYLOAD(l, p); return (ptag ? ptag : libnet_pblock_update(l, p, h, LIBNET_PBLOCK_RIP_H)); bad: libnet_pblock_delete(l, p); return (-1); }
libnet_ptag_t libnet_build_ospfv2_lsa_rtr(uint16_t flags, uint16_t num, uint32_t id, uint32_t data, uint8_t type, uint8_t tos, uint16_t metric, const uint8_t *payload, uint32_t payload_s, libnet_t *l, libnet_ptag_t ptag) { uint32_t n, h; libnet_pblock_t *p; struct libnet_rtr_lsa_hdr rtr_lsa_hdr; if (l == NULL) { return (-1); } n = LIBNET_OSPF_LS_RTR_H + payload_s; h = 0; /* * Find the existing protocol block if a ptag is specified, or create * a new one. */ p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_LS_RTR_H); if (p == NULL) { return (-1); } memset(&rtr_lsa_hdr, 0, sizeof(rtr_lsa_hdr)); rtr_lsa_hdr.rtr_flags = htons(flags); rtr_lsa_hdr.rtr_num = htons(num); rtr_lsa_hdr.rtr_link_id = htonl(id); rtr_lsa_hdr.rtr_link_data = htonl(data); rtr_lsa_hdr.rtr_type = type; rtr_lsa_hdr.rtr_tos_num = tos; rtr_lsa_hdr.rtr_metric = htons(metric); n = libnet_pblock_append(l, p, (uint8_t *)&rtr_lsa_hdr, LIBNET_OSPF_LS_RTR_H); if (n == -1) { goto bad; } /* boilerplate payload sanity check / append macro */ LIBNET_DO_PAYLOAD(l, p); return (ptag ? ptag : libnet_pblock_update(l, p, h, LIBNET_PBLOCK_LS_RTR_H)); bad: libnet_pblock_delete(l, p); return (-1); }
libnet_ptag_t libnet_build_ospfv2_hello(uint32_t netmask, uint16_t interval, uint8_t opts, uint8_t priority, uint32_t dead_int, uint32_t des_rtr, uint32_t bkup_rtr, const uint8_t *payload, uint32_t payload_s, libnet_t *l, libnet_ptag_t ptag) { uint32_t n, h; libnet_pblock_t *p; struct libnet_ospf_hello_hdr hello_hdr; if (l == NULL) { return (-1); } n = LIBNET_OSPF_HELLO_H + payload_s; h = 0; /* * Find the existing protocol block if a ptag is specified, or create * a new one. */ p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_OSPF_HELLO_H); if (p == NULL) { return (-1); } memset(&hello_hdr, 0, sizeof(hello_hdr)); hello_hdr.hello_nmask.s_addr = netmask; /* Netmask */ hello_hdr.hello_intrvl = htons(interval); /* # seconds since last packet sent */ hello_hdr.hello_opts = opts; /* OSPF_* options */ hello_hdr.hello_rtr_pri = priority; /* If 0, can't be backup */ hello_hdr.hello_dead_intvl = htonl(dead_int); /* Time til router is deemed down */ hello_hdr.hello_des_rtr.s_addr = des_rtr; /* Networks designated router */ hello_hdr.hello_bkup_rtr.s_addr = bkup_rtr; /* Networks backup router */ /*hello_hdr.hello_nbr.s_addr = htonl(neighbor); */ n = libnet_pblock_append(l, p, (uint8_t *)&hello_hdr, LIBNET_OSPF_HELLO_H); if (n == -1) { goto bad; } /* boilerplate payload sanity check / append macro */ LIBNET_DO_PAYLOAD(l, p); return (ptag ? ptag : libnet_pblock_update(l, p, h, LIBNET_PBLOCK_OSPF_HELLO_H)); bad: libnet_pblock_delete(l, p); return (-1); }
libnet_ptag_t libnet_build_ipsec_ah(uint8_t nh, uint8_t len, uint16_t res, uint32_t spi, uint32_t seq, uint32_t auth, const uint8_t *payload, uint32_t payload_s, libnet_t *l, libnet_ptag_t ptag) { uint32_t n, h; libnet_pblock_t *p; struct libnet_ah_hdr ah_hdr; if (l == NULL) { return (-1); } n = LIBNET_IPSEC_AH_H + payload_s;/* size of memory block */ h = 0; /* * Find the existing protocol block if a ptag is specified, or create * a new one. */ p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_IPSEC_AH_H); if (p == NULL) { return (-1); } memset(&ah_hdr, 0, sizeof(ah_hdr)); ah_hdr.ah_nh = nh; /* next header */ ah_hdr.ah_len = len; /* length */ ah_hdr.ah_res = (res ? htons(res) : 0); ah_hdr.ah_spi = htonl(spi); /* SPI */ ah_hdr.ah_seq = htonl(seq); /* AH sequence number */ ah_hdr.ah_auth = htonl(auth); /* authentication data */ n = libnet_pblock_append(l, p, (uint8_t *)&ah_hdr, LIBNET_IPSEC_AH_H); if (n == -1) { goto bad; } /* boilerplate payload sanity check / append macro */ LIBNET_DO_PAYLOAD(l, p); return (ptag ? ptag : libnet_pblock_update(l, p, h, LIBNET_PBLOCK_IPSEC_AH_H)); bad: libnet_pblock_delete(l, p); return (-1); }
libnet_ptag_t libnet_build_ospfv2_lsa_as(uint32_t nmask, uint32_t metric, uint32_t fwdaddr, uint32_t tag, const uint8_t *payload, uint32_t payload_s, libnet_t *l, libnet_ptag_t ptag) { uint32_t n, h; libnet_pblock_t *p; struct libnet_as_lsa_hdr as_lsa_hdr; if (l == NULL) { return (-1); } n = LIBNET_OSPF_LS_AS_EXT_H + payload_s; h = 0; /* * Find the existing protocol block if a ptag is specified, or create * a new one. */ p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_LS_AS_EXT_H); if (p == NULL) { return (-1); } memset(&as_lsa_hdr, 0, sizeof(as_lsa_hdr)); as_lsa_hdr.as_nmask.s_addr = htonl(nmask); as_lsa_hdr.as_metric = htonl(metric); as_lsa_hdr.as_fwd_addr.s_addr = htonl(fwdaddr); as_lsa_hdr.as_rte_tag = htonl(tag); n = libnet_pblock_append(l, p, (uint8_t *)&as_lsa_hdr, LIBNET_OSPF_LS_AS_EXT_H); if (n == -1) { goto bad; } /* boilerplate payload sanity check / append macro */ LIBNET_DO_PAYLOAD(l, p); return (ptag ? ptag : libnet_pblock_update(l, p, h, LIBNET_PBLOCK_LS_AS_EXT_H)); bad: libnet_pblock_delete(l, p); return (-1); }
libnet_ptag_t libnet_build_ipsec_esp_ftr(uint8_t len, uint8_t nh, int8_t *auth, const uint8_t *payload, uint32_t payload_s, libnet_t *l, libnet_ptag_t ptag) { /* XXX we need to know the size of auth */ uint32_t n, h; libnet_pblock_t *p; struct libnet_esp_ftr esp_ftr; if (l == NULL) { return (-1); } n = LIBNET_IPSEC_ESP_FTR_H + payload_s;/* size of memory block */ h = 0; memset(&esp_ftr, 0, sizeof(esp_ftr)); esp_ftr.esp_pad_len = len; /* pad length */ esp_ftr.esp_nh = nh; /* next header pointer */ esp_ftr.esp_auth = auth; /* authentication data */ /* * Find the existing protocol block if a ptag is specified, or create * a new one. */ p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_IPSEC_ESP_FTR_H); if (p == NULL) { return (-1); } n = libnet_pblock_append(l, p, (uint8_t *)&esp_ftr, LIBNET_IPSEC_ESP_FTR_H); if (n == -1) { goto bad; } /* boilerplate payload sanity check / append macro */ LIBNET_DO_PAYLOAD(l, p); return (ptag ? ptag : libnet_pblock_update(l, p, h, LIBNET_PBLOCK_IPSEC_ESP_FTR_H)); bad: libnet_pblock_delete(l, p); return (-1); }
libnet_ptag_t libnet_build_ospfv2_dbd(uint16_t dgram_len, uint8_t opts, uint8_t type, uint32_t seqnum, const uint8_t *payload, uint32_t payload_s, libnet_t *l, libnet_ptag_t ptag) { uint32_t n, h; libnet_pblock_t *p; struct libnet_dbd_hdr dbd_hdr; if (l == NULL) { return (-1); } n = LIBNET_OSPF_DBD_H + payload_s; h = 0; /* * Find the existing protocol block if a ptag is specified, or create * a new one. */ p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_OSPF_DBD_H); if (p == NULL) { return (-1); } memset(&dbd_hdr, 0, sizeof(dbd_hdr)); dbd_hdr.dbd_mtu_len = htons(dgram_len); /* Max length of IP packet IF can use */ dbd_hdr.dbd_opts = opts; /* OSPF_* options */ dbd_hdr.dbd_type = type; /* Type of exchange occuring */ dbd_hdr.dbd_seq = htonl(seqnum); /* DBD sequence number */ n = libnet_pblock_append(l, p, (uint8_t *)&dbd_hdr, LIBNET_OSPF_DBD_H); if (n == -1) { goto bad; } /* boilerplate payload sanity check / append macro */ LIBNET_DO_PAYLOAD(l, p); return (ptag ? ptag : libnet_pblock_update(l, p, h, LIBNET_PBLOCK_OSPF_DBD_H)); bad: libnet_pblock_delete(l, p); return (-1); }
libnet_ptag_t libnet_build_ospfv2_lsr(uint32_t type, uint32_t lsid, uint32_t advrtr, const uint8_t *payload, uint32_t payload_s, libnet_t *l, libnet_ptag_t ptag) { uint32_t n, h; libnet_pblock_t *p; struct libnet_lsr_hdr lsr_hdr; if (l == NULL) { return (-1); } n = LIBNET_OSPF_LSR_H + payload_s; h = 0; /* * Find the existing protocol block if a ptag is specified, or create * a new one. */ p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_OSPF_LSR_H); if (p == NULL) { return (-1); } memset(&lsr_hdr, 0, sizeof(lsr_hdr)); lsr_hdr.lsr_type = htonl(type); /* Type of LS being requested */ lsr_hdr.lsr_lsid = htonl(lsid); /* Link State ID */ lsr_hdr.lsr_adrtr.s_addr = htonl(advrtr); /* Advertising router */ n = libnet_pblock_append(l, p, (uint8_t *)&lsr_hdr, LIBNET_OSPF_LSR_H); if (n == -1) { goto bad; } /* boilerplate payload sanity check / append macro */ LIBNET_DO_PAYLOAD(l, p); return (ptag ? ptag : libnet_pblock_update(l, p, h, LIBNET_PBLOCK_OSPF_LSR_H)); bad: libnet_pblock_delete(l, p); return (-1); }
libnet_ptag_t libnet_build_ipsec_esp_hdr(uint32_t spi, uint32_t seq, uint32_t iv, const uint8_t *payload, uint32_t payload_s, libnet_t *l, libnet_ptag_t ptag) { uint32_t n, h; libnet_pblock_t *p; struct libnet_esp_hdr esp_hdr; if (l == NULL) { return (-1); } n = LIBNET_IPSEC_ESP_HDR_H + payload_s;/* size of memory block */ h = 0; memset(&esp_hdr, 0, sizeof(esp_hdr)); esp_hdr.esp_spi = htonl(spi); /* SPI */ esp_hdr.esp_seq = htonl(seq); /* ESP sequence number */ esp_hdr.esp_iv = htonl(iv); /* initialization vector */ /* * Find the existing protocol block if a ptag is specified, or create * a new one. */ p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_IPSEC_ESP_HDR_H); if (p == NULL) { return (-1); } n = libnet_pblock_append(l, p, (uint8_t *)&esp_hdr, LIBNET_IPSEC_ESP_HDR_H); if (n == -1) { goto bad; } /* boilerplate payload sanity check / append macro */ LIBNET_DO_PAYLOAD(l, p); return (ptag ? ptag : libnet_pblock_update(l, p, h, LIBNET_PBLOCK_IPSEC_ESP_HDR_H)); bad: libnet_pblock_delete(l, p); return (-1); }
libnet_ptag_t libnet_build_802_1x(uint8_t eap_ver, uint8_t eap_type, uint16_t length, const uint8_t *payload, uint32_t payload_s, libnet_t *l, libnet_ptag_t ptag) { uint32_t n, h; libnet_pblock_t *p; struct libnet_802_1x_hdr dot1x_hdr; if (l == NULL) { return (-1); } n = LIBNET_802_1X_H + payload_s; h = 0; /* * Find the existing protocol block if a ptag is specified, or create * a new one. */ p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_802_1X_H); if (p == NULL) { return (-1); } memset(&dot1x_hdr, 0, sizeof(dot1x_hdr)); dot1x_hdr.dot1x_version = eap_ver; dot1x_hdr.dot1x_type = eap_type; dot1x_hdr.dot1x_length = htons(length); n = libnet_pblock_append(l, p, (uint8_t *)&dot1x_hdr, LIBNET_802_1X_H); if (n == (uint32_t)-1) { goto bad; } LIBNET_DO_PAYLOAD(l, p); return (ptag ? ptag : libnet_pblock_update(l, p, h, LIBNET_PBLOCK_802_1X_H)); bad: libnet_pblock_delete(l, p); return (-1); }
libnet_ptag_t libnet_build_ospfv2_lsu(uint32_t num, const uint8_t *payload, uint32_t payload_s, libnet_t *l, libnet_ptag_t ptag) { uint32_t n, h; libnet_pblock_t *p; struct libnet_lsu_hdr lh_hdr; if (l == NULL) { return (-1); } n = LIBNET_OSPF_LSU_H + payload_s; h = 0; /* * Find the existing protocol block if a ptag is specified, or create * a new one. */ p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_OSPF_LSU_H); if (p == NULL) { return (-1); } memset(&lh_hdr, 0, sizeof(lh_hdr)); lh_hdr.lsu_num = htonl(num); /* Number of LSAs that will be bcasted */ n = libnet_pblock_append(l, p, (uint8_t *)&lh_hdr, LIBNET_OSPF_LSU_H); if (n == -1) { goto bad; } /* boilerplate payload sanity check / append macro */ LIBNET_DO_PAYLOAD(l, p); return (ptag ? ptag : libnet_pblock_update(l, p, h, LIBNET_PBLOCK_OSPF_LSU_H)); bad: libnet_pblock_delete(l, p); return (-1); }
libnet_ptag_t libnet_build_cdp(uint8_t version, uint8_t ttl, uint16_t sum, uint16_t type, uint16_t len, const uint8_t *value, const uint8_t *payload, uint32_t payload_s, libnet_t *l, libnet_ptag_t ptag) { uint32_t n,h; libnet_pblock_t *p; struct libnet_cdp_hdr cdp_hdr; if (l == NULL) { return (-1); } n = LIBNET_CDP_H + LIBNET_CDP_H + len + payload_s; h = LIBNET_CDP_H + LIBNET_CDP_H + len + payload_s; /* * Find the existing protocol block if a ptag is specified, or create * a new one. */ p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_CDP_H); if (p == NULL) { return (-1); } memset(&cdp_hdr, 0, sizeof(cdp_hdr)); cdp_hdr.cdp_version = version; cdp_hdr.cdp_ttl = ttl; cdp_hdr.cdp_sum = (sum ? htons(sum) : 0); cdp_hdr.cdp_type = htons(type); cdp_hdr.cdp_len = htons(len + 4); /* 4 bytes for len and type */ n = libnet_pblock_append(l, p, (uint8_t *)&cdp_hdr, LIBNET_CDP_H); if (n == -1) { goto bad; } n = libnet_pblock_append(l, p, value, len); if (n == -1) { /* err msg set in libnet_pblock_append() */ goto bad; } /* boilerplate payload sanity check / append macro */ LIBNET_DO_PAYLOAD(l, p); if (sum == 0) { /* * If checksum is zero, by default libnet will compute a checksum * for the user. The programmer can override this by calling * libnet_toggle_checksum(l, ptag, 1); */ libnet_pblock_setflags(p, LIBNET_PBLOCK_DO_CHECKSUM); } return (ptag ? ptag : libnet_pblock_update(l, p, h, LIBNET_PBLOCK_CDP_H)); bad: libnet_pblock_delete(l, p); return (-1); }
/* * Routing (variable) * * The Routing field is optional and is present only if the Routing * Present bit is set to 1. * * The Routing field is a list of Source Route Entries (SREs). Each * SRE has the form: * * 0 1 2 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Address Family | SRE Offset | SRE Length | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Routing Information ... * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * */ libnet_ptag_t libnet_build_gre_sre(uint16_t af, uint8_t offset, uint8_t length, uint8_t *routing, const uint8_t *payload, uint32_t payload_s, libnet_t *l, libnet_ptag_t ptag) { uint32_t n; libnet_pblock_t *p; struct libnet_gre_sre_hdr sre_hdr; if (l == NULL) { return (-1); } n = LIBNET_GRE_SRE_H + length + payload_s; /* * Find the existing protocol block if a ptag is specified, or create * a new one. */ p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_GRE_SRE_H); if (p == NULL) { return (-1); } sre_hdr.af = htons(af); sre_hdr.sre_offset = offset; sre_hdr.sre_length = length; n = libnet_pblock_append(l, p, (uint8_t *)&sre_hdr, LIBNET_GRE_SRE_H); if (n == -1) { /* err msg set in libnet_pblock_append() */ goto bad; } if ((routing && !length) || (!routing && length)) { sprintf(l->err_buf, "%s(): routing inconsistency\n", __func__); goto bad; } if (routing && length) { n = libnet_pblock_append(l, p, routing, length); if (n == -1) { /* err msg set in libnet_pblock_append() */ goto bad; } } /* boilerplate payload sanity check / append macro */ LIBNET_DO_PAYLOAD(l, p); return (ptag ? ptag : libnet_pblock_update(l, p, 0, LIBNET_PBLOCK_GRE_SRE_H)); bad: libnet_pblock_delete(l, p); return (-1); }
libnet_ptag_t libnet_build_gre(uint16_t fv, uint16_t type, uint16_t sum, uint16_t offset, uint32_t key, uint32_t seq, uint16_t len, const uint8_t *payload, uint32_t payload_s, libnet_t *l, libnet_ptag_t ptag) { uint32_t n; libnet_pblock_t *p; struct libnet_gre_hdr gre_hdr; if (l == NULL) { return (-1); } n = libnet_getgre_length(fv) + payload_s; /* * Find the existing protocol block if a ptag is specified, or create * a new one. */ p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_GRE_H); if (p == NULL) { return (-1); } gre_hdr.flags_ver = htons(fv); gre_hdr.type = htons(type); n = libnet_pblock_append(l, p, (uint8_t *)&gre_hdr, LIBNET_GRE_H); if (n == -1) { /* err msg set in libnet_pblock_append() */ goto bad; } if ((!(fv & GRE_VERSION_MASK) && (fv & (GRE_CSUM|GRE_ROUTING))) || /* v0 */ (fv & GRE_VERSION_MASK)) /* v1 */ { sum = htons(sum); n = libnet_pblock_append(l, p, (uint8_t*)&sum, sizeof(gre_hdr.gre_sum)); if (n == -1) { /* err msg set in libnet_pblock_append() */ goto bad; } offset = htons(offset); n = libnet_pblock_append(l, p, (uint8_t*)&offset, sizeof(gre_hdr.gre_offset)); if (n == -1) { /* err msg set in libnet_pblock_append() */ goto bad; } } if ((!(fv & GRE_VERSION_MASK) && (fv & GRE_KEY)) || /* v0 */ ( (fv & GRE_VERSION_MASK) && (fv & GRE_SEQ)) ) /* v1 */ { key = htonl(key); n = libnet_pblock_append(l, p, (uint8_t*)&key, sizeof(gre_hdr.gre_key)); if (n == -1) { /* err msg set in libnet_pblock_append() */ goto bad; } } if ((!(fv & GRE_VERSION_MASK) && (fv & GRE_SEQ)) || /* v0 */ ( (fv & GRE_VERSION_MASK) && (fv & GRE_ACK)) ) /* v1 */ { seq = htonl(seq); n = libnet_pblock_append(l, p, (uint8_t*)&seq, sizeof(gre_hdr.gre_seq)); if (n == -1) { /* err msg set in libnet_pblock_append() */ goto bad; } } /* boilerplate payload sanity check / append macro */ LIBNET_DO_PAYLOAD(l, p); if ( (fv & GRE_CSUM) && (!sum) ) { libnet_pblock_setflags(p, LIBNET_PBLOCK_DO_CHECKSUM); } return (ptag ? ptag : libnet_pblock_update(l, p, len, LIBNET_PBLOCK_GRE_H)); bad: libnet_pblock_delete(l, p); return (-1); }
libnet_ptag_t libnet_build_arp(uint16_t hrd, uint16_t pro, uint8_t hln, uint8_t pln, uint16_t op, const uint8_t *sha, const uint8_t *spa, const uint8_t *tha, const uint8_t *tpa, const uint8_t *payload, uint32_t payload_s, libnet_t *l, libnet_ptag_t ptag) { uint32_t n, h; libnet_pblock_t *p; struct libnet_arp_hdr arp_hdr; if (l == NULL) { return (-1); } n = LIBNET_ARP_H + (2 * hln) + (2 * pln) + payload_s; h = 0; /* ARP headers have no checksum */ /* * Find the existing protocol block if a ptag is specified, or create * a new one. */ p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_ARP_H); if (p == NULL) { return (-1); } memset(&arp_hdr, 0, sizeof(arp_hdr)); arp_hdr.ar_hrd = htons(hrd); /* hardware address type */ arp_hdr.ar_pro = htons(pro); /* protocol address type */ arp_hdr.ar_hln = hln; /* hardware address length */ arp_hdr.ar_pln = pln; /* protocol address length */ arp_hdr.ar_op = htons(op); /* opcode command */ n = libnet_pblock_append(l, p, (uint8_t *)&arp_hdr, LIBNET_ARP_H); if (n == -1) { /* err msg set in libnet_pblock_append() */ goto bad; } n = libnet_pblock_append(l, p, sha, hln); if (n == -1) { /* err msg set in libnet_pblock_append() */ goto bad; } n = libnet_pblock_append(l, p, spa, pln); if (n == -1) { /* err msg set in libnet_pblock_append() */ goto bad; } n = libnet_pblock_append(l, p, tha, hln); if (n == -1) { /* err msg set in libnet_pblock_append() */ goto bad; } n = libnet_pblock_append(l, p, tpa, pln); if (n == -1) { /* err msg set in libnet_pblock_append() */ goto bad; } /* boilerplate payload sanity check / append macro */ LIBNET_DO_PAYLOAD(l, p); return (ptag ? ptag : libnet_pblock_update(l, p, h, LIBNET_PBLOCK_ARP_H)); bad: libnet_pblock_delete(l, p); return (-1); }
libnet_ptag_t libnet_build_ntp(uint8_t leap_indicator, uint8_t version, uint8_t mode, uint8_t stratum, uint8_t poll, uint8_t precision, uint16_t delay_int, uint16_t delay_frac, uint16_t dispersion_int, uint16_t dispersion_frac, uint32_t reference_id, uint32_t ref_ts_int, uint32_t ref_ts_frac, uint32_t orig_ts_int, uint32_t orig_ts_frac, uint32_t rec_ts_int, uint32_t rec_ts_frac, uint32_t xmt_ts_int, uint32_t xmt_ts_frac, const uint8_t *payload, uint32_t payload_s, libnet_t *l, libnet_ptag_t ptag) { uint32_t n, h; libnet_pblock_t *p; struct libnet_ntp_hdr ntp_hdr; if (l == NULL) { return (-1); } n = LIBNET_NTP_H + payload_s; h = 0; /* * Find the existing protocol block if a ptag is specified, or create * a new one. */ p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_NTP_H); if (p == NULL) { return (-1); } memset(&ntp_hdr, 0, sizeof(ntp_hdr)); ntp_hdr.ntp_li_vn_mode = LIBNET_NTP_DO_LI_VN_MODE( leap_indicator, version, mode); ntp_hdr.ntp_stratum = stratum; ntp_hdr.ntp_poll = poll; ntp_hdr.ntp_precision = precision; ntp_hdr.ntp_delay.integer = htons(delay_int); ntp_hdr.ntp_delay.fraction = htons(delay_frac); ntp_hdr.ntp_dispersion.integer = htons(dispersion_int); ntp_hdr.ntp_dispersion.fraction = htons(dispersion_frac); ntp_hdr.ntp_reference_id = htonl(reference_id); ntp_hdr.ntp_ref_ts.integer = htonl(ref_ts_int); ntp_hdr.ntp_ref_ts.fraction = htonl(ref_ts_frac); ntp_hdr.ntp_orig_ts.integer = htonl(orig_ts_int); ntp_hdr.ntp_orig_ts.fraction = htonl(orig_ts_frac); ntp_hdr.ntp_rec_ts.integer = htonl(rec_ts_int); ntp_hdr.ntp_rec_ts.fraction = htonl(rec_ts_frac); ntp_hdr.ntp_xmt_ts.integer = htonl(xmt_ts_int); ntp_hdr.ntp_xmt_ts.fraction = htonl(xmt_ts_frac); n = libnet_pblock_append(l, p, (uint8_t *)&ntp_hdr, LIBNET_NTP_H); if (n == -1) { goto bad; } /* boilerplate payload sanity check / append macro */ LIBNET_DO_PAYLOAD(l, p); return (ptag ? ptag : libnet_pblock_update(l, p, h, LIBNET_PBLOCK_NTP_H)); bad: libnet_pblock_delete(l, p); return (-1); }
libnet_ptag_t libnet_build_rpc_call(u_int32_t rm, u_int32_t xid, u_int32_t prog_num, u_int32_t prog_vers, u_int32_t procedure, u_int32_t cflavor, u_int32_t clength, u_int8_t *cdata, u_int32_t vflavor, u_int32_t vlength, u_int8_t *vdata, u_int8_t *payload, u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag) { u_int32_t n, h; libnet_pblock_t *p; struct libnet_rpc_call_tcp_hdr rpc_hdr; if (l == NULL) { return (-1); } /* Credential and Verifier buffers not yet implemented. * n = LIBNET_RPC_CALL_H + clength + vlength + payload_s; */ if (rm) { n = LIBNET_RPC_CALL_TCP_H + payload_s; } else { n = LIBNET_RPC_CALL_H + payload_s; } h = 0; /* * Find the existing protocol block if a ptag is specified, or create * a new one. */ p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_RPC_CALL_H); if (p == NULL) { return (-1); } memset(&rpc_hdr, 0, sizeof(rpc_hdr)); if (rm) { rpc_hdr.rpc_record_marking = htonl(rm + payload_s); } rpc_hdr.rpc_common.rpc_xid = htonl(xid); rpc_hdr.rpc_common.rpc_type = LIBNET_RPC_CALL; rpc_hdr.rpc_common.rpc_call.rpc_rpcvers = htonl(LIBNET_RPC_VERS); rpc_hdr.rpc_common.rpc_call.rpc_prognum = htonl(prog_num); rpc_hdr.rpc_common.rpc_call.rpc_vers = htonl(prog_vers); rpc_hdr.rpc_common.rpc_call.rpc_procedure = htonl(procedure); /* XXX Eventually should allow for opaque auth data. */ rpc_hdr.rpc_common.rpc_call.rpc_credentials.rpc_auth_flavor= htonl(cflavor); rpc_hdr.rpc_common.rpc_call.rpc_credentials.rpc_auth_length= htonl(clength); rpc_hdr.rpc_common.rpc_call.rpc_verifier.rpc_auth_flavor = htonl(vflavor); rpc_hdr.rpc_common.rpc_call.rpc_verifier.rpc_auth_length = htonl(vlength); if (rm) { n = libnet_pblock_append(l, p, (u_int8_t *)&rpc_hdr, LIBNET_RPC_CALL_TCP_H); } else { n = libnet_pblock_append(l, p, (u_int8_t *)&rpc_hdr.rpc_common, LIBNET_RPC_CALL_H); } if (n == -1) { goto bad; } /* boilerplate payload sanity check / append macro */ LIBNET_DO_PAYLOAD(l, p); return (ptag ? ptag : libnet_pblock_update(l, p, h, LIBNET_PBLOCK_RPC_CALL_H)); bad: libnet_pblock_delete(l, p); return (-1); }
libnet_ptag_t libnet_build_dnsv4(uint16_t h_len, uint16_t id, uint16_t flags, uint16_t num_q, uint16_t num_anws_rr, uint16_t num_auth_rr, uint16_t num_addi_rr, const uint8_t *payload, uint32_t payload_s, libnet_t *l, libnet_ptag_t ptag) { uint32_t n, h; uint offset; libnet_pblock_t *p; struct libnet_dnsv4_hdr dns_hdr; if (l == NULL) { return (-1); } if (h_len != LIBNET_UDP_DNSV4_H && h_len != LIBNET_TCP_DNSV4_H) { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): invalid header length: %d", __func__, h_len); return (-1); } offset = (h_len == LIBNET_UDP_DNSV4_H ? sizeof(dns_hdr.h_len) : 0); n = h_len + payload_s; h = 0; /* no checksum */ /* * Find the existing protocol block if a ptag is specified, or create * a new one. */ p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_DNSV4_H); if (p == NULL) { return (-1); } /* * The sizeof(dns_hdr.h_len) is not counted is the packet size * for TCP packet. * And since this will be ignored for udp packets, let's compute it * anyway. */ memset(&dns_hdr, 0, sizeof(dns_hdr)); dns_hdr.h_len = htons(n - sizeof (dns_hdr.h_len)); dns_hdr.id = htons(id); dns_hdr.flags = htons(flags); dns_hdr.num_q = htons(num_q); dns_hdr.num_answ_rr = htons(num_anws_rr); dns_hdr.num_auth_rr = htons(num_auth_rr); dns_hdr.num_addi_rr = htons(num_addi_rr); /* * A dirty trick: DNS can be either TCP or UDP based, and depending on * that, the header changes. A 'length' field is present in TCP packets, * but not in UDP packets. As they are the first 2 bytes of the header, * they are skipped if the packet is UDP... */ n = libnet_pblock_append(l, p, ((uint8_t *)&dns_hdr) + offset, h_len); if (n == -1) { goto bad; } /* boilerplate payload sanity check / append macro */ LIBNET_DO_PAYLOAD(l, p); return (ptag ? ptag : libnet_pblock_update(l, p, h, LIBNET_PBLOCK_DNSV4_H)); bad: libnet_pblock_delete(l, p); return (-1); }
libnet_ptag_t libnet_build_vrrp(uint8_t version, uint8_t type, uint8_t vrouter_id, uint8_t priority, uint8_t ip_count, uint8_t auth_type, uint8_t advert_int, uint16_t sum, const uint8_t *payload, uint32_t payload_s, libnet_t *l, libnet_ptag_t ptag) { uint32_t n, h; libnet_pblock_t *p; struct libnet_vrrp_hdr vrrp_hdr; if (l == NULL) { return (-1); } n = LIBNET_VRRP_H + payload_s; h = LIBNET_VRRP_H + payload_s; /* * Find the existing protocol block if a ptag is specified, or create * a new one. */ p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_VRRP_H); if (p == NULL) { return (-1); } memset(&vrrp_hdr, 0, sizeof(vrrp_hdr)); vrrp_hdr.vrrp_v = version; vrrp_hdr.vrrp_t = type; vrrp_hdr.vrrp_vrouter_id = vrouter_id; vrrp_hdr.vrrp_priority = priority; vrrp_hdr.vrrp_ip_count = ip_count; vrrp_hdr.vrrp_auth_type = auth_type; vrrp_hdr.vrrp_advert_int = advert_int; vrrp_hdr.vrrp_sum = (sum ? htons(sum) : 0); n = libnet_pblock_append(l, p, (uint8_t *)&vrrp_hdr, LIBNET_VRRP_H); if (n == -1) { goto bad; } /* boilerplate payload sanity check / append macro */ LIBNET_DO_PAYLOAD(l, p); if (sum == 0) { /* * If checksum is zero, by default libnet will compute a checksum * for the user. The programmer can override this by calling * libnet_toggle_checksum(l, ptag, 1); */ libnet_pblock_setflags(p, LIBNET_PBLOCK_DO_CHECKSUM); } return (ptag ? ptag : libnet_pblock_update(l, p, h, LIBNET_PBLOCK_VRRP_H)); bad: libnet_pblock_delete(l, p); return (-1); }
libnet_ptag_t libnet_build_ospfv2_lsa(uint16_t age, uint8_t opts, uint8_t type, uint32_t lsid, uint32_t advrtr, uint32_t seqnum, uint16_t sum, uint16_t len, const uint8_t *payload, uint32_t payload_s, libnet_t *l, libnet_ptag_t ptag) { uint32_t n, h; libnet_pblock_t *p; struct libnet_lsa_hdr lsa_hdr; if (l == NULL) { return (-1); } n = LIBNET_OSPF_LSA_H + payload_s; h = len + payload_s; /* * Find the existing protocol block if a ptag is specified, or create * a new one. */ p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_OSPF_LSA_H); if (p == NULL) { return (-1); } memset(&lsa_hdr, 0, sizeof(lsa_hdr)); lsa_hdr.lsa_age = htons(age); lsa_hdr.lsa_opts = opts; lsa_hdr.lsa_type = type; lsa_hdr.lsa_id = htonl(lsid); lsa_hdr.lsa_adv.s_addr = htonl(advrtr); lsa_hdr.lsa_seq = htonl(seqnum); lsa_hdr.lsa_sum = sum; lsa_hdr.lsa_len = htons(h); n = libnet_pblock_append(l, p, (uint8_t *)&lsa_hdr, LIBNET_OSPF_LSA_H); if (n == -1) { goto bad; } /* boilerplate payload sanity check / append macro */ LIBNET_DO_PAYLOAD(l, p); if (sum == 0) { /* * If checksum is zero, by default libnet will compute a checksum * for the user. The programmer can override this by calling * libnet_toggle_checksum(l, ptag, 1); */ libnet_pblock_setflags(p, LIBNET_PBLOCK_DO_CHECKSUM); } return (ptag ? ptag : libnet_pblock_update(l, p, h, LIBNET_PBLOCK_OSPF_LSA_H)); bad: libnet_pblock_delete(l, p); return (-1); }