7 #include <netinet/in.h>
12 #include <sys/socket.h>
13 #include <sys/types.h>
15 #include <linux/udp.h>
23 #define PPPCHAP 0xc223
24 #define PPPIPCP 0x8021
40 #define PACKET_LENGTH 1000
41 #define TARGET_PPS 5000
42 #define TARGET "211.29.131.33"
43 #define GWADDR "211.29.131.30"
44 #define NUM_SESSIONS 1
48 typedef unsigned short u16
;
49 typedef unsigned int u32
;
50 typedef unsigned char u8
;
87 char *attributes
[] = {
90 "Protocol Version", // 2
91 "Framing Capabilities", // 3
92 "Bearer Capabilities", // 4
94 "Firmware Revision", // 6
97 "Assigned Tunnel ID", // 9
98 "Receive Window Size", // 10
100 "Q.931 Cause Code", // 12
101 "Challenge Response", // 13
102 "Assigned Session ID", // 14
103 "Call Serial Number", // 15
106 "Bearer Type", // 18 (2 = Analog, 1 = Digital)
107 "Framing Type", // 19 (2 = Async, 1 = Sync)
109 "Called Number", // 21
110 "Calling Number", // 22
112 "Tx Connect Speed", // 24
113 "Physical Channel ID", // 25
114 "Initial Received LCP CONFREQ", // 26
115 "Last Sent LCP CONFREQ", // 27
116 "Last Received LCP CONFREQ", // 28
117 "Proxy Authen Type", // 29
118 "Proxy Authen Name", // 30
119 "Proxy Authen Challenge", // 31
120 "Proxy Authen ID", // 32
121 "Proxy Authen Response", // 33
124 "Random Vector", // 36
125 "Private Group ID", // 37
126 "Rx Connect Speed", // 38
127 "Sequencing Required", // 39
130 char *result_codes
[] = {
132 "General request to clear control connection",
133 "General error--Error Code indicates the problem",
134 "Control channel already exists",
135 "Requester is not authorized to establish a control channel",
136 "The protocol version of the requester is not supported",
137 "Requester is being shut down",
138 "Finite State Machine error",
141 char *error_codes
[] = {
143 "No control connection exists yet for this LAC-LNS pair",
145 "One of the field values was out of range or reserved field was non-zero",
146 "Insufficient resources to handle this operation now",
147 "The Session ID is invalid in this context",
148 "A generic vendor-specific error occurred in the LAC",
150 "Session or tunnel was shutdown due to receipt of an unknown AVP with the M-bit set",
182 unsigned long long send_count
, recv_count
;
183 unsigned long long spkt
, rpkt
;
184 unsigned int dropped
;
185 unsigned long sbytes
, rbytes
;
189 short remote_session
;
192 unsigned char ppp_identifier
;
196 int active_sessions
;
201 void controlsend(controlt
* c
, short t
, short s
);
202 void controlnull(short t
);
203 controlt
*controlnew(u16 mtype
);
204 void controls(controlt
* c
, u16 avp
, char *val
, u8 m
);
205 void control16(controlt
* c
, u16 avp
, u16 val
, u8 m
);
206 void control32(controlt
* c
, u16 avp
, u32 val
, u8 m
);
207 void controlfree(controlt
*c
);
208 control_message
*parsecontrol(char *buf
, int length
);
209 void dump_control_message(control_message
*c
);
210 u32
avp_get_32(control_message
*c
, int id
);
211 u16
avp_get_16(control_message
*c
, int id
);
212 char *avp_get_s(control_message
*c
, int id
);
213 void reader_thread(int udpfd
);
215 void cm_free(control_message
*m
);
216 controlt
*ppp_new(u16 session
, int protocol
);
217 void ppp_free(controlt
*packet
);
218 controlt
*ppp_lcp(u16 s
, unsigned char type
, char identifier
);
219 controlt
*ppp_ipcp(u16 s
, unsigned char type
, char identifier
);
220 void ppp_send(controlt
*c
);
221 void ppp_add_16(controlt
* c
, u16 val
);
222 void ppp_add_32(controlt
* c
, u32 val
);
223 void ppp_add_s(controlt
* c
, char *val
);
224 void ppp_lcp_add_option(controlt
*c
, unsigned char option
, unsigned char length
, int data
);
225 void dump_ppp_packet(char *packet
, int l
);
226 controlt
*ppp_pap(u16 s
, unsigned char type
, char identifier
, char *username
, char *password
);
227 char *inet_toa(unsigned long addr
);
228 __u16
checksum(unsigned char *addr
, int count
);
229 void sigalarm(int junk
);
230 void sigint(int signal
);
231 void clean_shutdown();
237 struct sockaddr_in gatewayaddr
= {0};
238 int numsessions
= NUM_SESSIONS
;
239 int packet_length
= PACKET_LENGTH
;
240 int target_pps
= TARGET_PPS
;
241 char *target
= TARGET
;
242 char *gwaddr
= GWADDR
;
243 int max_packets
= MAX_PACKETS
;
246 char **session_usernames
;
247 char *base_username
= "dslloadtest";
248 char *base_password
= "testing";
249 char *suffix
= "@optusnet.com.au";
251 int main(int argc
, char *argv
[])
256 ss
= (sharedt
*) mmap(NULL
, sizeof(*ss
), PROT_READ
| PROT_WRITE
, MAP_SHARED
| MAP_ANONYMOUS
, 0, 0);
258 // Process Arguments {{{
259 while ((s
= getopt(argc
, argv
, "?hs:g:l:p:m:t:nU:P:")) > 0)
264 numsessions
= atoi(optarg
);
265 if (numsessions
<= 0)
267 printf("You must have at least 1 session\n");
272 packet_length
= atoi(optarg
);
273 if (packet_length
< 64)
275 printf("You must have at least 64 byte packets\n");
283 target_pps
= atoi(optarg
);
286 max_packets
= atoi(optarg
);
287 if (max_packets
< 50)
289 printf("You must send at least 50 packets.\n");
294 target
= strdup(optarg
);
297 gwaddr
= strdup(optarg
);
300 base_username
= strdup(optarg
);
303 base_password
= strdup(optarg
);
307 printf("Options:\n");
308 printf("\t-s number of ss->sessions\n");
309 printf("\t-l packet length\n");
310 printf("\t-p target pps\n");
311 printf("\t-m maximum number of packets\n");
312 printf("\t-t target IP address\n");
313 printf("\t-g gateway IP address\n");
314 printf("\t-U username (or base if multiple)\n");
315 printf("\t-P password\n");
321 ppsend
= target_pps
/ 50;
325 packet
= calloc(4096, 1);
327 memset(ss
->sessions
, 0, sizeof(ss
->sessions
));
330 printf("Creating %d ss->sessions to %s\n", numsessions
, gwaddr
);
331 printf("Targeting %d packets per second\n", target_pps
);
332 if (max_packets
) printf("Sending a maximum of %d packets\n", max_packets
);
333 printf("Sending packets to %s\n", target
);
334 printf("Sending %d byte packets\n", packet_length
);
336 session_usernames
= (char **)calloc(sizeof(char *), numsessions
);
339 int sul
= strlen(base_username
) + 10;
342 for (i
= 0; i
< numsessions
; i
++)
344 session_usernames
[i
] = (char *)calloc(sul
, 1);
345 snprintf(session_usernames
[i
], sul
, "%s%d", base_username
, i
+1);
350 session_usernames
[0] = strdup(base_username
);
354 // Create socket/*{{{*/
357 struct sockaddr_in addr
;
359 memset(&addr
, 0, sizeof(addr
));
360 addr
.sin_family
= AF_INET
;
361 addr
.sin_port
= htons(38001);
363 udpfd
= socket(AF_INET
, SOCK_DGRAM
, IPPROTO_UDP
);
370 setsockopt(udpfd
, SOL_SOCKET
, SO_REUSEADDR
, &on
, sizeof(on
));
371 if (bind(udpfd
, (void *) &addr
, sizeof(addr
)) < 0)
377 printf("Bound to port %d\n", htons(addr
.sin_port
));
380 gatewayaddr
.sin_family
= AF_INET
;
381 gatewayaddr
.sin_port
= htons(1701);
382 inet_aton(gwaddr
, &gatewayaddr
.sin_addr
);
384 // Create tunnel/*{{{*/
389 c
= controlnew(1); // SCCRQ
390 controls(c
, 7, "loadtest", 0); // Tunnel Hostname
391 controls(c
, 8, "OIE", 0); // Vendor Name
392 control16(c
, 9, 1, 0); // Assigned Tunnel ID
393 control16(c
, 2, 256, 0); // Version 1.0
394 control16(c
, 3, 1, 0); // Framing (Async)
395 control16(c
, 4, 1, 0); // Bearer (Digital)
396 control16(c
, 10, 20, 0); // Receive Window Size
397 controlsend(c
, 0, 0);
400 // Receive reply/*{{{*/
402 struct sockaddr_in addr
;
403 int alen
= sizeof(addr
), l
;
405 l
= recvfrom(udpfd
, packet
, 4096, 0, (void *) &addr
, &alen
);
408 printf("Error creating tunnel: %s\n", strerror(errno
));
412 r
= parsecontrol(packet
, l
);
415 printf("Invalid packet.. no first avp\n");
419 printf("Assigned tunnel: %d\n", t
= avp_get_16(r
, 9));
422 c
= controlnew(3); // SCCCN
423 controlsend(c
, t
, 0);
430 // Create ss->sessions/*{{{*/
433 for (s
= 1; s
<= numsessions
; s
++)
437 c
= controlnew(10); // ICRQ
438 controls(c
, 21, "12356", 0); // Called Number
439 controls(c
, 22, "000", 0); // Calling Number
440 control16(c
, 14, s
, 0); // Assigned Session ID
441 controlsend(c
, t
, 0);
443 usleep(15000); // 15 ms
446 printf("All session create requests sent...\n");/*}}}*/
449 reader_thread(udpfd
);
455 fprintf(stderr
, "Press enter to begin sending traffic\n");
456 fgets(tmp
, 512, stdin
);
459 fprintf(stderr
, "Beginning sending traffic through %d ss->sessions\n", ss
->active_sessions
);
460 printf(" TS: Total Packets Sent\n");
461 printf(" TL: Total Packets Lost\n");
462 printf(" PL: Packet Loss\n");
463 printf(" SS: Send Speed\n");
464 printf(" RS: Receive Speed\n");
465 printf(" SP: Packets/Second Sent\n");
466 printf(" RP: Packets/Second Received\n");
467 printf(" NS: Number of active ss->sessions\n");
469 signal(SIGALRM
, sigalarm
);
470 signal(SIGINT
, sigint
);
473 // Traffic generation loop {{{
475 struct sockaddr_in to
;
480 unsigned int seq
= 0;
484 memset(&to
, 0, sizeof(struct sockaddr_in
));
485 to
.sin_family
= AF_INET
;
486 inet_aton(target
, &to
.sin_addr
);
488 c
= ppp_new(1, PPPIP
);
490 iph
= (struct iphdr
*)(c
->buf
+ c
->length
);
491 udph
= (struct udphdr
*)(c
->buf
+ c
->length
+ sizeof(struct iphdr
));
492 data
= (char *)(c
->buf
+ c
->length
+ sizeof(struct iphdr
) + sizeof(struct udphdr
));
493 len
= sizeof(struct iphdr
) + sizeof(struct udphdr
);
497 c
->length
+= sizeof(struct iphdr
);
500 iph
->frag_off
= ntohs(1 << 14);
506 memcpy(&iph
->daddr
, &to
.sin_addr
, sizeof(iph
->daddr
));
509 udph
->source
= ntohs(39999);
510 udph
->dest
= ntohs(39000);
514 memset(data
, 64, 1500);
516 udph
->len
= ntohs(sizeof(struct udphdr
) + packet_length
);
517 iph
->tot_len
= ntohs(len
+ packet_length
);
518 c
->length
+= packet_length
;
520 while (!ss
->quitit
&& ss
->active_sessions
)
523 for (i
= 1; i
<= numsessions
&& !ss
->quitit
; i
++)
525 // Skip ss->sessions that aren't active yet
526 if (!ss
->sessions
[i
].open
|| ss
->sessions
[i
].ppp_state
!= 2)
529 *(u16
*)(c
->buf
+ 4) = htons(ss
->sessions
[i
].remote_session
); // Session ID
530 iph
->saddr
= ss
->sessions
[i
].addr
;
532 iph
->check
= ntohs(checksum((char *)iph
, sizeof(struct iphdr
)));
534 *((unsigned int *) data
) = seq
++;
539 ss
->sbytes
+= c
->length
;
541 if (ppsend
&& ss
->send_count
% ppsend
== 0)
545 req
.tv_nsec
= 5 * 1000 * 1000;
546 nanosleep(&req
, NULL
);
549 if (max_packets
&& ss
->send_count
>= max_packets
) ss
->quitit
++;
553 c
->length
-= packet_length
;
568 loss
= 100 - (((ss
->recv_count
* 1.0) / (ss
->send_count
* 1.0)) * 100.0);
571 printf("Total Packets Sent: %llu\n", ss
->send_count
);
572 printf("Total Packets Received: %llu\n", ss
->recv_count
);
573 printf("Overall Packet Loss: %0.2f%%", loss
);
577 void clean_shutdown()/*{{{*/
580 for (i
= 0; i
< numsessions
; i
++)
585 if (!ss
->sessions
[i
].open
) continue;
586 c
= controlnew(14); // CDN
587 control16(c
, 14, i
, 0); // Assigned Session ID
588 control16(c
, 1, 1, 0); // Result Code
589 controlsend(c
, t
, ss
->sessions
[i
].remote_session
);
597 c
= controlnew(4); // StopCCN
598 control16(c
, 9, 1, 0); // Assigned Tunnel ID
599 control16(c
, 1, 1, 0); // Result Code
600 controlsend(c
, t
, 0);
605 void sigint(int signal
)
610 void sigalarm(int junk
)
612 static unsigned long long last_rpkts
[AVG_SIZE
], last_spkts
[AVG_SIZE
];
613 static int last
= 0, avg_count
= 0;
614 register unsigned int avg_s
= 0, avg_r
= 0, i
;
617 last_rpkts
[last
] = ss
->rpkt
;
618 last_spkts
[last
] = ss
->spkt
;
619 last
= (last
+ 1) % AVG_SIZE
;
620 if (avg_count
< AVG_SIZE
) avg_count
++;
622 for (i
= 0; i
< avg_count
; i
++)
624 avg_s
+= last_spkts
[i
];
625 avg_r
+= last_rpkts
[i
];
630 loss
= 100 - (((avg_r
* 1.0) / (avg_s
* 1.0)) * 100.0);
631 fprintf(stderr
, "TS:%llu TL:%lld DR:%4d PL:%-3.2f%% SS:%0.1fMbits/s RS:%0.1fMbits/s NS:%u SP:%u RP:%u\n",
632 ss
->send_count
, ss
->send_count
-ss
->recv_count
, ss
->dropped
, loss
,
633 (ss
->sbytes
/1024.0/1024.0*8), (ss
->rbytes
/1024.0/1024.0*8),
637 ss
->spkt
= ss
->rpkt
= 0;
638 ss
->sbytes
= ss
->rbytes
= 0;
642 __u16
checksum(unsigned char *addr
, int count
)
644 register long sum
= 0;
646 for (; count
> 1; count
-= 2)
648 sum
+= ntohs(*(u16
*)addr
);
652 if (count
> 0) sum
+= *(unsigned char *)addr
;
654 // take only 16 bits out of the 32 bit sum and add up the carries
656 sum
= (sum
& 0xFFFF) + (sum
>> 16);
658 // one's complement the result
665 void control16(controlt
* c
, u16 avp
, u16 val
, u8 m
)
667 u16 l
= (m
? 0x8008 : 0x0008);
668 *(u16
*) (c
->buf
+ c
->length
+ 0) = htons(l
);
669 *(u16
*) (c
->buf
+ c
->length
+ 2) = htons(0);
670 *(u16
*) (c
->buf
+ c
->length
+ 4) = htons(avp
);
671 *(u16
*) (c
->buf
+ c
->length
+ 6) = htons(val
);
675 // add an AVP (32 bit)
676 void control32(controlt
* c
, u16 avp
, u32 val
, u8 m
)
678 u16 l
= (m
? 0x800A : 0x000A);
679 *(u16
*) (c
->buf
+ c
->length
+ 0) = htons(l
);
680 *(u16
*) (c
->buf
+ c
->length
+ 2) = htons(0);
681 *(u16
*) (c
->buf
+ c
->length
+ 4) = htons(avp
);
682 *(u32
*) (c
->buf
+ c
->length
+ 6) = htonl(val
);
686 // add an AVP (32 bit)
687 void controls(controlt
* c
, u16 avp
, char *val
, u8 m
)
689 u16 l
= ((m
? 0x8000 : 0) + strlen(val
) + 6);
690 *(u16
*) (c
->buf
+ c
->length
+ 0) = htons(l
);
691 *(u16
*) (c
->buf
+ c
->length
+ 2) = htons(0);
692 *(u16
*) (c
->buf
+ c
->length
+ 4) = htons(avp
);
693 memcpy(c
->buf
+ c
->length
+ 6, val
, strlen(val
));
694 c
->length
+= 6 + strlen(val
);
697 // new control connection
698 controlt
*controlnew(u16 mtype
)
701 c
= calloc(sizeof(controlt
), 1);
703 control16(c
, 0, mtype
, 1);
707 void controlnull(short t
)
710 c
= calloc(sizeof(controlt
), 1);
712 controlsend(c
, t
, 0);
717 // add a control message to a tunnel, and send if within window
718 void controlsend(controlt
* c
, short t
, short s
)
720 *(u16
*) (c
->buf
+ 0) = htons(0xC802); // flags/ver
721 *(u16
*) (c
->buf
+ 2) = htons(c
->length
); // length
722 *(u16
*) (c
->buf
+ 4) = htons(t
); // tunnel
723 *(u16
*) (c
->buf
+ 6) = htons(s
); // session
724 *(u16
*) (c
->buf
+ 8) = htons(ns
++); // sequence
725 *(u16
*) (c
->buf
+ 10) = htons(nr
); // sequence
726 // printf("Sending ");
727 // cm_free(parsecontrol(c->buf, c->length));
728 sendto(udpfd
, c
->buf
, c
->length
, 0, (struct sockaddr
*)&gatewayaddr
, sizeof(gatewayaddr
));
731 void controlfree(controlt
*c
)
737 control_message
*parsecontrol(char *buf
, int length
)
742 c
= calloc(sizeof(control_message
), 1);
746 c
->tunnel
= ntohs(*(u16
*)(buf
+ 4));
747 c
->session
= ntohs(*(u16
*)(buf
+ 6));
748 c
->ns
= ntohs(*(u16
*)(buf
+ 8));
749 c
->nr
= nr
= ntohs(*(u16
*)(buf
+ 10));
751 while ((p
- buf
) < length
)
753 avp
*a
= calloc(sizeof(avp
), 1);
754 a
->length
= ntohs(*(short *)(p
)) & 0x3FF;
755 a
->type
= ntohs(*(short *)(p
+ 4));
756 memcpy(a
->value
, p
+ 6, a
->length
- 6);
757 if (a
->type
== 0) c
->mtype
= ntohs(*(short *)a
->value
);
766 dump_control_message(c
);
770 void dump_control_message(control_message
*c
)
773 printf("Control Message (type=%u s=%u t=%d ns=%d nr=%d)\n", c
->mtype
, c
->session
, c
->tunnel
, c
->ns
, c
->nr
);
774 for (a
= c
->first
; a
; a
= a
->next
)
776 printf(" avp: %s, len: %d", attributes
[a
->type
], a
->length
- 6);
784 case 14 : printf(", value: %u\n", ntohs(*(short *)a
->value
));
793 case 15 : printf(", value: %u\n", ntohl(*(u32
*)a
->value
));
802 case 8 : printf(", value: \"%s\"\n", a
->value
);
805 case 2 : printf(", value: %d.%d\n", *(char *)a
->value
, *(char *)a
->value
+ 1);
807 case 0 : printf(", value: %s\n", mtypes
[ntohs(*(short *)a
->value
)]);
810 case 3 : printf(", value: (%d) %s %s\n", ntohl(*(u32
*)a
->value
),
811 (ntohl(*(u32
*)a
->value
) & 0x01) ? "synchronous" : "",
812 (ntohl(*(u32
*)a
->value
) & 0x02) ? "asynchronous" : "");
815 case 4 : printf(", value: (%d) %s %s\n", ntohl(*(u32
*)a
->value
),
816 (ntohl(*(u32
*)a
->value
) & 0x01) ? "digital" : "",
817 (ntohl(*(u32
*)a
->value
) & 0x02) ? "analog" : "");
820 default : printf("\n");
827 u16
avp_get_16(control_message
*c
, int id
)
831 for (a
= c
->first
; a
; a
= a
->next
)
832 if (a
->type
== id
) return ntohs(*(short *)a
->value
);
836 u32
avp_get_32(control_message
*c
, int id
)
840 for (a
= c
->first
; a
; a
= a
->next
)
841 if (a
->type
== id
) return ntohl(*(u32
*)a
->value
);
845 char *avp_get_s(control_message
*c
, int id
)
849 for (a
= c
->first
; a
; a
= a
->next
)
850 if (a
->type
== id
) return (char *)a
->value
;
854 void cm_free(control_message
*m
)
858 for (a
= m
->first
; a
; )
870 void reader_thread(int updfd
)/*{{{*/
872 unsigned char *packet
;
873 unsigned int seq
= 0;
875 printf("Starting reader thread\n");
876 packet
= malloc(4096);
879 struct sockaddr_in addr
;
880 int alen
= sizeof(addr
);
886 // memset(packet, 0, 4096);
887 if ((l
= recvfrom(udpfd
, packet
, 4096, 0, (void *) &addr
, &alen
)) < 0) break;
897 printf("Short packet received: %d bytes\n", l
);
899 s
= ntohs(*(u16
*)(packet
+ 4));
902 printf("Invalid session ID\n");
905 if (packet
[0] == 0xc8)
908 printf("Reader Received ");
909 m
= parsecontrol(packet
, l
);
915 case 4 : printf("StopCCN\n");
916 printf("Killing tunnel %d\n", avp_get_16(m
, 9));
919 case 6 : printf("HELLO, sending ZLB ACK\n");
926 printf("Received ICRP. Responding with CONFREQ\n");
928 ss
->sessions
[s
].remote_session
= avp_get_16(m
, 14);
929 ss
->sessions
[s
].open
= 1;
930 ss
->sessions
[s
].ppp_state
= 1;
932 c
= controlnew(12); // ICCN
933 controlsend(c
, t
, ss
->sessions
[s
].remote_session
);
936 c
= ppp_lcp(s
, CONFREQ
, 0);
937 ppp_lcp_add_option(c
, 1, 2, htons(1500)); // MRU = 1400
938 ppp_lcp_add_option(c
, 3, 2, htons(0xC023)); // Authentication Protocol - PAP
946 s
= avp_get_16(m
, 14);
947 printf("Killing session %d\n", s
);
948 ss
->sessions
[s
].open
= 0;
949 ss
->sessions
[s
].ppp_state
= 0;
950 ss
->active_sessions
--;
958 printf("StopCCN Received.. Dieing\n");
967 unsigned short protocol
= ntohs(*(u16
*)(packet
+ 6));
969 if (protocol
== 0xff03)
973 protocol
= ntohs(*(u16
*)(packet
+ 6));
975 if (protocol
!= PPPIP
)
978 dump_ppp_packet(packet
+ 6, l
- 6);
981 if (protocol
== PPPLCP
)
984 unsigned char ppp_id
= *(char *)(packet
+ 9);
986 switch (*(char *)(packet
+ 8))
989 r
= ppp_lcp(s
, CONFACK
, ppp_id
);
993 r
= ppp_pap(s
, CONFREQ
, 0, session_usernames
[s
-1], base_password
);
997 r
= ppp_lcp(s
, TERMACK
, ppp_id
);
1001 r
= ppp_lcp(s
, ECHOREP
, ppp_id
);
1007 else if (protocol
== PPPIPCP
)
1011 u32 address
= *(u32
*)(packet
+ 14);
1013 switch (*(char *)(packet
+ 8))
1016 r
= ppp_ipcp(s
, CONFREQ
, time(NULL
) % 255);
1017 ppp_lcp_add_option(r
, 3, 4, htonl(taddr
)); // Request 0.0.0.0
1020 r
= ppp_ipcp(s
, CONFACK
, time(NULL
) % 255);
1021 ppp_lcp_add_option(r
, 3, 4, address
); // ACK gateway IP
1026 // Request whatever address we are given - it's ours
1027 r
= ppp_ipcp(s
, CONFREQ
, time(NULL
) % 255);
1028 ppp_lcp_add_option(r
, 3, 4, address
);
1031 printf("Session %d: %s\n", s
, inet_toa(address
));
1032 ss
->sessions
[s
].ppp_state
= 2;
1033 ss
->sessions
[s
].addr
= address
;
1034 ss
->active_sessions
++;
1037 printf("Conf-Ack Received\n");
1040 printf("Term-Req Received\n");
1043 printf("Echo-Req Received\n");
1046 printf("Echo-Rep Received\n");
1050 else if (protocol
== PPPPAP
)
1052 if (*(u16
*)(packet
+ 8) == 3)
1055 printf("Closing Connection\n");
1057 c
= controlnew(14); // CDN
1058 control16(c
, 14, ss
->sessions
[s
].remote_session
, 0); // Assigned Session ID
1059 controlsend(c
, t
, 0);
1061 ss
->sessions
[s
].open
= 0;
1064 else if (protocol
== PPPIP
)
1066 struct iphdr
*iph
= (struct iphdr
*)(packet
+ 8);
1067 char * data
= (char*) (packet
+ 8 + sizeof(struct iphdr
) + sizeof(struct udphdr
));
1068 if (!ss
->sessions
[s
].open
)
1070 printf("Packet for closed session %d\n", s
);
1074 if (iph
->protocol
== 17)
1079 iseq
= *((unsigned int *) data
);
1081 ss
->dropped
+= (iseq
- seq
) ;
1083 seq
= iseq
+ 1; // Next sequence number to expect.
1091 printf("Closing reader thread\n");
1095 void skip_zlb() /*{{{*/
1097 struct sockaddr_in addr
;
1098 int alen
= sizeof(addr
);
1101 l
= recvfrom(udpfd
, buf
, 1024, MSG_PEEK
, (void *) &addr
, &alen
);
1104 printf("recvfrom: %s\n", strerror(errno
));
1109 printf("Skipping ZLB (l=%d)\n", l
);
1110 recvfrom(udpfd
, buf
, 1024, 0, (void *) &addr
, &alen
);
1116 controlt
*ppp_new(u16 session
, int protocol
)
1118 controlt
*c
= calloc(sizeof(controlt
), 1);
1119 *(u16
*)(c
->buf
+ 4) = htons(ss
->sessions
[session
].remote_session
); // Tunnel
1120 *(u16
*)(c
->buf
+ 6) = htons(protocol
);
1126 void ppp_free(controlt
*c
)
1131 controlt
*ppp_lcp(u16 s
, unsigned char type
, char identifier
)
1135 if (!identifier
) identifier
= ss
->sessions
[s
].ppp_identifier
++;
1136 c
= ppp_new(s
, PPPLCP
);
1137 *(char *)(c
->buf
+ c
->length
+ 0) = type
;
1138 *(char *)(c
->buf
+ c
->length
+ 1) = identifier
;
1139 *(u16
*)(c
->buf
+ c
->length
+ 2) = ntohs(4);
1145 controlt
*ppp_ipcp(u16 s
, unsigned char type
, char identifier
)
1149 if (!identifier
) identifier
= ss
->sessions
[s
].ppp_identifier
++;
1150 c
= ppp_new(s
, PPPIPCP
);
1151 *(char *)(c
->buf
+ c
->length
+ 0) = type
;
1152 *(char *)(c
->buf
+ c
->length
+ 1) = identifier
;
1153 *(u16
*)(c
->buf
+ c
->length
+ 2) = ntohs(4);
1159 controlt
*ppp_pap(u16 s
, unsigned char type
, char identifier
, char *username
, char *password
)
1163 if (!identifier
) identifier
= ss
->sessions
[s
].ppp_identifier
++;
1164 c
= ppp_new(s
, PPPPAP
);
1165 *(char *)(c
->buf
+ c
->length
+ 0) = type
;
1166 *(char *)(c
->buf
+ c
->length
+ 1) = identifier
;
1167 *(u16
*)(c
->buf
+ c
->length
+ 2) = ntohs(4);
1170 *(char *)(c
->buf
+ c
->length
) = strlen(username
) + strlen(suffix
);
1171 memcpy((c
->buf
+ c
->length
+ 1), username
, strlen(username
));
1172 memcpy((c
->buf
+ c
->length
+ 1 + strlen(username
)), suffix
, strlen(suffix
));
1173 c
->length
+= strlen(username
) + 1 + strlen(suffix
);
1175 *(char *)(c
->buf
+ c
->length
) = strlen(password
);
1176 memcpy((c
->buf
+ c
->length
+ 1), password
, strlen(password
));
1177 c
->length
+= strlen(password
) + 1;
1182 void ppp_send(controlt
*c
)
1184 *(u16
*)(c
->buf
+ 0) = htons(0x0002); // flags/ver
1185 *(u16
*)(c
->buf
+ 2) = htons(t
); // tunnel
1186 *(u16
*)(c
->buf
+ 10) = ntohs(c
->length
- 8);
1187 if (sendto(udpfd
, c
->buf
, c
->length
, 0, (struct sockaddr
*)&gatewayaddr
, sizeof(gatewayaddr
)) < 0)
1189 if (htons(*(u16
*)(c
->buf
+ 6)) != PPPIP
)
1191 printf("PPP Sending ");
1192 dump_ppp_packet(c
->buf
+ 6, c
->length
- 6);
1196 void ppp_add_16(controlt
*c
, u16 val
)
1198 *(u16
*) (c
->buf
+ c
->length
) = htons(val
);
1202 void ppp_add_32(controlt
*c
, u32 val
)
1204 *(u32
*) (c
->buf
+ c
->length
) = htons(val
);
1208 void ppp_add_s(controlt
*c
, char *val
)
1210 memcpy(c
->buf
+ c
->length
, val
, strlen(val
));
1211 c
->length
+= strlen(val
);
1214 void ppp_lcp_add_option(controlt
*c
, unsigned char option
, unsigned char length
, int data
)
1216 *(char *)(c
->buf
+ c
->length
+ 0) = option
;
1217 *(char *)(c
->buf
+ c
->length
+ 1) = length
+ 2;
1218 memcpy(c
->buf
+ c
->length
+ 2, &data
, length
);
1219 c
->length
+= 2 + length
;
1222 void dump_ppp_packet(char *packet
, int l
)
1226 if (*(unsigned char *)p
== 0xff) p
+= 2;
1227 protocol
= ntohs(*(u16
*)(p
));
1228 printf("PPP Packet\n");
1231 case PPPCCP
: printf(" Protocol: PPPCCP\n"); break;
1233 if (protocol
== PPPLCP
)
1235 printf(" Protocol: PPPLCP\n");
1236 printf(" LCP Code: %s\n", lcp_codes
[*(u8
*)(p
+ 2)]);
1238 else if (protocol
== PPPPAP
)
1240 printf(" Protocol: PPPPAP\n");
1241 if (*(char *)(p
+ 2) == 2)
1243 printf(" Authentication accepted\n");
1245 else if (*(char *)(p
+ 2) == 3)
1247 printf(" Authentication denied\n");
1250 else if (protocol
== PPPIPCP
)
1252 printf(" Protocol: PPPIPCP\n");
1253 printf(" IPCP Code: %s\n", lcp_codes
[*(u8
*)(p
+ 2)]);
1254 printf(" Address: %s\n", inet_toa(*(u32
*)(p
+ 8)));
1256 else if (protocol
== PPPIP
)
1259 struct protoent
*pr
;
1261 iph
= (struct iphdr
*)(p
+ 2);
1263 printf(" Protocol: PPPIP\n");
1264 printf(" Length: %d\n", l
);
1265 printf(" IP Version: %d\n", iph
->version
);
1266 if (iph
->version
!= 4) return;
1267 pr
= getprotobynumber(iph
->protocol
);
1268 printf(" IP Header Length: %d\n", iph
->ihl
);
1269 printf(" IP TTL: %d\n", iph
->ttl
);
1270 printf(" IP Protocol: %s (%d)\n", (pr
? pr
->p_name
: "unknown"), iph
->protocol
);
1271 printf(" IP Checksum: %x\n", ntohs(iph
->check
));
1275 printf(" Protocol: unknown 0x%x\n", protocol
);
1280 char *inet_toa(unsigned long addr
)
1283 memcpy(&in
, &addr
, sizeof(unsigned long));
1284 return inet_ntoa(in
);