--- ppp/pppd/demand.c +++ ppp/pppd/demand.c 2000/06/28 14:54:04 @@ -25,6 +25,8 @@ #include #include #include +#include +#include #include #include #include @@ -32,6 +34,8 @@ #include #include #include +#include +#include #ifdef PPP_FILTER #include #include @@ -210,6 +214,14 @@ int c, rv; rv = 0; + +/* check for synchronous connection... */ + + if ( (p[0] == 0xFF) && (p[1] == 0x03) ) { + rv = loop_frame(p,n); + return rv; + } + for (; n > 0; --n) { c = *p++; if (c == PPP_FLAG) { @@ -288,17 +300,102 @@ * loopback, now that the real serial link is up. */ void -demand_rexmit(proto) +demand_rexmit(proto, newip) int proto; + u_int32_t newip; { struct packet *pkt, *prev, *nextpkt; + unsigned short checksum; + unsigned short pkt_checksum = 0; + unsigned iphdr; + struct timeval tv; + char cv = 0; + char ipstr[16]; prev = NULL; pkt = pend_q; pend_q = NULL; + tv.tv_sec = 1; + tv.tv_usec = 0; + select(0,NULL,NULL,NULL,&tv); /* Sleep for 1 Seconds */ for (; pkt != NULL; pkt = nextpkt) { nextpkt = pkt->next; if (PPP_PROTOCOL(pkt->data) == proto) { + if ( (proto == PPP_IP) && newip ) { + /* Get old checksum */ + + iphdr = (pkt->data[4] & 15) << 2; + checksum = *((unsigned short *) (pkt->data+14)); + if (checksum == 0xFFFF) { + checksum = 0; + } + + + if (pkt->data[13] == 17) { + pkt_checksum = *((unsigned short *) (pkt->data+10+iphdr)); + if (pkt_checksum) { + cv = 1; + if (pkt_checksum == 0xFFFF) { + pkt_checksum = 0; + } + } + else { + cv = 0; + } + } + + if (pkt->data[13] == 6) { + pkt_checksum = *((unsigned short *) (pkt->data+20+iphdr)); + cv = 1; + if (pkt_checksum == 0xFFFF) { + pkt_checksum = 0; + } + } + + /* Delete old Source-IP-Address */ + checksum -= *((unsigned short *) (pkt->data+16)) ^ 0xFFFF; + checksum -= *((unsigned short *) (pkt->data+18)) ^ 0xFFFF; + + pkt_checksum -= *((unsigned short *) (pkt->data+16)) ^ 0xFFFF; + pkt_checksum -= *((unsigned short *) (pkt->data+18)) ^ 0xFFFF; + + /* Change Source-IP-Address */ + * ((u_int32_t *) (pkt->data + 16)) = newip; + + /* Add new Source-IP-Address */ + checksum += *((unsigned short *) (pkt->data+16)) ^ 0xFFFF; + checksum += *((unsigned short *) (pkt->data+18)) ^ 0xFFFF; + + pkt_checksum += *((unsigned short *) (pkt->data+16)) ^ 0xFFFF; + pkt_checksum += *((unsigned short *) (pkt->data+18)) ^ 0xFFFF; + + /* Write new checksum */ + if (!checksum) { + checksum = 0xFFFF; + } + *((unsigned short *) (pkt->data+14)) = checksum; + if (pkt->data[13] == 6) { + *((unsigned short *) (pkt->data+20+iphdr)) = pkt_checksum; + } + if (cv && (pkt->data[13] == 17) ) { + *((unsigned short *) (pkt->data+10+iphdr)) = pkt_checksum; + } + + /* Log Packet */ + strcpy(ipstr,inet_ntoa(*( (struct in_addr *) (pkt->data+16)))); + if (pkt->data[13] == 1) { + syslog(LOG_INFO,"Open ICMP %s -> %s\n", + ipstr, + inet_ntoa(*( (struct in_addr *) (pkt->data+20)))); + } else { + syslog(LOG_INFO,"Open %s %s:%d -> %s:%d\n", + pkt->data[13] == 6 ? "TCP" : "UDP", + ipstr, + ntohs(*( (short *) (pkt->data+iphdr+4))), + inet_ntoa(*( (struct in_addr *) (pkt->data+20))), + ntohs(*( (short *) (pkt->data+iphdr+6)))); + } + } output(0, pkt->data, pkt->length); free(pkt); } else { --- ppp/pppd/ipcp.c +++ ppp/pppd/ipcp.c 2000/06/28 12:32:05 @@ -1454,7 +1454,7 @@ proxy_arp_set[f->unit] = 1; } - demand_rexmit(PPP_IP); + demand_rexmit(PPP_IP,go->ouraddr); sifnpmode(f->unit, PPP_IP, NPMODE_PASS); } else { --- ppp/pppd/ipv6cp.c +++ ppp/pppd/ipv6cp.c 2000/06/28 12:32:06 @@ -1153,7 +1153,7 @@ } } - demand_rexmit(PPP_IPV6); + demand_rexmit(PPP_IPV6,0); sifnpmode(f->unit, PPP_IPV6, NPMODE_PASS); } else { --- ppp/pppd/pppd.h +++ ppp/pppd/pppd.h 2000/06/28 12:32:06 @@ -359,7 +359,7 @@ void demand_block __P((void)); /* set all NPs to queue up packets */ void demand_unblock __P((void)); /* set all NPs to pass packets */ void demand_discard __P((void)); /* set all NPs to discard packets */ -void demand_rexmit __P((int)); /* retransmit saved frames for an NP */ +void demand_rexmit __P((int, u_int32_t)); /* retransmit saved frames for an NP*/ int loop_chars __P((unsigned char *, int)); /* process chars from loopback */ int loop_frame __P((unsigned char *, int)); /* should we bring link up? */