c2786569875aef75d1372225339b1ca1ef7bb4ff
[openwrt/staging/chunkeey.git] / package / network / services / ppp / patches / 105-debian_demand.patch
1 --- a/pppd/demand.c
2 +++ b/pppd/demand.c
3 @@ -36,6 +36,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 @@ -43,6 +45,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 <pcap-bpf.h>
20 #endif
21 @@ -221,6 +225,14 @@ loop_chars(p, n)
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 @@ -299,17 +311,102 @@ loop_frame(frame, len)
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 --- a/pppd/ipcp.c
141 +++ b/pppd/ipcp.c
142 @@ -1864,7 +1864,7 @@ ipcp_up(f)
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 --- a/pppd/ipv6cp.c
152 +++ b/pppd/ipv6cp.c
153 @@ -1232,7 +1232,7 @@ ipv6cp_up(f)
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 --- a/pppd/pppd.h
163 +++ b/pppd/pppd.h
164 @@ -566,7 +566,7 @@ void demand_conf __P((void)); /* config
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