-// process Multilink PPP packet received
-void processmpin(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l)
-{
- bundleidt b = session[s].bundle;
- uint8_t begin_frame;
- uint8_t end_frame;
- uint32_t seq_num;
- uint32_t offset;
-
- if (!b)
- {
- LOG(3, s, t, "MPPP: Invalid bundle id: 0\n");
- return;
- }
-
- begin_frame = (*p & 0x80);
- end_frame = (*p & 0x40);
- if (session[s].mssf)
- {
- // Get 12 bit for seq number
- uint16_t short_seq_num = ntohs((*(uint16_t *) p) & 0xFF0F);
- uint16_t short_seq_num2 = short_seq_num >> 4;
- p += 2;
- l -= 2;
- seq_num = short_seq_num2;
- // After this point the pointer should be advanced 2 bytes
- LOG(3, s, t, "MPPP: 12 bits, sequence number: %d, short1: %d, short2: %d\n",seq_num, short_seq_num, short_seq_num2);
- }
- else
- {
- // Get 24 bit for seq number
- p++;
- seq_num = ntohl((*(uint32_t *) p) & 0xFFFFFF00);
- seq_num = seq_num >> 8;
- p += 3;
- l -= 4;
- // After this point the pointer should be advanced 4 bytes
- LOG(4, s, t, "MPPP: 24 bits sequence number:%d\n",seq_num);
- }
-
- if (seq_num - bundle[b].offset < 0)
- {
- bundle[b].offset = 0;
- bundle[b].pending_frag = 0;
- }
-
- offset = bundle[b].offset;
- if (begin_frame)
- {
- // Check for previous non-assembled frames
- int error = 0;
- if (bundle[b].pending_frag)
- {
- uint32_t fn = bundle[b].seq_num_m - offset;
- uint16_t cur_len;
- bundle[b].pending_frag = 0;
- // Check for array indexes
- if (fn < 0 || fn > MAXFRAGNUM)
- {
- LOG(2, s, t, "ERROR: Index out of range fn:%d, bundle:%d\n",fn,b);
- return;
- }
-
- if (seq_num-offset < 0 || seq_num-offset > MAXFRAGNUM)
- {
- LOG(2, s, t, "ERROR: Index out of range fn(last):%d, bundle:%d\n",fn,b);
- return;
- }
- /////////////////////////////////////////////////////
- cur_len = 4; // This is set to 4 to leave 4 bytes for function processipin
- for (fn = bundle[b].seq_num_m - offset; fn < seq_num - offset; fn++)
- {
- if (!frag[b].fragment[fn].length)
- {
- LOG(4, s, t, "MPPP: Found lost fragment while reassembling frame %d in (%d,%d)\n",fn, bundle[b].seq_num_m-offset, seq_num-offset);
- error = 1;
- break;
- }
-
- if (cur_len + frag[b].fragment[fn].length > MAXETHER)
- {
- LOG(2, s, t, "MPPP: ERROR: very long frame after assembling %d\n", frag[b].fragment[fn].length+cur_len);
- error = 1;
- break;
- }
-
- memcpy(frag[b].reassembled_frame+cur_len, frag[b].fragment[fn].data, frag[b].fragment[fn].length);
- cur_len += frag[b].fragment[fn].length;
- frag[b].fragment[fn].length = 0; // Indicates that this fragment has been consumed
- // This is usefull for compression
- memset(frag[b].fragment[fn].data, 0, sizeof(frag[b].fragment[fn].data));
- }
-
- if (!error)
- {
- frag[b].re_frame_len = cur_len;
- // Process the resassembled frame
- LOG(4, s, t, "MPPP: Process the reassembled frame, len=%d\n",cur_len);
- processmpframe(s, t, frag[b].reassembled_frame, frag[b].re_frame_len, 1);
- // Set reassembled frame length to zero after processing it
- frag[b].re_frame_len = 0;
- memset(frag[b].reassembled_frame, 0, sizeof(frag[b].reassembled_frame));
- }
- }
- //////////////////////////////////////////
- bundle[b].seq_num_m = seq_num;
- if (end_frame)
- {
- // Both bits are set
- LOG(4, s, t, "MPPP: Both bits are set (Begin and End).\n");
- processmpframe(s, t, p, l, 0);
- // The maximum number of fragments is 1500
- if (seq_num - bundle[b].offset >= 1400)
- {
- bundle[b].offset = seq_num;
- LOG(4, s, t, "MPPP: Setting offset to: %d\n",bundle[b].offset);
- }
- }
- else
- {
- bundle[b].pending_frag = 1;
- // End bit is clear
- LOG(4, s, t, "MPPP: Push to receive buffer\n");
- // Push to the receive buffer
- // Array indexes checking
- if (seq_num-offset < 0 || seq_num-offset >= MAXFRAGNUM)
- {
- LOG(2, s, t, "ERROR: Index out of range, push to receive buffer(1) seq:%d, offset:%d, bundle:%d\n",seq_num,offset,b);
- return;
- }
- // Perform length checking
- if (l > MAXFRAGLEN)
- {
- LOG(2, s, t, "MPPP: ERROR: very long fragment length (1)\n");
- return;
- }
- frag[b].fragment[seq_num - offset].length = l;
- memcpy(frag[b].fragment[seq_num - offset].data, p, l);
- }
- }
- else
- {
- LOG(4, s, t, "MPPP: Push to receive buffer\n");
- // Push to the receive buffer
- // Array indexes checking
- if (seq_num-offset < 0 || seq_num-offset >= MAXFRAGNUM)
- {
- LOG(2, s, t, "ERROR: Index out of range, push to receive buffer(2) seq:%d, offset:%d, bundle:%d\n",seq_num,offset,b);
- return;
- }
- // Perform length checking
- if (l > MAXFRAGLEN)
- {
- LOG(2, s, t, "MPPP: ERROR: very long fragment length (2).\n");
- return;
- }
- frag[b].fragment[seq_num - offset].length = l;
- memcpy(frag[b].fragment[seq_num - offset].data, p, l);
- }
-}
-