libnet_ptag_t libnet_build_ospfv2_lsa_sum(u_int32_t nmask, u_int32_t metric, u_int tos, 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_sum_lsa_hdr sum_lsa_hdr; if (l == NULL) { return (-1); } n = LIBNET_OSPF_LS_SUM_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_SUM_H); if (p == NULL) { return (-1); } memset(&sum_lsa_hdr, 0, sizeof(sum_lsa_hdr)); sum_lsa_hdr.sum_nmask.s_addr = htonl(nmask); sum_lsa_hdr.sum_metric = htonl(metric); sum_lsa_hdr.sum_tos_metric = htonl(tos); n = libnet_pblock_append(l, p, (u_int8_t *)&sum_lsa_hdr, LIBNET_OSPF_LS_SUM_H); if (n == -1) { goto bad; } if ((payload && !payload_s) || (!payload && payload_s)) { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): payload inconsistency\n", __func__); goto bad; } if (payload && payload_s) { n = libnet_pblock_append(l, p, payload, payload_s); if (n == -1) { goto bad; } } return (ptag ? ptag : libnet_pblock_update(l, p, h, LIBNET_PBLOCK_LS_SUM_H)); bad: libnet_pblock_delete(l, p); return (-1); }
libnet_ptag_t libnet_build_ospfv2_lsr(u_int32_t type, u_int lsid, u_int32_t advrtr, 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_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, (u_int8_t *)&lsr_hdr, LIBNET_OSPF_LSR_H); if (n == -1) { goto bad; } if ((payload && !payload_s) || (!payload && payload_s)) { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): payload inconsistency\n", __func__); goto bad; } if (payload && payload_s) { n = libnet_pblock_append(l, p, payload, payload_s); if (n == -1) { goto bad; } } 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_802_1x(u_int8_t eap_ver, u_int8_t eap_type, u_int16_t length, 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_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, (u_int8_t *)&dot1x_hdr, LIBNET_802_1X_H); if (n == -1) { goto bad; } if ((payload && !payload_s) || (!payload && payload_s)) { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): payload inconsistency\n", __func__); goto bad; } if (payload && payload_s) { n = libnet_pblock_append(l, p, payload, payload_s); if (n == -1) { goto bad; } } 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_802_3(u_int8_t *dst, u_int8_t *src, u_int16_t len, 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_802_3_hdr _802_3_hdr; if (l == NULL) { return (-1); } n = LIBNET_802_3_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_3_H); if (p == NULL) { return (-1); } memset(&_802_3_hdr, 0, sizeof(_802_3_hdr)); memcpy(_802_3_hdr._802_3_dhost, dst, ETHER_ADDR_LEN); /* dest address */ memcpy(_802_3_hdr._802_3_shost, src, ETHER_ADDR_LEN); /* src address */ _802_3_hdr._802_3_len = htons(len); /* packet length */ n = libnet_pblock_append(l, p, (u_int8_t *)&_802_3_hdr, LIBNET_802_3_H); if (n == -1) { goto bad; } if ((payload && !payload_s) || (!payload && payload_s)) { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): payload inconsistency\n", __func__); goto bad; } if (payload && payload_s) { n = libnet_pblock_append(l, p, payload, payload_s); if (n == -1) { goto bad; } } return (ptag ? ptag : libnet_pblock_update(l, p, h, LIBNET_PBLOCK_802_3_H)); bad: libnet_pblock_delete(l, p); return (-1); }
libnet_ptag_t libnet_build_ospfv2_lsu(u_int32_t num, 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_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, (u_int8_t *)&lh_hdr, LIBNET_OSPF_LSU_H); if (n == -1) { goto bad; } if ((payload && !payload_s) || (!payload && payload_s)) { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): payload inconsistency\n", __func__); goto bad; } if (payload && payload_s) { n = libnet_pblock_append(l, p, payload, payload_s); if (n == -1) { goto bad; } } 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_stp_tcn(u_short id, u_char version, u_char bpdu_type, u_char *payload, u_long payload_s, libnet_t *l, libnet_ptag_t ptag) { u_long n; u_short h; libnet_pblock_t *p; struct libnet_stp_tcn_hdr stp_hdr; if (l == NULL) { return (-1); } n = LIBNET_STP_TCN_H + payload_s; /* size of memory block */ 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_STP_TCN_H); if (p == NULL) { return (-1); } stp_hdr.stp_id = htons(id); stp_hdr.stp_version = version; stp_hdr.stp_bpdu_type = bpdu_type; n = libnet_pblock_append(l, p, (u_char *)&stp_hdr, LIBNET_STP_TCN_H); if (n == -1) { goto bad; } if (payload && payload_s) { n = libnet_pblock_append(l, p, payload, payload_s); if (n == -1) { goto bad; } } return (ptag ? ptag : libnet_pblock_update(l, p, h, LIBNET_PBLOCK_STP_TCN_H)); bad: libnet_pblock_free(p); return (-1); }
libnet_ptag_t libnet_autobuild_ethernet(const uint8_t *dst, uint16_t type, libnet_t *l) { uint32_t n, h; struct libnet_ether_addr *src; libnet_pblock_t *p; libnet_ptag_t ptag; 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, "libnet_autobuild_ethernet() called with non-link layer wire" " injection primitive"); p = NULL; goto bad; } n = LIBNET_ETH_H; h = 0; ptag = LIBNET_PTAG_INITIALIZER; src = libnet_get_hwaddr(l); if (src == NULL) { /* err msg set in libnet_get_hwaddr() */ return (-1); } /* * Create a new pblock. */ 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; } return (libnet_pblock_update(l, p, h, LIBNET_PBLOCK_ETH_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_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_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_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_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_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_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_data(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; 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); } if ((payload && !payload_s) || (!payload && payload_s)) { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): payload inconsistency\n", __func__); goto bad; } if (payload && payload_s) { n = libnet_pblock_append(l, p, payload, payload_s); if (n == -1) { goto bad; } } 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_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_gre_last_sre(libnet_t *l, libnet_ptag_t ptag) { uint32_t n, zero = 0; libnet_pblock_t *p; if (l == NULL) { return (-1); } n = LIBNET_GRE_SRE_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_GRE_H); if (p == NULL) { return (-1); } n = libnet_pblock_append(l, p, (uint8_t *)&zero, LIBNET_GRE_SRE_H); if (n == -1) { /* err msg set in libnet_pblock_append() */ goto bad; } 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_tcp(u_int16_t sp, u_int16_t dp, u_int32_t seq, u_int32_t ack, u_int8_t control, u_int16_t win, u_int16_t sum, u_int16_t urg, u_int16_t len, u_int8_t *payload, u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag) { int n, offset; u_int32_t i, j; libnet_pblock_t *p, *p_data, *p_temp; libnet_ptag_t ptag_hold, ptag_data; struct libnet_tcp_hdr tcp_hdr; struct libnet_ipv4_hdr *ip_hdr; if (l == NULL) { return (-1); } ptag_data = 0; /* for possible options */ /* * Find the existing protocol block if a ptag is specified, or create * a new one. */ p = libnet_pblock_probe(l, ptag, LIBNET_TCP_H, LIBNET_PBLOCK_TCP_H); if (p == NULL) { return (-1); } memset(&tcp_hdr, 0, sizeof(tcp_hdr)); tcp_hdr.th_sport = htons(sp); /* source port */ tcp_hdr.th_dport = htons(dp); /* destination port */ tcp_hdr.th_seq = htonl(seq); /* sequence number */ tcp_hdr.th_ack = htonl(ack); /* acknowledgement number */ tcp_hdr.th_flags = control; /* control flags */ tcp_hdr.th_x2 = 0; /* UNUSED */ tcp_hdr.th_off = 5; /* 20 byte header */ /* check to see if there are TCP options to include */ if (p->prev) { p_temp = p->prev; while ((p_temp->prev) && (p_temp->type != LIBNET_PBLOCK_TCPO_H)) { p_temp = p_temp->prev; } if (p_temp->type == LIBNET_PBLOCK_TCPO_H) { /* * Count up number of 32-bit words in options list, padding if * neccessary. */ for (i = 0, j = 0; i < p_temp->b_len; i++) { (i % 4) ? j : j++; } tcp_hdr.th_off += j; } } tcp_hdr.th_win = htons(win); /* window size */ tcp_hdr.th_sum = (sum ? htons(sum) : 0); /* checksum */ tcp_hdr.th_urp = htons(urg); /* urgent pointer */ n = libnet_pblock_append(l, p, (u_int8_t *)&tcp_hdr, LIBNET_TCP_H); if (n == -1) { goto bad; } ptag_hold = ptag; if (ptag == LIBNET_PTAG_INITIALIZER) { ptag = libnet_pblock_update(l, p, len, LIBNET_PBLOCK_TCP_H); } /* find and set the appropriate ptag, or else use the default of 0 */ offset = payload_s; if (ptag_hold && p->prev) { p_temp = p->prev; while (p_temp->prev && (p_temp->type != LIBNET_PBLOCK_TCPDATA) && (p_temp->type != LIBNET_PBLOCK_TCP_H)) { p_temp = p_temp->prev; } if (p_temp->type == LIBNET_PBLOCK_TCPDATA) { ptag_data = p_temp->ptag; offset -= p_temp->b_len; p->h_len += offset; } else { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): TCP data pblock not found\n", __func__); } } /* update ip_len if present */ if (ptag_hold && p->next) { p_temp = p->next; while (p_temp->next && (p_temp->type != LIBNET_PBLOCK_IPV4_H)) { p_temp = p_temp->next; } if (p_temp->type == LIBNET_PBLOCK_IPV4_H) { ip_hdr = (struct libnet_ipv4_hdr *)p_temp->buf; n = ntohs(ip_hdr->ip_len) + offset; ip_hdr->ip_len = htons(n); } } if ((payload && !payload_s) || (!payload && payload_s)) { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): payload inconsistency\n", __func__); goto bad; } /* if there is a payload, add it in the context */ if (payload && payload_s) { /* update ptag_data with the new payload */ p_data = libnet_pblock_probe(l, ptag_data, payload_s, LIBNET_PBLOCK_TCPDATA); if (p_data == NULL) { return (-1); } if (libnet_pblock_append(l, p_data, payload, payload_s) == -1) { goto bad; } if (ptag_data == LIBNET_PTAG_INITIALIZER) { if (p_data->prev->type == LIBNET_PBLOCK_TCP_H) { libnet_pblock_update(l, p_data, payload_s, LIBNET_PBLOCK_TCPDATA); /* swap pblocks to correct the protocol order */ libnet_pblock_swap(l, p->ptag, p_data->ptag); } else { /* update without setting this as the final pblock */ p_data->type = LIBNET_PBLOCK_TCPDATA; p_data->ptag = ++(l->ptag_state); p_data->h_len = payload_s; /* Adjust h_len for checksum. */ p->h_len += payload_s; /* data was added after the initial construction */ for (p_temp = l->protocol_blocks; p_temp->type == LIBNET_PBLOCK_TCP_H || p_temp->type == LIBNET_PBLOCK_TCPO_H; p_temp = p_temp->next) { libnet_pblock_insert_before(l, p_temp->ptag, p_data->ptag); break; } /* The end block needs to have its next pointer cleared. */ l->pblock_end->next = NULL; } if (p_data->prev && p_data->prev->type == LIBNET_PBLOCK_TCPO_H) { libnet_pblock_swap(l, p_data->prev->ptag, p_data->ptag); } } } else { p_data = libnet_pblock_find(l, ptag_data); if (p_data) { libnet_pblock_delete(l, p_data); } } 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); bad: libnet_pblock_delete(l, p); return (-1); }
libnet_ptag_t libnet_build_tcp_options(u_int8_t *options, u_int32_t options_s, libnet_t *l, libnet_ptag_t ptag) { int offset, underflow; u_int32_t i, j, n, adj_size; libnet_pblock_t *p, *p_temp; struct libnet_ipv4_hdr *ip_hdr; struct libnet_tcp_hdr *tcp_hdr; if (l == NULL) { return (-1); } underflow = 0; offset = 0; /* check options list size */ if (options_s > LIBNET_MAXOPTION_SIZE) { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): options list is too large %d\n", __func__, options_s); return (-1); } adj_size = options_s; if (adj_size % 4) { /* size of memory block with padding */ adj_size += 4 - (options_s % 4); } /* if this pblock already exists, determine if there is a size diff */ if (ptag) { p_temp = libnet_pblock_find(l, ptag); if (p_temp) { if (adj_size >= p_temp->b_len) { offset = adj_size - p_temp->b_len; } else { offset = p_temp->b_len - adj_size; underflow = 1; } } } /* * Find the existing protocol block if a ptag is specified, or create * a new one. */ p = libnet_pblock_probe(l, ptag, adj_size, LIBNET_PBLOCK_TCPO_H); if (p == NULL) { return (-1); } n = libnet_pblock_append(l, p, options, adj_size); if (n == -1) { goto bad; } if (ptag && p->next) { p_temp = p->next; while ((p_temp->next) && (p_temp->type != LIBNET_PBLOCK_TCP_H)) { p_temp = p_temp->next; } if (p_temp->type == LIBNET_PBLOCK_TCP_H) { /* * Count up number of 32-bit words in options list, padding if * neccessary. */ for (i = 0, j = 0; i < p->b_len; i++) { (i % 4) ? j : j++; } tcp_hdr = (struct libnet_tcp_hdr *)p_temp->buf; tcp_hdr->th_off = j + 5; if (!underflow) { p_temp->h_len += offset; } else { p_temp->h_len -= offset; } } while ((p_temp->next) && (p_temp->type != LIBNET_PBLOCK_IPV4_H)) { p_temp = p_temp->next; } if (p_temp->type == LIBNET_PBLOCK_IPV4_H) { ip_hdr = (struct libnet_ipv4_hdr *)p_temp->buf; if (!underflow) { ip_hdr->ip_len += htons(offset); } else { ip_hdr->ip_len -= htons(offset); } } } return (ptag ? ptag : libnet_pblock_update(l, p, adj_size, LIBNET_PBLOCK_TCPO_H)); bad: libnet_pblock_delete(l, p); return (-1); }
libnet_ptag_t libnet_build_tcp( uint16_t sp, uint16_t dp, uint32_t seq, uint32_t ack, uint8_t control, uint16_t win, uint16_t sum, uint16_t urg, uint16_t h_len, const uint8_t *payload, uint32_t payload_s, libnet_t *l, libnet_ptag_t ptag) { int n, offset; libnet_pblock_t *p = NULL; libnet_ptag_t ptag_data = 0; struct libnet_tcp_hdr tcp_hdr; if (l == NULL) return -1; if (payload_s && !payload) { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): payload inconsistency", __func__); return -1; } p = libnet_pblock_probe(l, ptag, LIBNET_TCP_H, LIBNET_PBLOCK_TCP_H); if (p == NULL) return -1; memset(&tcp_hdr, 0, sizeof(tcp_hdr)); tcp_hdr.th_sport = htons(sp); /* source port */ tcp_hdr.th_dport = htons(dp); /* destination port */ tcp_hdr.th_seq = htonl(seq); /* sequence number */ tcp_hdr.th_ack = htonl(ack); /* acknowledgement number */ tcp_hdr.th_flags = control; /* control flags */ tcp_hdr.th_x2 = 0; /* UNUSED */ tcp_hdr.th_off = 5; /* 20 byte header */ /* check to see if there are TCP options to include */ if (p->prev && p->prev->type == LIBNET_PBLOCK_TCPO_H) { /* Note that the tcp options pblock is already padded */ tcp_hdr.th_off += (p->prev->b_len/4); } tcp_hdr.th_win = htons(win); /* window size */ tcp_hdr.th_sum = (sum ? htons(sum) : 0); /* checksum */ tcp_hdr.th_urp = htons(urg); /* urgent pointer */ n = libnet_pblock_append(l, p, (uint8_t *)&tcp_hdr, LIBNET_TCP_H); if (n == -1) { goto bad; } if (ptag == LIBNET_PTAG_INITIALIZER) { libnet_pblock_update(l, p, h_len, LIBNET_PBLOCK_TCP_H); } offset = payload_s; /* If we are going to modify a TCP data block, find it, and figure out the * "offset", the possibly negative amount by which we are increasing the ip * data length. */ if (ptag) { libnet_pblock_t* datablock = p->prev; if (datablock && datablock->type == LIBNET_PBLOCK_TCPO_H) datablock = datablock->prev; if (datablock && datablock->type == LIBNET_PBLOCK_TCPDATA) { ptag_data = datablock->ptag; offset -= datablock->b_len; } p->h_len += offset; } /* If we are modifying a TCP block, we should look forward and apply the offset * to our IPv4 header, if we have one. */ if (p->next) { libnet_pblock_t* ipblock = p->next; if(ipblock->type == LIBNET_PBLOCK_IPO_H) ipblock = ipblock->next; if(ipblock && ipblock->type == LIBNET_PBLOCK_IPV4_H) { struct libnet_ipv4_hdr * ip_hdr = (struct libnet_ipv4_hdr *)ipblock->buf; int ip_len = ntohs(ip_hdr->ip_len) + offset; ip_hdr->ip_len = htons(ip_len); } } /* if there is a payload, add it in the context */ if (payload_s) { /* update ptag_data with the new payload */ libnet_pblock_t* p_data = libnet_pblock_probe(l, ptag_data, payload_s, LIBNET_PBLOCK_TCPDATA); if (!p_data) { goto bad; } n = libnet_pblock_append(l, p_data, payload, payload_s); if (n == -1) { goto bad; } if (ptag_data == LIBNET_PTAG_INITIALIZER) { int insertbefore = p->ptag; /* Then we created it, and we need to shuffle it back until it's before * the tcp header and options. */ libnet_pblock_update(l, p_data, payload_s, LIBNET_PBLOCK_TCPDATA); if(p->prev && p->prev->type == LIBNET_PBLOCK_TCPO_H) insertbefore = p->prev->ptag; libnet_pblock_insert_before(l, insertbefore, p_data->ptag); } } else { libnet_pblock_t* p_data = libnet_pblock_find(l, ptag_data); libnet_pblock_delete(l, p_data); } 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 (p->ptag); 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); }
int /* Not Yet Implemented */ libnet_build_cdp_value(uint16_t type, uint16_t len, uint8_t *value, libnet_t *l, libnet_ptag_t ptag) { uint32_t n; libnet_pblock_t *p; struct libnet_cdp_value_hdr cdp_value_hdr; if (l == NULL) { return (-1); } /* * Find the existing protocol block. */ p = libnet_pblock_find(l, ptag); if (p == NULL) { /* err msg set in libnet_pblock_find */ return (-1); } if (p->type != LIBNET_PBLOCK_CDP_H) { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "libnet_build_cdp_value: ptag references different type than expected"); return (-1); } memset(&cdp_value_hdr, 0, sizeof(cdp_value_hdr)); cdp_value_hdr.cdp_type = htons(type); cdp_value_hdr.cdp_len = htons(len + LIBNET_CDP_VALUE_H); /* 4 bytes for len and type */ switch (type) { case LIBNET_CDP_DEVID: break; case LIBNET_CDP_ADDRESS: break; case LIBNET_CDP_PORTID: break; case LIBNET_CDP_CAPABIL: break; case LIBNET_CDP_VERSION: break; case LIBNET_CDP_PLATFORM: break; case LIBNET_CDP_IPPREFIX: break; default: break; } n = libnet_pblock_append(l, p, (uint8_t *)&cdp_value_hdr, LIBNET_CDP_VALUE_H); if (n == -1) { return (-1); } n = libnet_pblock_append(l, p, value, len); if (n == -1) { /* err msg set in libnet_pblock_append() */ return (-1); } return (1); }