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);
}
예제 #6
0
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(&eth_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 *)&eth_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); 
}
예제 #8
0
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(&eth_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 *)&eth_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);
}
예제 #11
0
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);
}
예제 #13
0
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);
}
예제 #14
0
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);
}
예제 #15
0
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);
}
예제 #16
0
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);
}
예제 #17
0
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);
}
예제 #18
0
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);
}
예제 #19
0
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);
}
예제 #21
0
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);
}
예제 #22
0
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);
}
예제 #23
0
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);
}
예제 #24
0
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);
}
예제 #25
0
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);

}
예제 #26
0
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);
}
예제 #27
0
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);
}
예제 #28
0
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);
}
예제 #29
0
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);
}
예제 #30
0
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);
}