| 161 | static void sppp_fr_signal (struct sppp *sp, unsigned char *h, int len); |
| 162 | |
| 163 | void sppp_fr_input (struct sppp *sp, struct mbuf *m) |
| 164 | { |
| 165 | STDDCL; |
| 166 | u_char *h = mtod (m, u_char*); |
| 167 | int isr = -1; |
| 168 | int dlci, hlen, proto; |
| 169 | |
| 170 | /* Get the DLCI number. */ |
| 171 | if (m->m_pkthdr.len < 10) { |
| 172 | bad: m_freem (m); |
| 173 | return; |
| 174 | } |
| 175 | dlci = (h[0] << 2 & 0x3f0) | (h[1] >> 4 & 0x0f); |
| 176 | |
| 177 | /* Process signaling packets. */ |
| 178 | if (dlci == 0) { |
| 179 | sppp_fr_signal (sp, h, m->m_pkthdr.len); |
| 180 | m_freem (m); |
| 181 | return; |
| 182 | } |
| 183 | |
| 184 | if (dlci != sp->fr_dlci) { |
| 185 | if (debug) |
| 186 | printf (SPP_FMT "Received packet from invalid DLCI %d\n", |
| 187 | SPP_ARGS(ifp), dlci); |
| 188 | goto bad; |
| 189 | } |
| 190 | |
| 191 | /* Process the packet. */ |
| 192 | if (ntohs (*(short*) (h+2)) == ETHERTYPE_IP) { |
| 193 | /* Prehistoric IP framing? */ |
| 194 | h[2] = FR_UI; |
| 195 | h[3] = FR_IP; |
| 196 | } |
| 197 | if (h[2] != FR_UI) { |
| 198 | if (debug) |
| 199 | printf (SPP_FMT "Invalid frame relay header flag 0x%02x\n", |
| 200 | SPP_ARGS(ifp), h[2]); |
| 201 | goto bad; |
| 202 | } |
| 203 | switch (h[3]) { |
| 204 | default: |
| 205 | if (debug) |
| 206 | printf (SPP_FMT "Unsupported NLPID 0x%02x\n", |
| 207 | SPP_ARGS(ifp), h[3]); |
| 208 | goto bad; |
| 209 | |
| 210 | case FR_PADDING: |
| 211 | if (h[4] != FR_SNAP) { |
| 212 | if (debug) |
| 213 | printf (SPP_FMT "Bad NLPID 0x%02x\n", |
| 214 | SPP_ARGS(ifp), h[4]); |
| 215 | goto bad; |
| 216 | } |
| 217 | if (h[5] || h[6] || h[7]) { |
| 218 | if (debug) |
| 219 | printf (SPP_FMT "Bad OID 0x%02x-0x%02x-0x%02x\n", |
| 220 | SPP_ARGS(ifp), |
no test coverage detected