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_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_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_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( 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); }
libnet_ptag_t libnet_build_udp(u_int16_t sp, u_int16_t dp, u_int16_t len, u_int16_t sum, 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_udp_hdr udp_hdr; if (l == NULL) { return (-1); } n = LIBNET_UDP_H + payload_s; /* size of memory block */ h = len; /* header length (for cksum) */ /* * Find the existing protocol block if a ptag is specified, or create * a new one. */ p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_UDP_H); if (p == NULL) { return (-1); } memset(&udp_hdr, 0, sizeof(udp_hdr)); udp_hdr.uh_sport = htons(sp); /* source port */ udp_hdr.uh_dport = htons(dp); /* destination port */ udp_hdr.uh_ulen = htons(h); /* total length of UDP packet*/ udp_hdr.uh_sum = (sum ? htons(sum) : 0);/* checksum */ n = libnet_pblock_append(l, p, (u_int8_t *)&udp_hdr, LIBNET_UDP_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; } } 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_UDP_H)); bad: libnet_pblock_delete(l, p); return (-1); }
libnet_ptag_t libnet_build_ospfv2(u_int16_t len, u_int8_t type, u_int32_t rtr_id, u_int32_t area_id, u_int16_t sum, u_int16_t autype, 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_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 = htonl(rtr_id); /* Router ID */ ospf_hdr.ospf_area_id.s_addr = htonl(area_id); /* Area ID */ ospf_hdr.ospf_sum = (sum ? htons(sum) : 0); ospf_hdr.ospf_auth_type = htons(autype); /* Type of auth */ n = libnet_pblock_append(l, p, (u_int8_t *)&ospf_hdr, LIBNET_OSPF_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; } } 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_ospfv2_lsa(u_int16_t age, u_int8_t opts, u_int8_t type, u_int lsid, u_int32_t advrtr, u_int32_t seqnum, u_int16_t sum, 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_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 ? htons(sum) : 0); lsa_hdr.lsa_len = htons(h); n = libnet_pblock_append(l, p, (u_int8_t *)&lsa_hdr, LIBNET_OSPF_LSA_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; } } 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); }
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_isl(u_char *dhost, u_char type, u_char user, u_char *shost, u_short len, u_char *snap, u_short vid, u_short index, u_short reserved, 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_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); } 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(index); isl_hdr.isl_reserved= htons(reserved); n = libnet_pblock_append(l, p, (u_char *)&isl_hdr, LIBNET_ISL_H); if (n == -1) { goto bad; } if (payload && payload_s) { n = libnet_pblock_append(l, p, payload, payload_s); if (n == -1) { goto bad; } } /* 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_free(p); return (-1); }
libnet_ptag_t libnet_build_igmp(u_int8_t type, u_int8_t code, u_int16_t sum, u_int32_t ip, 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_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, (u_int8_t *)&igmp_hdr, LIBNET_IGMP_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; } } 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_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); }