* Add the frame relay header to the packet. * For IP the header length is 4 bytes, * for all other protocols - 10 bytes (RFC 1490). */
| 281 | * for all other protocols - 10 bytes (RFC 1490). |
| 282 | */ |
| 283 | struct mbuf *sppp_fr_header (struct sppp *sp, struct mbuf *m, |
| 284 | int family) |
| 285 | { |
| 286 | STDDCL; |
| 287 | u_char *h; |
| 288 | int type, hlen; |
| 289 | |
| 290 | /* Prepend the space for Frame Relay header. */ |
| 291 | hlen = (family == AF_INET) ? 4 : 10; |
| 292 | M_PREPEND (m, hlen, M_NOWAIT); |
| 293 | if (! m) |
| 294 | return 0; |
| 295 | h = mtod (m, u_char*); |
| 296 | |
| 297 | /* Fill the header. */ |
| 298 | h[0] = sp->fr_dlci >> 2 & 0xfc; |
| 299 | h[1] = sp->fr_dlci << 4 | 1; |
| 300 | h[2] = FR_UI; |
| 301 | |
| 302 | switch (family) { |
| 303 | default: |
| 304 | if (debug) |
| 305 | printf (SPP_FMT "Cannot handle address family %d\n", |
| 306 | SPP_ARGS(ifp), family); |
| 307 | m_freem (m); |
| 308 | return 0; |
| 309 | #ifdef INET |
| 310 | case AF_INET: |
| 311 | #if 0 /* Crashes on fragmented packets */ |
| 312 | /* |
| 313 | * Set the discard eligibility bit, if: |
| 314 | * 1) no fragmentation |
| 315 | * 2) length > 400 bytes |
| 316 | * 3a) the protocol is UDP or |
| 317 | * 3b) TCP data (no control bits) |
| 318 | */ |
| 319 | { |
| 320 | struct ip *ip = (struct ip*) (h + hlen); |
| 321 | struct tcphdr *tcp = (struct tcphdr*) ((long*)ip + ip->ip_hl); |
| 322 | |
| 323 | if (! (ip->ip_off & ~IP_DF) && ip->ip_len > 400 && |
| 324 | (ip->ip_p == IPPROTO_UDP || |
| 325 | ip->ip_p == IPPROTO_TCP && ! tcp->th_flags)) |
| 326 | h[1] |= FR_DE; |
| 327 | } |
| 328 | #endif |
| 329 | h[3] = FR_IP; |
| 330 | return m; |
| 331 | #endif |
| 332 | #ifdef NS |
| 333 | case AF_NS: |
| 334 | type = 0x8137; |
| 335 | break; |
| 336 | #endif |
| 337 | } |
| 338 | h[3] = FR_PADDING; |
| 339 | h[4] = FR_SNAP; |
| 340 | h[5] = 0; |
no test coverage detected