diff options
Diffstat (limited to 'isisd/isis_bpf.c')
-rw-r--r-- | isisd/isis_bpf.c | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/isisd/isis_bpf.c b/isisd/isis_bpf.c index 0493c125b..872bc5bc7 100644 --- a/isisd/isis_bpf.c +++ b/isisd/isis_bpf.c @@ -216,7 +216,8 @@ end: int isis_recv_pdu_bcast(struct isis_circuit *circuit, u_char *ssnpa) { - int bytesread = 0, bytestoread, offset, one = 1; + int bytesread = 0, bytestoread, offset, one = 1, err = ISIS_OK; + u_char *buff_ptr; struct bpf_hdr *bpf_hdr; assert(circuit->fd > 0); @@ -230,25 +231,33 @@ int isis_recv_pdu_bcast(struct isis_circuit *circuit, u_char *ssnpa) } if (bytesread < 0) { zlog_warn("isis_recv_pdu_bcast(): read() failed: %s", - safe_strerror(errno)); + safe_strerror(errno)); return ISIS_WARNING; } if (bytesread == 0) return ISIS_WARNING; - bpf_hdr = (struct bpf_hdr *)readbuff; + buff_ptr = readbuff; + while (buff_ptr < readbuff + bytesread) { + bpf_hdr = (struct bpf_hdr *) buff_ptr; + assert(bpf_hdr->bh_caplen == bpf_hdr->bh_datalen); + offset = bpf_hdr->bh_hdrlen + LLC_LEN + ETHER_HDR_LEN; - assert(bpf_hdr->bh_caplen == bpf_hdr->bh_datalen); + /* then we lose the BPF, LLC and ethernet headers */ + stream_write(circuit->rcv_stream, buff_ptr + offset, + bpf_hdr->bh_caplen - LLC_LEN - ETHER_HDR_LEN); + stream_set_getp(circuit->rcv_stream, 0); - offset = bpf_hdr->bh_hdrlen + LLC_LEN + ETHER_HDR_LEN; + memcpy(ssnpa, buff_ptr + bpf_hdr->bh_hdrlen + ETHER_ADDR_LEN, + ETHER_ADDR_LEN); - /* then we lose the BPF, LLC and ethernet headers */ - stream_write(circuit->rcv_stream, readbuff + offset, - bpf_hdr->bh_caplen - LLC_LEN - ETHER_HDR_LEN); - stream_set_getp(circuit->rcv_stream, 0); + err = isis_handle_pdu(circuit, ssnpa); + stream_reset(circuit->rcv_stream); + buff_ptr += BPF_WORDALIGN(bpf_hdr->bh_hdrlen + + bpf_hdr->bh_datalen); + } - memcpy(ssnpa, readbuff + bpf_hdr->bh_hdrlen + ETH_ALEN, ETH_ALEN); if (ioctl(circuit->fd, BIOCFLUSH, &one) < 0) zlog_warn("Flushing failed: %s", safe_strerror(errno)); |