Beispiel #1
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);
}
Beispiel #2
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_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);
}
Beispiel #4
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);
}
Beispiel #5
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);
}
Beispiel #6
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);
}
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);
}
Beispiel #11
0
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);
}
Beispiel #14
0
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);
}