| 1 |
--- ppp/pppd/demand.c |
| 2 |
+++ ppp/pppd/demand.c 2000/06/28 14:54:04 |
| 3 |
@@ -25,6 +25,8 @@ |
| 4 |
#include <errno.h> |
| 5 |
#include <fcntl.h> |
| 6 |
#include <netdb.h> |
| 7 |
+#include <unistd.h> |
| 8 |
+#include <syslog.h> |
| 9 |
#include <sys/param.h> |
| 10 |
#include <sys/types.h> |
| 11 |
#include <sys/wait.h> |
| 12 |
@@ -32,6 +34,8 @@ |
| 13 |
#include <sys/resource.h> |
| 14 |
#include <sys/stat.h> |
| 15 |
#include <sys/socket.h> |
| 16 |
+#include <netinet/in.h> |
| 17 |
+#include <arpa/inet.h> |
| 18 |
#ifdef PPP_FILTER |
| 19 |
#include <net/if.h> |
| 20 |
#include <net/bpf.h> |
| 21 |
@@ -210,6 +214,14 @@ |
| 22 |
int c, rv; |
| 23 |
|
| 24 |
rv = 0; |
| 25 |
+ |
| 26 |
+/* check for synchronous connection... */ |
| 27 |
+ |
| 28 |
+ if ( (p[0] == 0xFF) && (p[1] == 0x03) ) { |
| 29 |
+ rv = loop_frame(p,n); |
| 30 |
+ return rv; |
| 31 |
+ } |
| 32 |
+ |
| 33 |
for (; n > 0; --n) { |
| 34 |
c = *p++; |
| 35 |
if (c == PPP_FLAG) { |
| 36 |
@@ -288,17 +300,102 @@ |
| 37 |
* loopback, now that the real serial link is up. |
| 38 |
*/ |
| 39 |
void |
| 40 |
-demand_rexmit(proto) |
| 41 |
+demand_rexmit(proto, newip) |
| 42 |
int proto; |
| 43 |
+ u_int32_t newip; |
| 44 |
{ |
| 45 |
struct packet *pkt, *prev, *nextpkt; |
| 46 |
+ unsigned short checksum; |
| 47 |
+ unsigned short pkt_checksum = 0; |
| 48 |
+ unsigned iphdr; |
| 49 |
+ struct timeval tv; |
| 50 |
+ char cv = 0; |
| 51 |
+ char ipstr[16]; |
| 52 |
|
| 53 |
prev = NULL; |
| 54 |
pkt = pend_q; |
| 55 |
pend_q = NULL; |
| 56 |
+ tv.tv_sec = 1; |
| 57 |
+ tv.tv_usec = 0; |
| 58 |
+ select(0,NULL,NULL,NULL,&tv); /* Sleep for 1 Seconds */ |
| 59 |
for (; pkt != NULL; pkt = nextpkt) { |
| 60 |
nextpkt = pkt->next; |
| 61 |
if (PPP_PROTOCOL(pkt->data) == proto) { |
| 62 |
+ if ( (proto == PPP_IP) && newip ) { |
| 63 |
+ /* Get old checksum */ |
| 64 |
+ |
| 65 |
+ iphdr = (pkt->data[4] & 15) << 2; |
| 66 |
+ checksum = *((unsigned short *) (pkt->data+14)); |
| 67 |
+ if (checksum == 0xFFFF) { |
| 68 |
+ checksum = 0; |
| 69 |
+ } |
| 70 |
+ |
| 71 |
+ |
| 72 |
+ if (pkt->data[13] == 17) { |
| 73 |
+ pkt_checksum = *((unsigned short *) (pkt->data+10+iphdr)); |
| 74 |
+ if (pkt_checksum) { |
| 75 |
+ cv = 1; |
| 76 |
+ if (pkt_checksum == 0xFFFF) { |
| 77 |
+ pkt_checksum = 0; |
| 78 |
+ } |
| 79 |
+ } |
| 80 |
+ else { |
| 81 |
+ cv = 0; |
| 82 |
+ } |
| 83 |
+ } |
| 84 |
+ |
| 85 |
+ if (pkt->data[13] == 6) { |
| 86 |
+ pkt_checksum = *((unsigned short *) (pkt->data+20+iphdr)); |
| 87 |
+ cv = 1; |
| 88 |
+ if (pkt_checksum == 0xFFFF) { |
| 89 |
+ pkt_checksum = 0; |
| 90 |
+ } |
| 91 |
+ } |
| 92 |
+ |
| 93 |
+ /* Delete old Source-IP-Address */ |
| 94 |
+ checksum -= *((unsigned short *) (pkt->data+16)) ^ 0xFFFF; |
| 95 |
+ checksum -= *((unsigned short *) (pkt->data+18)) ^ 0xFFFF; |
| 96 |
+ |
| 97 |
+ pkt_checksum -= *((unsigned short *) (pkt->data+16)) ^ 0xFFFF; |
| 98 |
+ pkt_checksum -= *((unsigned short *) (pkt->data+18)) ^ 0xFFFF; |
| 99 |
+ |
| 100 |
+ /* Change Source-IP-Address */ |
| 101 |
+ * ((u_int32_t *) (pkt->data + 16)) = newip; |
| 102 |
+ |
| 103 |
+ /* Add new Source-IP-Address */ |
| 104 |
+ checksum += *((unsigned short *) (pkt->data+16)) ^ 0xFFFF; |
| 105 |
+ checksum += *((unsigned short *) (pkt->data+18)) ^ 0xFFFF; |
| 106 |
+ |
| 107 |
+ pkt_checksum += *((unsigned short *) (pkt->data+16)) ^ 0xFFFF; |
| 108 |
+ pkt_checksum += *((unsigned short *) (pkt->data+18)) ^ 0xFFFF; |
| 109 |
+ |
| 110 |
+ /* Write new checksum */ |
| 111 |
+ if (!checksum) { |
| 112 |
+ checksum = 0xFFFF; |
| 113 |
+ } |
| 114 |
+ *((unsigned short *) (pkt->data+14)) = checksum; |
| 115 |
+ if (pkt->data[13] == 6) { |
| 116 |
+ *((unsigned short *) (pkt->data+20+iphdr)) = pkt_checksum; |
| 117 |
+ } |
| 118 |
+ if (cv && (pkt->data[13] == 17) ) { |
| 119 |
+ *((unsigned short *) (pkt->data+10+iphdr)) = pkt_checksum; |
| 120 |
+ } |
| 121 |
+ |
| 122 |
+ /* Log Packet */ |
| 123 |
+ strcpy(ipstr,inet_ntoa(*( (struct in_addr *) (pkt->data+16)))); |
| 124 |
+ if (pkt->data[13] == 1) { |
| 125 |
+ syslog(LOG_INFO,"Open ICMP %s -> %s\n", |
| 126 |
+ ipstr, |
| 127 |
+ inet_ntoa(*( (struct in_addr *) (pkt->data+20)))); |
| 128 |
+ } else { |
| 129 |
+ syslog(LOG_INFO,"Open %s %s:%d -> %s:%d\n", |
| 130 |
+ pkt->data[13] == 6 ? "TCP" : "UDP", |
| 131 |
+ ipstr, |
| 132 |
+ ntohs(*( (short *) (pkt->data+iphdr+4))), |
| 133 |
+ inet_ntoa(*( (struct in_addr *) (pkt->data+20))), |
| 134 |
+ ntohs(*( (short *) (pkt->data+iphdr+6)))); |
| 135 |
+ } |
| 136 |
+ } |
| 137 |
output(0, pkt->data, pkt->length); |
| 138 |
free(pkt); |
| 139 |
} else { |
| 140 |
--- ppp/pppd/ipcp.c |
| 141 |
+++ ppp/pppd/ipcp.c 2000/06/28 12:32:05 |
| 142 |
@@ -1454,7 +1454,7 @@ |
| 143 |
proxy_arp_set[f->unit] = 1; |
| 144 |
|
| 145 |
} |
| 146 |
- demand_rexmit(PPP_IP); |
| 147 |
+ demand_rexmit(PPP_IP,go->ouraddr); |
| 148 |
sifnpmode(f->unit, PPP_IP, NPMODE_PASS); |
| 149 |
|
| 150 |
} else { |
| 151 |
--- ppp/pppd/ipv6cp.c |
| 152 |
+++ ppp/pppd/ipv6cp.c 2000/06/28 12:32:06 |
| 153 |
@@ -1153,7 +1153,7 @@ |
| 154 |
} |
| 155 |
|
| 156 |
} |
| 157 |
- demand_rexmit(PPP_IPV6); |
| 158 |
+ demand_rexmit(PPP_IPV6,0); |
| 159 |
sifnpmode(f->unit, PPP_IPV6, NPMODE_PASS); |
| 160 |
|
| 161 |
} else { |
| 162 |
--- ppp/pppd/pppd.h |
| 163 |
+++ ppp/pppd/pppd.h 2000/06/28 12:32:06 |
| 164 |
@@ -359,7 +359,7 @@ |
| 165 |
void demand_block __P((void)); /* set all NPs to queue up packets */ |
| 166 |
void demand_unblock __P((void)); /* set all NPs to pass packets */ |
| 167 |
void demand_discard __P((void)); /* set all NPs to discard packets */ |
| 168 |
-void demand_rexmit __P((int)); /* retransmit saved frames for an NP */ |
| 169 |
+void demand_rexmit __P((int, u_int32_t)); /* retransmit saved frames for an NP*/ |
| 170 |
int loop_chars __P((unsigned char *, int)); /* process chars from loopback */ |
| 171 |
int loop_frame __P((unsigned char *, int)); /* should we bring link up? */ |
| 172 |
|