* return a pointer to a contiguous piece of data from the given mbuf chain * starting at 'off' for 'len' bytes. If the desired piece spans more than * one mbuf, a copy is made at 'ptr'. caller must ensure that the buffer size * is >= 'len' returns NULL if there there isn't 'len' bytes in the chain. */
| 3045 | * is >= 'len' returns NULL if there there isn't 'len' bytes in the chain. |
| 3046 | */ |
| 3047 | caddr_t |
| 3048 | sctp_m_getptr(struct mbuf *m, int off, int len, uint8_t *in_ptr) |
| 3049 | { |
| 3050 | uint32_t count; |
| 3051 | uint8_t *ptr; |
| 3052 | |
| 3053 | ptr = in_ptr; |
| 3054 | if ((off < 0) || (len <= 0)) |
| 3055 | return (NULL); |
| 3056 | |
| 3057 | /* find the desired start location */ |
| 3058 | while ((m != NULL) && (off > 0)) { |
| 3059 | if (off < SCTP_BUF_LEN(m)) |
| 3060 | break; |
| 3061 | off -= SCTP_BUF_LEN(m); |
| 3062 | m = SCTP_BUF_NEXT(m); |
| 3063 | } |
| 3064 | if (m == NULL) |
| 3065 | return (NULL); |
| 3066 | |
| 3067 | /* is the current mbuf large enough (eg. contiguous)? */ |
| 3068 | if ((SCTP_BUF_LEN(m) - off) >= len) { |
| 3069 | return (mtod(m, caddr_t)+off); |
| 3070 | } else { |
| 3071 | /* else, it spans more than one mbuf, so save a temp copy... */ |
| 3072 | while ((m != NULL) && (len > 0)) { |
| 3073 | count = min(SCTP_BUF_LEN(m) - off, len); |
| 3074 | memcpy(ptr, mtod(m, caddr_t)+off, count); |
| 3075 | len -= count; |
| 3076 | ptr += count; |
| 3077 | off = 0; |
| 3078 | m = SCTP_BUF_NEXT(m); |
| 3079 | } |
| 3080 | if ((m == NULL) && (len > 0)) |
| 3081 | return (NULL); |
| 3082 | else |
| 3083 | return ((caddr_t)in_ptr); |
| 3084 | } |
| 3085 | } |
| 3086 | |
| 3087 | struct sctp_paramhdr * |
| 3088 | sctp_get_next_param(struct mbuf *m, |
no test coverage detected