Closed marcin-de closed 2 years ago
Hi @marcin-de, interesting, there should be four bytes available for ppp (IPCP header is two bytes), could you debug the code as below? let me know what you find. Thanks.
Set breakpoint here in _nx_icmpv4_process_echo_request(), then watch packet_ptr->nx_packet_prepend_ptr and packet_ptr->nx_packet_data_start, check if the value of (packet_ptr->nx_packet_prepend_ptr - packet_ptr->nx_packet_data_start) is 24,
Set breakpoint here in nx_ip_packet_send() to check the logic of adding IP header (20 bytes), watch the same variables and check if the value of (packet_ptr->nx_packet_prepend_ptr - packet_ptr->nx_packet_data_start) is 4,
After adding IP header and before adding IPCP header, no data need to be added into packet, set breakpoint here to check if the value (packet_ptr->nx_packet_prepend_ptr - packet_ptr->nx_packet_data_start) is changed.
Hello, @bo-ms
Regarding above checks:
Hi @marcin-de Before IP header, there should be five bytes: three bytes (0x7e, 0xff, 0x03) for HDLC, and two bytes for (0x00, 0x21) for IPCP protocol, then move one byte to keep four bytes alignment before calling IP receive, could you set breakpoint to check it and share your data between data_start pointer and prepend_ptr pointer? Thanks.
Hi @bo-ms,
In my case, things look like this:
So there are only three bytes before IP header. Why? This brings us to another "issue" with PPP stack: if during PPP connection setup remote peer requests LCP option 0x08 (Address-and-Control-Field-Compression), local stack accepts it - but later, when remote peer sends IPCP/IP packets with "compressed" fields (i.e. 0xFF and 0x03 bytes are not present), local stack still assumes that these bytes are present(!) and tries to remove them (it is done here ). This, of course, leads to "misalignment" in payload of IPCP packets and consequently to inability to set up PPP session. This was my first problem with PPP stack - and I solved it by replacing above code with this:
`
if ((packet_head_ptr -> nx_packet_prepend_ptr[0] == 0x7e) &&
(packet_head_ptr -> nx_packet_prepend_ptr[1] == 0xff) &&
(packet_head_ptr -> nx_packet_prepend_ptr[2] == 0x03)
) { // ** Full HDLC header present - remove
packet_head_ptr -> nx_packet_prepend_ptr += 3;
packet_head_ptr -> nx_packet_length -= 3;
} else { // ** header not present (IPCP with compression?) - remove only start flag
packet_head_ptr -> nx_packet_prepend_ptr += 1;
packet_head_ptr -> nx_packet_length -= 1;
}
` This brought PPP stack to work - it can negotiate the connection, gets IP address and IP stack is able to use the connection (UDP communication works OK). However, it seems that there are other places in PPP stack where assumption is made that received PPP frame always begins with 0x7E 0xFF 0x03...
Hi @marcin-de you are right, the Address and Control fields may be compressed, we will fix this issue in next release, you are able to fix it locally for testing, thanks for reporting this issue.
Hi @bo-ms Thanks for feedback. However... As I dig deeper into PPP specification, I'm getting the feeling that it is not an issue with PPP stack, but with modem itself...
Below is dump of PPP frames during establishment of connection. Lines with "<" show data from CPU to modem, lines with ">" - from modem to CPU.
<7EFF03 C021 01 2C 0008 010405DC 9D8C7E
<7EFF03 C021 01 2D 0008 010405DC 48137E
>7EFF03 C021 01 01 0018 020600000000 0304C023 050654FD4A65 0702 0802 A9067E
<7EFF03 C021 04 01 0008 0304C023 2CD47E
>7EFF03 C021 02 2D 0008 010405DC 98997E
>7EFF03 C021 01 02 0014 020600000000 05061121D847 0702 0802 111F7E
<7EFF03 C021 02 02 0014 020600000000 05061121D847 0702 0802 FA767E
<7EFF03 8021 01 2E 0016 030600000000 810600000000 830600000000 FD317E
>7E 8021 01 03 0004 032C7E
<7EFF03 8021 02 03 0004 75277E
>7E 8021 03 2E 0016 03060A0A2409 810600000000 830600000000 26007E
<7EFF03 8021 01 2F 0016 03060A0A2409 810600000000 830600000000 81FD7E
>7E 8021 02 2F 0016 03060A0A2409 810600000000 830600000000 179E7E
Third line is ConfReq from modem to stack with LCP option 0x08 present. Then stack rejects option 0x03 (auth protocol), so in line six modem resends ConfReq without rejected option and in line seven stack acknowledges rest of options (including 0x08). But, according to RFC, this means that Address and Control Field Compression may be used in direction from stack to modem, not the opposite - but instead modem starts to use compression(!?), which leads to "issues" in PPP stack. And stack itself still sends frames with full header (even if it knows that it can be omitted - but it does not matter). Furthermore, stack never requests LCP 0x08, so modem should not use the compression, in which case everything shall work as expected... Please consider if this is the case.
Quick followup. If I remove LCP option 0x08 from "known options list" here, so during parsing it falls to default and gets rejected, then modem sends IPCP/IP frames with full header and all, including ping, works as expected...
Hi @marcin-de Thanks for the update. From the spec below. This Configuration Option (ACFC) is sent to inform the peer that the implementation can receive compressed Address and Control fields. If our PPP client (CPU) did not send this option to modem, the modem should not send compressed data to PPP client (CPU). Looks the issue is in modem, not PPP stack, what do you think?
6.6. Address-and-Control-Field-Compression (ACFC)
Description
This Configuration Option provides a method to negotiate the
compression of the Data Link Layer Address and Control fields. By
default, all implementations MUST transmit frames with Address and
Control fields appropriate to the link framing.
Since these fields usually have constant values for point-to-point
links, they are easily compressed. This Configuration Option is
sent to inform the peer that the implementation can receive
compressed Address and Control fields.
If a compressed frame is received when Address-and-Control-Field-
Compression has not been negotiated, the implementation MAY
silently discard the frame.
The Address and Control fields MUST NOT be compressed when sending
any LCP packet. This rule guarantees unambiguous recognition of
LCP packets.
When the Address and Control fields are compressed, the Data Link
Layer FCS field is calculated on the compressed frame, not the
original uncompressed frame.
Yes, exactly, it looks like an issue with modem's firmware, not the PPP stack in NetX. I will report this to modem's manufacturer (Simcom), and you can close this issue.
Thanks for support!
closing, @marcin-de feel free to reopen it if you have any issue after discussion with Simcom.
If NetX uses PPP as network interface, it does not respond to ICMP Echo requests sent from network. In fact, ICMP Echo requests are received by stack and processed (in _nx_icmpv4_process_echo_request function), but when responses are passed down to PPP stack, _nx_ppp_process_deferred_ip_packet_send function ends up with error when checking for available space for IPCP header, right here:
` / Determine if there is room in the front of the packet for the PPP header. / if ((packet_ptr -> nx_packet_prepend_ptr - packet_ptr -> nx_packet_data_start) < 2) {
ifndef NX_PPP_DISABLE_INFO
endif
` It seems that higher level functions don't provide needed room for header, hence packet is dropped. Other than that, PPP interface works OK (at least with UDP traffic).