blob: e00168c8ee25b4fb5e9ec3fab020e6ddab6115ec [file] [log] [blame]
jjako52c24142002-12-16 13:33:51 +00001/*
2 * OpenGGSN - Gateway GPRS Support Node
3 * Copyright (C) 2002 Mondru AB.
4 *
5 * The contents of this file may be used under the terms of the GNU
6 * General Public License Version 2, provided that the above copyright
7 * notice and this permission notice is included in all copies or
8 * substantial portions of the software.
9 *
10 * The initial developer of the original code is
11 * Jens Jakobsen <jj@openggsn.org>
12 *
13 * Contributor(s):
14 *
15 */
16
17/*
18 * gtp.c: Contains all GTP functionality. Should be able to handle multiple
19 * tunnels in the same program.
20 *
21 * TODO:
22 * - Do we need to handle fragmentation?
23 */
24
25
26#ifdef __linux__
27#define _GNU_SOURCE 1
28#endif
29
30
31#include <syslog.h>
32#include <stdio.h>
33#include <stdarg.h>
34#include <stdlib.h>
35#include <sys/time.h>
36#include <sys/types.h>
37#include <sys/socket.h>
38#include <netinet/in.h>
39#include <arpa/inet.h>
40#include <sys/stat.h>
41#include <time.h>
42#include <unistd.h>
43#include <string.h>
44#include <errno.h>
45#include <fcntl.h>
46
47#include <arpa/inet.h>
48
49#include <stdint.h> /* ISO C99 types */
50
51#include "pdp.h"
52#include "gtp.h"
53#include "gtpie.h"
54#include "queue.h"
55
56
57struct gtp0_header gtp0_default;
58struct gtp1_header_long gtp1_default;
59
60/* API Functions */
61
62const char* gtp_version()
63{
64 return VERSION;
65}
66
67/* gtp_new */
68/* gtp_free */
69
70int gtp_newpdp(struct gsn_t* gsn, struct pdp_t **pdp,
71 uint64_t imsi, uint8_t nsapi) {
72 return pdp_newpdp(pdp, imsi, nsapi, NULL);
73}
74
75int gtp_freepdp(struct gsn_t* gsn, struct pdp_t *pdp) {
76 return pdp_freepdp(pdp);
77}
78
79int gtp_create_context(struct gsn_t *gsn, struct pdp_t *pdp, void *aid,
80 struct in_addr* inetaddr) {
81 int version = 0;
82
83 return gtp_create_pdp_req(gsn, version, aid, inetaddr, pdp);
84}
85
86int gtp_update_context(struct gsn_t *gsn, struct pdp_t *pdp, void *aid,
87 struct in_addr* inetaddr) {
88 int version = 0;
89
90 return gtp_update_pdp_req(gsn, version, aid, inetaddr, pdp);
91}
92
93int gtp_delete_context(struct gsn_t *gsn, struct pdp_t *pdp, void *aid) {
94 int version = 0;
95 return gtp_delete_pdp_req(gsn, version, aid, pdp);
96}
97
98/* gtp_gpdu */
99
100extern int gtp_fd(struct gsn_t *gsn) {
101 return gsn->fd;
102}
103
104/* gtp_decaps */
105/* gtp_retrans */
106/* gtp_retranstimeout */
107
108int gtp_set_cb_delete_context(struct gsn_t *gsn,
109 int (*cb_delete_context) (struct pdp_t* pdp))
110{
111 gsn->cb_delete_context = cb_delete_context;
112 return 0;
113}
114
115int gtp_set_cb_create_context(struct gsn_t *gsn,
116 int (*cb_create_context) (struct pdp_t* pdp))
117{
118 gsn->cb_create_context = cb_create_context;
119 return 0;
120}
121
122/*
123
124 int gtp_set_cb_create_pdp_conf(struct gsn_t *gsn,
125 int (*cb) (struct pdp_t*, int))
126 {
127 gsn->cb_create_pdp_conf = cb;
128 return 0;
129 }
130
131 int gtp_set_cb_update_pdp_conf(struct gsn_t *gsn,
132 int (*cb) (struct pdp_t*, int, int))
133 {
134 gsn->cb_update_pdp_conf = cb;
135 return 0;
136}
137
138in t gtp_set_cb_delete_pdp_conf(struct gsn_t *gsn,
139int (*cb) (struct pdp_t*, int))
140 {
141gsn->cb_delete_pdp_conf = cb;
142return 0;
143}
144
145*/
146
147int gtp_set_cb_conf(struct gsn_t *gsn,
148 int (*cb) (int type, int cause,
149 struct pdp_t* pdp, void *aid)) {
150 gsn->cb_conf = cb;
151 return 0;
152}
153
154extern int gtp_set_cb_gpdu(struct gsn_t *gsn,
155 int (*cb_gpdu) (struct pdp_t* pdp,
156 void* pack,
157 unsigned len))
158{
159 gsn->cb_gpdu = cb_gpdu;
160 return 0;
161}
162
163
164
165void get_default_gtp(int version, void *packet) {
166 switch (version) {
167 case 0:
168 memcpy(packet, &gtp0_default, sizeof(gtp0_default));
169 break;
170 case 1:
171 memcpy(packet, &gtp1_default, sizeof(gtp1_default));
172 break;
173 }
174}
175
176int print_packet(void *packet, unsigned len)
177{
178 int i;
179 printf("The packet looks like this (%d bytes):\n", len);
180 for( i=0; i<len; i++) {
181 printf("%02x ", (unsigned char)*(char *)(packet+i));
182 if (!((i+1)%16)) printf("\n");
183 };
184 printf("\n");
185 return 0;
186}
187
188char* snprint_packet(struct gsn_t *gsn, struct sockaddr_in *peer,
189 void *pack, unsigned len, char *buf, int size) {
190 int n;
191 int pos;
192 snprintf(buf, size, "Packet from %s:%u, length: %d, content:",
193 inet_ntoa(peer->sin_addr),
194 ntohs(peer->sin_port),
195 len);
196 pos = strlen(buf);
197 for(n=0; n<len; n++) {
198 if ((pos+4)<size) {
199 sprintf((buf+pos), " %02hhx", ((unsigned char*)pack)[n]);
200 pos += 3;
201 }
202 }
203 buf[pos] = 0;
204 return buf;
205}
206
207void gtp_err(int priority, char *filename, int linenum, char *fmt, ...) {
208 va_list args;
209 char buf[ERRMSG_SIZE];
210
211 va_start(args, fmt);
212 vsnprintf(buf, ERRMSG_SIZE, fmt, args);
213 va_end(args);
214
215 syslog(priority, "%s: %d: %s", filename, linenum, buf);
216}
217
218void gtp_errpack(int pri, char *fn, int ln, struct sockaddr_in *peer,
219 void *pack, unsigned len, char *fmt, ...) {
220
221 va_list args;
222 char buf[ERRMSG_SIZE];
223 char buf2[ERRMSG_SIZE];
224 int n;
225 int pos;
226
227 va_start(args, fmt);
228 vsnprintf(buf, ERRMSG_SIZE, fmt, args);
229 va_end(args);
230
231 snprintf(buf2, ERRMSG_SIZE, "Packet from %s:%u, length: %d, content:",
232 inet_ntoa(peer->sin_addr),
233 ntohs(peer->sin_port),
234 len);
235 pos = strlen(buf2);
236 for(n=0; n<len; n++) {
237 if ((pos+4)<ERRMSG_SIZE) {
238 sprintf((buf2+pos), " %02hhx", ((unsigned char*)pack)[n]);
239 pos += 3;
240 }
241 }
242 buf2[pos] = 0;
243
244 syslog(pri, "%s: %d: %s. %s", fn, ln, buf, buf2);
245
246}
247
248
249/* ***********************************************************
250 * Reliable delivery of signalling messages
251 *
252 * Sequence numbers are used for both signalling messages and
253 * data messages.
254 *
255 * For data messages each tunnel maintains a sequence counter,
256 * which is incremented by one each time a new data message
257 * is sent. The sequence number starts at (0) zero at tunnel
258 * establishment, and wraps around at 65535 (29.060 9.3.1.1
259 * and 09.60 8.1.1.1). The sequence numbers are either ignored,
260 * or can be used to check the validity of the message in the
261 * receiver, or for reordering af packets.
262 *
263 * For signalling messages the sequence number is used by
264 * signalling messages for which a response is defined. A response
265 * message should copy the sequence from the corresponding request
266 * message. The sequence number "unambiguously" identifies a request
267 * message within a given path, with a path being defined as a set of
268 * two endpoints (29.060 8.2, 29.060 7.6, 09.60 7.8). "All request
269 * messages shall be responded to, and all response messages associated
270 * with a certain request shall always include the same information"
271 *
272 * We take this to mean that the GSN transmitting a request is free to
273 * choose the sequence number, as long as it is unique within a given path.
274 * It means that we are allowed to count backwards, or roll over at 17
275 * if we prefer that. It also means that we can use the same counter for
276 * all paths. This has the advantage that the transmitted request sequence
277 * numbers are unique within each GSN, and also we dont have to mess around
278 * with path setup and teardown.
279 *
280 * If a response message is lost, the request will be retransmitted, and
281 * the receiving GSN will receive a "duplicated" request. The standard
282 * requires the receiving GSN to send a response, with the same information
283 * as in the original response. For most messages this happens automatically:
284 *
285 * Echo: Automatically dublicates the original response
286 * Create pdp context: The SGSN may send create context request even if
287 * a context allready exist (imsi+nsapi?). This means that the reply will
288 automatically dublicate the original response. It might however have
289 * sideeffects in the application which is asked twice to allocate
290 * validate the login.
291 * Update pdp context: Automatically dublicates the original response???
292 * Delete pdp context. Automatically in gtp0, but in gtp1 will generate
293 * a nonexist reply message.
294 *
295 * The correct solution will be to make a queue containing response messages.
296 * This queue should be checked whenever a request is received. If the
297 * response is allready in the queue that response should be transmitted.
298 * It should be possible to find messages in this queue on the basis of
299 * the sequence number and peer GSN IP address (The sequense number is unique
300 * within each path). This need to be implemented by a hash table. Furthermore
301 * it should be possibly to delete messages based on a timeout. This can be
302 * achieved by means of a linked list. The timeout value need to be larger
303 * than T3-RESPONSE * N3-REQUESTS (recommended value 5). These timers are
304 * set in the peer GSN, so there is no way to know these parameters. On the
305 * other hand the timeout value need to be so small that we do not receive
306 * wraparound sequence numbere before the message is deleted. 60 seconds is
307 * probably not a bad choise.
308 *
309 * This queue however is first really needed from gtp1.
310 *
311 * gtp_req:
312 * Send off a signalling message with appropiate sequence
313 * number. Store packet in queue.
314 * gtp_conf:
315 * Remove an incoming confirmation from the queue
316 * gtp_resp:
317 * Send off a responce to a request. Use the same sequence
318 * number in the response as in the request.
319 * gtp_retrans:
320 * Retransmit any outstanding packets which have exceeded
321 * a predefined timeout.
322 *************************************************************/
323
324int gtp_req(struct gsn_t *gsn, int version, union gtp_packet *packet,
325 int len, struct in_addr *inetaddr, void *aid) {
326 struct sockaddr_in addr;
327 struct qmsg_t *qmsg;
328 memset(&addr, 0, sizeof(addr));
329 addr.sin_family = AF_INET;
330 addr.sin_addr = *inetaddr;
331 addr.sin_port = htons(GTP0_PORT);
332
333 packet->gtp0.h.seq = hton16(gsn->seq_next);
334
335 if (sendto(gsn->fd, packet, len, 0,
336 (struct sockaddr *) &addr, sizeof(addr)) < 0) {
337 gsn->err_sendto++;
338 gtp_err(LOG_ERR, __FILE__, __LINE__, "Sendto(fd=%d, msg=%lx, len=%d) failed: Error = %s", gsn->fd, (unsigned long) &packet, len, strerror(errno));
339 return -1;
340 }
341
342 /* Use new queue structure */
343 if (queue_newmsg(gsn->queue_req, &qmsg, &addr, gsn->seq_next)) {
344 gsn->err_queuefull++;
345 gtp_err(LOG_ERR, __FILE__, __LINE__, "Retransmit queue is full");
346 }
347 else {
348 memcpy(&qmsg->p, packet, sizeof(union gtp_packet));
349 qmsg->l = len;
350 qmsg->timeout = time(NULL) + 3; /* When to timeout */
351 qmsg->retrans = 0; /* No retransmissions so far */
352 qmsg->aid = aid;
353 qmsg->type = ntoh8(packet->gtp0.h.type);
354 }
355 gsn->seq_next++; /* Count up this time */
356 return 0;
357}
358
359/* gtp_conf
360 * Remove signalling packet from retransmission queue.
361 * return 0 on success, EOF if packet was not found */
362
363int gtp_conf(struct gsn_t *gsn, int version, struct sockaddr_in *peer,
364 union gtp_packet *packet, int len, uint8_t *type, void **aid) {
365 int seq = ntoh16(packet->gtp0.h.seq);
366
367 if (queue_freemsg_seq(gsn->queue_req, peer, seq, type, aid)) {
368 gsn->err_seq++;
369 gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, packet, len,
370 "Confirmation packet not found in queue");
371 return EOF;
372 }
373
374 return 0;
375}
376
377int gtp_retrans(struct gsn_t *gsn) {
378 /* Retransmit any outstanding packets */
379 /* Remove from queue if maxretrans exceeded */
380 time_t now;
381 struct qmsg_t *qmsg;
382 now = time(NULL);
383 /*printf("Retrans: New beginning %d\n", (int) now);*/
384
385 while ((!queue_getfirst(gsn->queue_req, &qmsg)) &&
386 (qmsg->timeout <= now)) {
387 /*printf("Retrans timeout found: %d\n", (int) time(NULL));*/
388 if (qmsg->retrans > 3) { /* To many retrans */
389 if (gsn->cb_conf) gsn->cb_conf(qmsg->type, EOF, NULL, qmsg->aid);
390 queue_freemsg(gsn->queue_req, qmsg);
391 }
392 else {
393 if (sendto(gsn->fd, &qmsg->p, qmsg->l, 0,
394 (struct sockaddr *) &qmsg->peer, sizeof(struct sockaddr_in)) < 0) {
395 gsn->err_sendto++;
396 gtp_err(LOG_ERR, __FILE__, __LINE__, "Sendto(fd=%d, msg=%lx, len=%d) failed: Error = %s", gsn->fd, (unsigned long) &qmsg->p, qmsg->l, strerror(errno));
397 }
398 queue_back(gsn->queue_req, qmsg);
399 qmsg->timeout = now + 3;
400 qmsg->retrans++;
401 }
402 }
403
404 /* Also clean up reply timeouts */
405 while ((!queue_getfirst(gsn->queue_resp, &qmsg)) &&
406 (qmsg->timeout < now)) {
407 /*printf("Retrans (reply) timeout found: %d\n", (int) time(NULL));*/
408 queue_freemsg(gsn->queue_resp, qmsg);
409 }
410
411 return 0;
412}
413
414int gtp_retranstimeout(struct gsn_t *gsn, struct timeval *timeout) {
415 time_t now, later;
416 struct qmsg_t *qmsg;
417
418 if (queue_getfirst(gsn->queue_req, &qmsg)) {
419 timeout->tv_sec = 10;
420 timeout->tv_usec = 0;
421 }
422 else {
423 now = time(NULL);
424 later = qmsg->timeout;
425 timeout->tv_sec = later - now;
426 timeout->tv_usec = 0;
427 if (timeout->tv_sec < 0) timeout->tv_sec = 0; /* No negative allowed */
428 if (timeout->tv_sec > 10) timeout->tv_sec = 10; /* Max sleep for 10 sec*/
429 }
430 return 0;
431}
432
433int gtp_resp(int version, struct gsn_t *gsn, union gtp_packet *packet,
434 int len, struct sockaddr_in *peer) {
435 struct qmsg_t *qmsg;
436 uint16_t seq;
437
438 seq = ntoh16(packet->gtp0.h.seq);
439
440 /* print message */
441 /*
442 printf("gtp_resp: to %s:UDP%u\n",
443 inet_ntoa(peer->sin_addr),
444 ntohs(peer->sin_port));
445 print_packet(packet, len);
446 */
447
448 if (sendto(gsn->fd, packet, len, 0,
449 (struct sockaddr *) peer, sizeof(struct sockaddr_in)) < 0) {
450 gsn->err_sendto++;
451 gtp_err(LOG_ERR, __FILE__, __LINE__, "Sendto(fd=%d, msg=%lx, len=%d) failed: Error = %s", gsn->fd, (unsigned long) &packet, len, strerror(errno));
452 return -1;
453 }
454
455 /* Use new queue structure */
456 if (queue_newmsg(gsn->queue_resp, &qmsg, peer, seq)) {
457 gsn->err_queuefull++;
458 gtp_err(LOG_ERR, __FILE__, __LINE__, "Retransmit queue is full");
459 }
460 else {
461 memcpy(&qmsg->p, packet, sizeof(union gtp_packet));
462 qmsg->l = len;
463 qmsg->timeout = time(NULL) + 60; /* When to timeout */
464 qmsg->retrans = 0; /* No retransmissions so far */
465 qmsg->aid = NULL;
466 qmsg->type = 0;
467 }
468 return 0;
469}
470
471int gtp_dublicate(struct gsn_t *gsn, int version,
472 struct sockaddr_in *peer, uint16_t seq) {
473 struct qmsg_t *qmsg;
474
475 if(queue_seqget(gsn->queue_resp, &qmsg, peer, seq)) {
476 return EOF; /* Notfound */
477 }
478 else {
479 /* print message */
480
481 /*printf("gtp_dublicate: to %s:UDP%u\n",
482 inet_ntoa(peer->sin_addr),
483 ntohs(peer->sin_port));
484 print_packet(&qmsg->p, qmsg->l);
485 */
486 if (sendto(gsn->fd, &qmsg->p, qmsg->l, 0,
487 (struct sockaddr *) peer, sizeof(struct sockaddr_in)) < 0) {
488 gsn->err_sendto++;
489 gtp_err(LOG_ERR, __FILE__, __LINE__, "Sendto(fd=%d, msg=%lx, len=%d) failed: Error = %s", gsn->fd, (unsigned long) &qmsg->p, qmsg->l, strerror(errno));
490 }
491 return 0;
492 }
493}
494
495
496
497/* Perform restoration and recovery error handling as described in 29.060 */
498static void log_restart(struct gsn_t *gsn) {
499 FILE *f;
500 int i;
501 int counter = 0;
502 char filename[NAMESIZE];
503
504 filename[NAMESIZE-1] = 0; /* No null term. guarantee by strncpy */
505 strncpy(filename, gsn->statedir, NAMESIZE-1);
506 strncat(filename, RESTART_FILE,
507 NAMESIZE-1-sizeof(RESTART_FILE));
508
509 i = umask(022);
510
511 /* We try to open file. On failure we will later try to create file */
512 if (!(f = fopen(filename, "r"))) {
513 gtp_err(LOG_ERR, __FILE__, __LINE__, "fopen(path=%s, mode=%s) failed: Error = %s", filename, "r", strerror(errno));
514 }
515 else {
516 umask(i);
517 fscanf(f, "%d", &counter);
518 if (fclose(f)) {
519 gtp_err(LOG_ERR, __FILE__, __LINE__, "fclose failed: Error = %s", strerror(errno));
520 }
521 }
522
523 gsn->restart_counter = (unsigned char) counter;
524 gsn->restart_counter++;
525
526 if (!(f = fopen(filename, "w"))) {
527 gtp_err(LOG_ERR, __FILE__, __LINE__, "fopen(path=%s, mode=%s) failed: Error = %s", filename, "w", strerror(errno));
528 return;
529 }
530
531 umask(i);
532 fprintf(f, "%d\n", gsn->restart_counter);
533 if (fclose(f)) {
534 gtp_err(LOG_ERR, __FILE__, __LINE__, "fclose failed: Error = %s", strerror(errno));
535 return;
536 }
537}
538
539
540
541int gtp_new(struct gsn_t **gsn, char *statedir, struct in_addr *listen)
542{
543 struct sockaddr_in addr;
544 int gtp_fd;
545
546 syslog(LOG_ERR, "GTP: gtp_newgsn() started");
547
548 *gsn = calloc(sizeof(struct gsn_t), 1); /* TODO */
549
550 (*gsn)->statedir = statedir;
551 log_restart(*gsn);
552
553 /* Initialise request retransmit queue */
554 queue_new(&(*gsn)->queue_req);
555 queue_new(&(*gsn)->queue_resp);
556
557 /* Initialise pdp table */
558 pdp_init();
559
560 /* Initialise call back functions */
561 (*gsn)->cb_create_context = 0;
562 (*gsn)->cb_delete_context = 0;
563 (*gsn)->cb_conf = 0;
564 (*gsn)->cb_gpdu = 0;
565
566 if ((gtp_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
567 (*gsn)->err_socket++;
568 gtp_err(LOG_ERR, __FILE__, __LINE__, "socket(domain=%d, type=%d, protocol=%d) failed: Error = %s", AF_INET, SOCK_DGRAM, 0, strerror(errno));
569 return -1;
570 }
571 (*gsn)->fd = gtp_fd;
572
573 /* syslog(LOG_ERR, "GTP: gtp_init() after socket");*/
574
575 (*gsn)->gsnc = *listen;
576 (*gsn)->gsnu = *listen;
577
578 memset(&addr, 0, sizeof(addr));
579
580 addr.sin_family = AF_INET;
581 /* addr.sin_addr = *inetaddr; */
582 addr.sin_addr = *listen; /* Same IP for user traffic and signalling*/
583 addr.sin_port = htons(GTP0_PORT);
584
585 if (bind(gtp_fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
586 (*gsn)->err_socket++;
587 gtp_err(LOG_ERR, __FILE__, __LINE__, "bind(fd=%d, addr=%lx, len=%d) failed: Error = %s", gtp_fd, (unsigned long) &addr, sizeof(addr), strerror(errno));
588 return -1;
589 }
590
591 /* Initialise "standard" GTP0 header */
592 memset(&gtp0_default, 0, sizeof(gtp0_default));
593 gtp0_default.flags=0x1e;
594 gtp0_default.spare1=0xff;
595 gtp0_default.spare2=0xff;
596 gtp0_default.spare3=0xff;
597 gtp0_default.number=0xff;
598
599 /* Initialise "standard" GTP1 header */
600 memset(&gtp1_default, 0, sizeof(gtp1_default));
601 gtp0_default.flags=0x1e;
602
603 return 0;
604}
605
606int gtp_free(struct gsn_t *gsn) {
607
608 /* Clean up retransmit queues */
609 queue_free(gsn->queue_req);
610 queue_free(gsn->queue_resp);
611
612 free(gsn);
613 return 0;
614}
615
616/* ***********************************************************
617 * Path management messages
618 * Messages: echo and version not supported.
619 * A path is connection between two UDP/IP endpoints
620 *
621 * A path is either using GTP0 or GTP1. A path can be
622 * established by any kind of GTP message??
623
624 * Which source port to use?
625 * GTP-C request destination port is 2123/3386
626 * GTP-U request destination port is 2152/3386
627 * T-PDU destination port is 2152/3386.
628 * For the above messages the source port is locally allocated.
629 * For response messages src=rx-dst and dst=rx-src.
630 * For simplicity we should probably use 2123+2152/3386 as
631 * src port even for the cases where src can be locally
632 * allocated. This also means that we have to listen only to
633 * the same ports.
634 * For response messages we need to be able to respond to
635 * the relevant src port even if it is locally allocated by
636 * the peer.
637 *
638 * The need for path management!
639 * We might need to keep a list of active paths. This might
640 * be in the form of remote IP address + UDP port numbers.
641 * (We will consider a path astablished if we have a context
642 * with the node in question)
643 *************************************************************/
644
645/* Send off an echo request */
646int gtp_echo_req(struct gsn_t *gsn, struct in_addr *inetaddr)
647{
648 union gtp_packet packet;
649
650 get_default_gtp(0, &packet);
651 packet.gtp0.h.type = hton8(GTP_ECHO_REQ);
652 packet.gtp0.h.length = hton16(0);
653
654 return gtp_req(gsn, 0, &packet, GTP0_HEADER_SIZE, inetaddr, NULL);
655}
656
657/* Send of an echo reply */
658int gtp_echo_resp(struct gsn_t *gsn, struct sockaddr_in *peer,
659 void *pack, unsigned len)
660{
661 union gtp_packet packet;
662 int length = 0;
663
664 get_default_gtp(0, &packet);
665
666 gtpie_tv1(packet.gtp0.p, &length, GTP_MAX, GTPIE_RECOVERY,
667 gsn->restart_counter);
668
669 packet.gtp0.h.type = hton8(GTP_ECHO_RSP);
670 packet.gtp0.h.length = hton16(length);
671 packet.gtp0.h.seq = ((union gtp_packet*)pack)->gtp0.h.seq;
672
673 return gtp_resp(0, gsn, &packet, GTP0_HEADER_SIZE+length, peer);
674}
675
676
677/* Handle a received echo request */
678int gtp_echo_ind(struct gsn_t *gsn, struct sockaddr_in *peer,
679 void *pack, unsigned len) {
680
681 uint16_t seq = ntoh16(((union gtp_packet*)pack)->gtp0.h.seq);
682
683 if(!gtp_dublicate(gsn, 0, peer, seq)) {
684 return 0; /* We allready send of response once */
685 }
686
687
688 /* Now send off a reply to the peer */
689 return gtp_echo_resp(gsn, peer, pack, len);
690}
691
692/* Handle a received echo reply */
693int gtp_echo_conf(struct gsn_t *gsn, struct sockaddr_in *peer,
694 void *pack, unsigned len) {
695 union gtpie_member *ie[GTPIE_SIZE];
696 unsigned char recovery;
697 void *aid = NULL;
698 uint8_t type = 0;
699
700 /* Remove packet from queue */
701 if (gtp_conf(gsn, 0, peer, pack, len, &type, &aid)) return EOF;
702
703 if (gtpie_decaps(ie, pack+sizeof(struct gtp0_header), len-sizeof(struct gtp0_header))) {
704 gsn->invalid++;
705 gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
706 "Invalid message format");
707 return EOF;
708 }
709
710 if (gtpie_gettv1(ie, GTPIE_RECOVERY, 0, &recovery)) {
711 gsn->missing++;
712 gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
713 "Missing mandatory field");
714 return EOF;
715 }
716
717 if (gsn->cb_conf) gsn->cb_conf(type, 0, NULL, aid); /* TODO: Should return recovery in callback */
718
719 return 0;
720}
721
722/* Send off a Version Not Supported message */
723/* This message is somewhat special in that it actually is a
724 * response to some other message with unsupported GTP version
725 * For this reason it has parameters like a response, and does
726 * its own message transmission. No signalling queue is used
727 * The reply is sent to the peer IP and peer UDP. This means that
728 * the peer will be receiving a GTP0 message on a GTP1 port!
729 * In practice however this will never happen as a GTP0 GSN will
730 * only listen to the GTP0 port, and therefore will never receive
731 * anything else than GTP0 */
732
733int gtp_unsup_resp(struct gsn_t *gsn, struct sockaddr_in *peer,
734 void *pack, unsigned len)
735{
736 union gtp_packet packet;
737 int length = 0;
738
739 get_default_gtp(0, &packet);
740 packet.gtp0.h.type = hton8(GTP_NOT_SUPPORTED);
741 packet.gtp0.h.length = hton16(0);
742
743 return gtp_resp(0, gsn, &packet, GTP0_HEADER_SIZE+length, peer);
744}
745
746/* Handle a Version Not Supported message */
747int gtp_unsup_conf(struct gsn_t *gsn, struct sockaddr_in *peer, void *pack, unsigned len) {
748
749 /* TODO: Need to check the validity of header and information elements */
750 /* TODO: Implement callback to application */
751 /* As long as we only support GTP0 we should never receive this message */
752 /* Should be implemented as part of GTP1 support */
753
754 /* print received message */
755 /*
756 printf("gtp_unsup_ind: from %s:UDP%u\n",
757 inet_ntoa(peer->sin_addr),
758 ntohs(peer->sin_port));
759 print_packet(pack, len);
760 */
761 return 0;
762}
763
764/* ***********************************************************
765 * Session management messages
766 * Messages: create, update and delete PDP context
767 *
768 * Information storage
769 * Information storage for each PDP context is defined in
770 * 23.060 section 13.3. Includes IMSI, MSISDN, APN, PDP-type,
771 * PDP-address (IP address), sequence numbers, charging ID.
772 * For the SGSN it also includes radio related mobility
773 * information.
774 *************************************************************/
775
776/* Send Create PDP Context Request */
777extern int gtp_create_pdp_req(struct gsn_t *gsn, int version, void *aid,
778 struct in_addr* inetaddr, struct pdp_t *pdp) {
779 union gtp_packet packet;
780 int length = 0;
781
782 get_default_gtp(0, &packet);
783
784 if (0==0) { /* Always GTP0 */
785
786 gtpie_tv0(packet.gtp0.p, &length, GTP_MAX, GTPIE_QOS_PROFILE0,
787 sizeof(pdp->qos_req0), pdp->qos_req0);
788 gtpie_tv1(packet.gtp0.p, &length, GTP_MAX, GTPIE_RECOVERY,
789 gsn->restart_counter);
790 gtpie_tv1(packet.gtp0.p, &length, GTP_MAX, GTPIE_SELECTION_MODE,
791 pdp->selmode);
792 gtpie_tv2(packet.gtp0.p, &length, GTP_MAX, GTPIE_FL_DI,
793 pdp->fllu);
794 gtpie_tv2(packet.gtp0.p, &length, GTP_MAX, GTPIE_FL_C,
795 pdp->fllc);
796 gtpie_tlv(packet.gtp0.p, &length, GTP_MAX, GTPIE_EUA,
797 pdp->eua.l, pdp->eua.v);
798 gtpie_tlv(packet.gtp0.p, &length, GTP_MAX, GTPIE_APN,
799 pdp->apn_use.l, pdp->apn_use.v);
800
801 if (pdp->pco_req.l) { /* Optional PCO */
802 gtpie_tlv(packet.gtp0.p, &length, GTP_MAX, GTPIE_PCO,
803 pdp->pco_req.l, pdp->pco_req.v);
804 }
805
806 gtpie_tlv(packet.gtp0.p, &length, GTP_MAX, GTPIE_GSN_ADDR,
807 pdp->gsnlc.l, pdp->gsnlc.v);
808 gtpie_tlv(packet.gtp0.p, &length, GTP_MAX, GTPIE_GSN_ADDR,
809 pdp->gsnlu.l, pdp->gsnlu.v);
810 gtpie_tlv(packet.gtp0.p, &length, GTP_MAX, GTPIE_MSISDN,
811 pdp->msisdn.l, pdp->msisdn.v);
812
813
814
815 } else { /* GTP1 */
816 gtpie_tv0(packet.gtp1s.p, &length, GTP_MAX, GTPIE_IMSI,
817 sizeof(pdp->imsi), (uint8_t*) &pdp->imsi);
818 gtpie_tv1(packet.gtp1s.p, &length, GTP_MAX, GTPIE_RECOVERY,
819 gsn->restart_counter);
820 gtpie_tv1(packet.gtp1s.p, &length, GTP_MAX, GTPIE_SELECTION_MODE,
821 pdp->selmode);
822 gtpie_tv4(packet.gtp1s.p, &length, GTP_MAX, GTPIE_TEI_DI,
823 pdp->teid_own);
824 gtpie_tv4(packet.gtp1s.p, &length, GTP_MAX, GTPIE_TEI_C,
825 pdp->teic_own);
826 gtpie_tv1(packet.gtp1s.p, &length, GTP_MAX, GTPIE_NSAPI,
827 pdp->nsapi);
828 /*gtpie_tv1(packet.gtp1s.p, &length, GTP_MAX, GTPIE_NSAPI,
829 pdp->nsapil); For use by several QoS profiles for the same address */
830 gtpie_tv2(packet.gtp1s.p, &length, GTP_MAX, GTPIE_CHARGING_C,
831 pdp->cch_pdp);
832 gtpie_tv2(packet.gtp1s.p, &length, GTP_MAX, GTPIE_TRACE_REF,
833 pdp->traceref);
834 gtpie_tv2(packet.gtp1s.p, &length, GTP_MAX, GTPIE_TRACE_TYPE,
835 pdp->tracetype);
836 gtpie_tlv(packet.gtp1s.p, &length, GTP_MAX, GTPIE_EUA,
837 pdp->eua.l, pdp->eua.v);
838 gtpie_tlv(packet.gtp1s.p, &length, GTP_MAX, GTPIE_APN,
839 pdp->apn_use.l, pdp->apn_use.v);
840 gtpie_tlv(packet.gtp1s.p, &length, GTP_MAX, GTPIE_PCO,
841 pdp->pco_req.l, pdp->pco_req.v);
842 gtpie_tlv(packet.gtp1s.p, &length, GTP_MAX, GTPIE_GSN_ADDR,
843 pdp->gsnlc.l, pdp->gsnlc.v);
844 gtpie_tlv(packet.gtp1s.p, &length, GTP_MAX, GTPIE_GSN_ADDR,
845 pdp->gsnlu.l, pdp->gsnlu.v);
846 gtpie_tlv(packet.gtp1s.p, &length, GTP_MAX, GTPIE_MSISDN,
847 pdp->msisdn.l, pdp->msisdn.v);
848 gtpie_tlv(packet.gtp1s.p, &length, GTP_MAX, GTPIE_QOS_PROFILE,
849 pdp->qos_req.l, pdp->qos_req.v);
850 gtpie_tlv(packet.gtp1s.p, &length, GTP_MAX, GTPIE_TFT,
851 pdp->tft.l, pdp->tft.v);
852 gtpie_tlv(packet.gtp1s.p, &length, GTP_MAX, GTPIE_TRIGGER_ID,
853 pdp->triggerid.l, pdp->triggerid.v);
854 gtpie_tlv(packet.gtp1s.p, &length, GTP_MAX, GTPIE_OMC_ID,
855 pdp->omcid.l, pdp->omcid.v);
856 }
857 packet.gtp0.h.type = hton8(GTP_CREATE_PDP_REQ);
858 packet.gtp0.h.length = hton16(length);
859 packet.gtp0.h.flow = 0;
860 packet.gtp0.h.tid = pdp->tid;
861
862 gtp_req(gsn, 0, &packet, GTP0_HEADER_SIZE+length, inetaddr, aid);
863
864 return 0;
865}
866
867/* Send Create PDP Context Response */
868int gtp_create_pdp_resp(struct gsn_t *gsn, int version,
869 struct sockaddr_in *peer,
870 void *pack, unsigned len,
871 struct pdp_t *pdp, uint8_t cause)
872{
873 union gtp_packet packet;
874 int length = 0;
875
876 get_default_gtp(0, &packet);
877
878 gtpie_tv1(packet.gtp0.p, &length, GTP_MAX, GTPIE_CAUSE, cause);
879
880 if (cause == GTPCAUSE_ACC_REQ) {
881 gtpie_tv0(packet.gtp0.p, &length, GTP_MAX, GTPIE_QOS_PROFILE0,
882 sizeof(pdp->qos_neg0), pdp->qos_neg0);
883 gtpie_tv1(packet.gtp0.p, &length, GTP_MAX, GTPIE_REORDER,
884 pdp->reorder);
885 gtpie_tv1(packet.gtp0.p, &length, GTP_MAX, GTPIE_RECOVERY,
886 gsn->restart_counter);
887 gtpie_tv2(packet.gtp0.p, &length, GTP_MAX, GTPIE_FL_DI,
888 pdp->fllu);
889 gtpie_tv2(packet.gtp0.p, &length, GTP_MAX, GTPIE_FL_C,
890 pdp->fllc);
891 gtpie_tv4(packet.gtp0.p, &length, GTP_MAX, GTPIE_CHARGING_ID,
892 0x12345678);
893 gtpie_tlv(packet.gtp0.p, &length, GTP_MAX, GTPIE_EUA,
894 pdp->eua.l, pdp->eua.v);
895
896 if (pdp->pco_neg.l) { /* Optional PCO */
897 gtpie_tlv(packet.gtp0.p, &length, GTP_MAX, GTPIE_PCO,
898 pdp->pco_neg.l, pdp->pco_neg.v);
899 }
900
901 gtpie_tlv(packet.gtp0.p, &length, GTP_MAX, GTPIE_GSN_ADDR,
902 pdp->gsnlc.l, pdp->gsnlc.v);
903 gtpie_tlv(packet.gtp0.p, &length, GTP_MAX, GTPIE_GSN_ADDR,
904 pdp->gsnlu.l, pdp->gsnlu.v);
905 }
906
907 packet.gtp0.h.type = hton8(GTP_CREATE_PDP_RSP);
908 packet.gtp0.h.length = hton16(length);
909 packet.gtp0.h.flow = hton16(pdp->flrc);
910 packet.gtp0.h.seq = ((union gtp_packet*)pack)->gtp0.h.seq;
911 packet.gtp0.h.tid = ((union gtp_packet*)pack)->gtp0.h.tid;
912
913 return gtp_resp(0, gsn, &packet, GTP0_HEADER_SIZE+length, peer);
914}
915
916/* Handle Create PDP Context Request */
917int gtp_create_pdp_ind(struct gsn_t *gsn, int version,
918 struct sockaddr_in *peer, void *pack, unsigned len) {
919 struct pdp_t *pdp, *pdp_old;
920 struct pdp_t pdp_buf;
921 union gtpie_member* ie[GTPIE_SIZE];
922 uint8_t recovery;
923 uint64_t imsi;
924 uint8_t nsapi;
925 int auth = 0; /* Allow access if no callback is defined */
926
927 uint16_t seq = ntoh16(((union gtp_packet*)pack)->gtp0.h.seq);
928
929 if(!gtp_dublicate(gsn, 0, peer, seq)) {
930 return 0; /* We allready send of response once */
931 }
932
933 /* Decode information elements */
934 if (gtpie_decaps(ie, pack+GTP0_HEADER_SIZE, len-GTP0_HEADER_SIZE)) {
935 gsn->invalid++;
936 gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
937 "Invalid message format");
938 if (0 == version)
939 return EOF;
940 else
941 return gtp_create_pdp_resp(gsn, version, peer, pack, len, pdp,
942 GTPCAUSE_INVALID_MESSAGE);
943 }
944
945 pdp = &pdp_buf;
946 memset(pdp, 0, sizeof(struct pdp_t));
947
948 /* Extract IMSI and NSAPI from header */
949 imsi = ((union gtp_packet*)pack)->gtp0.h.tid & 0x0fffffffffffffff;
950 nsapi = (((union gtp_packet*)pack)->gtp0.h.tid & 0xf000000000000000) >> 60;
951
952 /* pdp_newpdp(&pdp, imsi, nsapi); TODO: Need to remove again */
953
954 if (gtpie_gettv0(ie, GTPIE_QOS_PROFILE0, 0,
955 pdp->qos_req0, sizeof(pdp->qos_req0))) {
956 gsn->missing++;
957 gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
958 "Missing mandatory information field");
959 return gtp_create_pdp_resp(gsn, version, peer, pack, len, pdp,
960 GTPCAUSE_MAN_IE_MISSING);
961 }
962
963 /* Extract recovery (optional) */
964 if (!gtpie_gettv1(ie, GTPIE_RECOVERY, 0, &recovery)) {
965 /* TODO: Handle received recovery IE */
966 }
967
968 if (gtpie_gettv0(ie, GTPIE_SELECTION_MODE, 0,
969 &pdp->selmode, sizeof(pdp->selmode))) {
970 gsn->missing++;
971 gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
972 "Missing mandatory information field");
973 return gtp_create_pdp_resp(gsn, version, peer, pack, len, pdp,
974 GTPCAUSE_MAN_IE_MISSING);
975 }
976
977 if (gtpie_gettv2(ie, GTPIE_FL_DI, 0, &pdp->flru)) {
978 gsn->missing++;
979 gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
980 "Missing mandatory information field");
981 return gtp_create_pdp_resp(gsn, version, peer, pack, len, pdp,
982 GTPCAUSE_MAN_IE_MISSING);
983 }
984
985 if (gtpie_gettv2(ie, GTPIE_FL_C, 0, &pdp->flrc)) {
986 gsn->missing++;
987 gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
988 "Missing mandatory information field");
989 return gtp_create_pdp_resp(gsn, version, peer, pack, len, pdp,
990 GTPCAUSE_MAN_IE_MISSING);
991 }
992
993 if (gtpie_gettlv(ie, GTPIE_EUA, 0, &pdp->eua.l,
994 &pdp->eua.v, sizeof(pdp->eua.v))) {
995 gsn->missing++;
996 gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
997 "Missing mandatory information field");
998 return gtp_create_pdp_resp(gsn, version, peer, pack, len, pdp,
999 GTPCAUSE_MAN_IE_MISSING);
1000 }
1001
1002 if (gtpie_gettlv(ie, GTPIE_APN, 0, &pdp->apn_req.l,
1003 &pdp->apn_req.v, sizeof(pdp->apn_req.v))) {
1004 gsn->missing++;
1005 gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
1006 "Missing mandatory information field");
1007 return gtp_create_pdp_resp(gsn, version, peer, pack, len, pdp,
1008 GTPCAUSE_MAN_IE_MISSING);
1009 }
1010
1011 /* Extract protocol configuration options (optional) */
1012 if (!gtpie_gettlv(ie, GTPIE_PCO, 0, &pdp->pco_req.l,
1013 &pdp->pco_req.v, sizeof(pdp->pco_req.v))) {
1014 /* TODO: Handle PCO IE */
1015 }
1016
1017 if (gtpie_gettlv(ie, GTPIE_GSN_ADDR, 0, &pdp->gsnrc.l,
1018 &pdp->gsnrc.v, sizeof(pdp->gsnrc.v))) {
1019 gsn->missing++;
1020 gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
1021 "Missing mandatory information field");
1022 return gtp_create_pdp_resp(gsn, version, peer, pack, len, pdp,
1023 GTPCAUSE_MAN_IE_MISSING);
1024 }
1025
1026 if (gtpie_gettlv(ie, GTPIE_GSN_ADDR, 1, &pdp->gsnru.l,
1027 &pdp->gsnru.v, sizeof(pdp->gsnru.v))) {
1028 gsn->missing++;
1029 gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
1030 "Missing mandatory information field");
1031 return gtp_create_pdp_resp(gsn, version, peer, pack, len, pdp,
1032 GTPCAUSE_MAN_IE_MISSING);
1033 }
1034
1035 if (gtpie_gettlv(ie, GTPIE_MSISDN, 0, &pdp->msisdn.l,
1036 &pdp->msisdn.v, sizeof(pdp->msisdn.v))) {
1037 gsn->missing++;
1038 gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
1039 "Missing mandatory information field");
1040 return gtp_create_pdp_resp(gsn, version, peer, pack, len, pdp,
1041 GTPCAUSE_MAN_IE_MISSING);
1042 }
1043
1044 in_addr2gsna(&pdp->gsnlc, &gsn->gsnc);
1045 in_addr2gsna(&pdp->gsnlu, &gsn->gsnu);
1046
1047 if (!pdp_tidget(&pdp_old, ((union gtp_packet*)pack)->gtp0.h.tid)) {
1048 /* Found old pdp with same tid. Now the voodoo begins! */
1049 /* We check that the APN, selection mode and MSISDN is the same */
1050 if ( (pdp->apn_req.l == pdp_old->apn_req.l)
1051 && (!memcmp(pdp->apn_req.v, pdp_old->apn_req.v, pdp->apn_req.l))
1052 && (pdp->selmode == pdp_old->selmode)
1053 && (pdp->msisdn.l == pdp_old->msisdn.l)
1054 && (!memcmp(pdp->msisdn.v, pdp_old->msisdn.v, pdp->msisdn.l))) {
1055 /* OK! We are dealing with the same APN. We will copy new
1056 * parameters to the old pdp and send off confirmation
1057 * We ignore the following information elements:
1058 * QoS: MS will get originally negotiated QoS.
1059 * End user address (EUA). MS will get old EUA anyway.
1060 * Protocol configuration option (PCO): Only application can verify */
1061
1062 /* Copy remote flow label */
1063 pdp_old->flru = pdp->flru;
1064 pdp_old->flrc = pdp->flrc;
1065
1066 /* Copy peer GSN address */
1067 pdp_old->gsnrc.l = pdp->gsnrc.l;
1068 memcpy(&pdp_old->gsnrc.v, &pdp->gsnrc.v, pdp->gsnrc.l);
1069 pdp_old->gsnru.l = pdp->gsnru.l;
1070 memcpy(&pdp_old->gsnru.v, &pdp->gsnru.v, pdp->gsnru.l);
1071
1072 /* pdp_freepdp(pdp); not nessasary anymore since never allocated */
1073 pdp = pdp_old;
1074
1075 /* Confirm to peer that things were "successful" */
1076 return gtp_create_pdp_resp(gsn, version, peer, pack, len, pdp,
1077 GTPCAUSE_ACC_REQ);
1078 }
1079 else { /* This is not the same PDP context. Delete the old one. */
1080
1081 if (gsn->cb_delete_context) gsn->cb_delete_context(pdp_old);
1082 pdp_freepdp(pdp_old);
1083
1084 }
1085 }
1086
1087 pdp_newpdp(&pdp, imsi, nsapi, pdp);
1088
1089 /* Callback function to validata login */
1090 if (gsn->cb_create_context !=0)
1091 auth = gsn->cb_create_context(pdp);
1092
1093 /* Now send off a reply to the peer */
1094 if (!auth) {
1095 return gtp_create_pdp_resp(gsn, version, peer, pack, len, pdp,
1096 GTPCAUSE_ACC_REQ);
1097 }
1098 else {
1099 gtp_create_pdp_resp(gsn, version, peer, pack, len, pdp,
1100 GTPCAUSE_USER_AUTH_FAIL);
1101 pdp_freepdp(pdp);
1102 return 0;
1103 }
1104}
1105
1106
1107/* Handle Create PDP Context Response */
1108int gtp_create_pdp_conf(struct gsn_t *gsn, int version,
1109 struct sockaddr_in *peer,
1110 void *pack, unsigned len) {
1111 struct pdp_t *pdp;
1112 union gtpie_member *ie[GTPIE_SIZE];
1113 uint8_t cause, recovery;
1114 void *aid = NULL;
1115 uint8_t type = 0;
1116
1117 /* Remove packet from queue */
1118 if (gtp_conf(gsn, 0, peer, pack, len, &type, &aid)) return EOF;
1119
1120 /* Find the context in question */
1121 if (pdp_getgtp0(&pdp, ntoh16(((union gtp_packet*)pack)->gtp0.h.flow))) {
1122 gsn->err_unknownpdp++;
1123 gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
1124 "Unknown PDP context");
1125 if (gsn->cb_conf) gsn->cb_conf(type, EOF, NULL, aid);
1126 return EOF;
1127 }
1128
1129 /* Decode information elements */
1130 if (gtpie_decaps(ie, pack+GTP0_HEADER_SIZE, len-GTP0_HEADER_SIZE)) {
1131 gsn->invalid++;
1132 gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
1133 "Invalid message format");
1134 if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, aid);
1135 return EOF;
1136 }
1137
1138 /* Extract cause value (mandatory) */
1139 if (gtpie_gettv1(ie, GTPIE_CAUSE, 0, &cause)) {
1140 gsn->missing++;
1141 gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
1142 "Missing mandatory information field");
1143 if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, aid);
1144 return EOF;
1145 }
1146
1147 /* Extract recovery (optional) */
1148 if (!gtpie_gettv1(ie, GTPIE_RECOVERY, 0, &recovery)) {
1149 /* TODO: Handle received recovery IE */
1150 }
1151
1152 /* Extract protocol configuration options (optional) */
1153 if (!gtpie_gettlv(ie, GTPIE_PCO, 0, &pdp->pco_req.l,
1154 &pdp->pco_req.v, sizeof(pdp->pco_req.v))) {
1155 /* TODO: Handle PCO IE */
1156 }
1157
1158 /* Check all conditional information elements */
1159 if (GTPCAUSE_ACC_REQ == cause) {
1160
1161 if (gtpie_gettv0(ie, GTPIE_QOS_PROFILE0, 0, /* TODO: HACK only gtp0 */
1162 &pdp->qos_neg0, sizeof(pdp->qos_neg0))) {
1163 gsn->missing++;
1164 gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
1165 "Missing conditional information field");
1166 if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, aid);
1167 return EOF;
1168 }
1169 /* pdp->qos_neg.l = 3; * TODO: HACK only gtp0 */
1170
1171 if (gtpie_gettv1(ie, GTPIE_REORDER, 0, &pdp->reorder)) {
1172 gsn->missing++;
1173 gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
1174 "Missing conditional information field");
1175 if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, aid);
1176 return EOF;
1177 }
1178
1179 if (gtpie_gettv2(ie, GTPIE_FL_DI, 0, &pdp->flru)) {
1180 gsn->missing++;
1181 gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
1182 "Missing conditional information field");
1183 if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, aid);
1184 return EOF;
1185 }
1186
1187 if (gtpie_gettv2(ie, GTPIE_FL_C, 0, &pdp->flrc)) {
1188 gsn->missing++;
1189 gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
1190 "Missing conditional information field");
1191 if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, aid);
1192 return EOF;
1193 }
1194
1195 if (gtpie_gettv4(ie, GTPIE_CHARGING_ID, 0, &pdp->cid)) {
1196 gsn->missing++;
1197 gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
1198 "Missing conditional information field");
1199 if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, aid);
1200 return gtp_create_pdp_resp(gsn, version, peer, pack, len, pdp,
1201 GTPCAUSE_MAN_IE_MISSING);
1202 }
1203
1204 if (gtpie_gettlv(ie, GTPIE_EUA, 0, &pdp->eua.l,
1205 &pdp->eua.v, sizeof(pdp->eua.v))) {
1206 gsn->missing++;
1207 gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
1208 "Missing conditional information field");
1209 if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, aid);
1210 return EOF;
1211 }
1212
1213 if (gtpie_gettlv(ie, GTPIE_GSN_ADDR, 0, &pdp->gsnrc.l,
1214 &pdp->gsnrc.v, sizeof(pdp->gsnrc.v))) {
1215 gsn->missing++;
1216 gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
1217 "Missing conditional information field");
1218 if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, aid);
1219 return EOF;
1220 }
1221
1222 if (gtpie_gettlv(ie, GTPIE_GSN_ADDR, 1, &pdp->gsnru.l,
1223 &pdp->gsnru.v, sizeof(pdp->gsnru.v))) {
1224 gsn->missing++;
1225 gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
1226 "Missing conditional information field");
1227 if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, aid);
1228 return EOF;
1229 }
1230 }
1231
1232 if (gsn->cb_conf) gsn->cb_conf(type, cause, pdp, aid);
1233
1234 return 0;
1235}
1236
1237/* Send Update PDP Context Request */
1238extern int gtp_update_pdp_req(struct gsn_t *gsn, int version, void *aid,
1239 struct in_addr* inetaddr, struct pdp_t *pdp) {
1240 union gtp_packet packet;
1241 int length = 0;
1242
1243 get_default_gtp(0, &packet);
1244
1245 gtpie_tv0(packet.gtp0.p, &length, GTP_MAX, GTPIE_QOS_PROFILE0,
1246 sizeof(pdp->qos_req0), pdp->qos_req0);
1247 gtpie_tv1(packet.gtp0.p, &length, GTP_MAX, GTPIE_RECOVERY,
1248 gsn->restart_counter);
1249 gtpie_tv2(packet.gtp0.p, &length, GTP_MAX, GTPIE_FL_DI,
1250 pdp->fllu);
1251 gtpie_tv2(packet.gtp0.p, &length, GTP_MAX, GTPIE_FL_C,
1252 pdp->fllc);
1253 gtpie_tlv(packet.gtp0.p, &length, GTP_MAX, GTPIE_GSN_ADDR,
1254 pdp->gsnlc.l, pdp->gsnlc.v);
1255 gtpie_tlv(packet.gtp0.p, &length, GTP_MAX, GTPIE_GSN_ADDR,
1256 pdp->gsnlu.l, pdp->gsnlu.v);
1257
1258 packet.gtp0.h.type = hton8(GTP_UPDATE_PDP_REQ);
1259 packet.gtp0.h.length = hton16(length);
1260 packet.gtp0.h.flow = 0;
1261 packet.gtp0.h.tid = (pdp->imsi & 0x0fffffffffffffff) + ((uint64_t)pdp->nsapi << 60);
1262
1263 return gtp_req(gsn, 0, &packet, GTP0_HEADER_SIZE+length, inetaddr, aid);
1264}
1265
1266/* Send Update PDP Context Response */
1267int gtp_update_pdp_resp(struct gsn_t *gsn, int version,
1268 struct sockaddr_in *peer,
1269 void *pack, unsigned len,
1270 struct pdp_t *pdp, uint8_t cause)
1271{
1272 union gtp_packet packet;
1273 int length = 0;
1274
1275 get_default_gtp(0, &packet);
1276
1277 gtpie_tv1(packet.gtp0.p, &length, GTP_MAX, GTPIE_CAUSE, cause);
1278
1279 if (cause == GTPCAUSE_ACC_REQ) {
1280 gtpie_tv0(packet.gtp0.p, &length, GTP_MAX, GTPIE_QOS_PROFILE0,
1281 sizeof(pdp->qos_sub0), pdp->qos_sub0);
1282 gtpie_tv1(packet.gtp0.p, &length, GTP_MAX, GTPIE_RECOVERY,
1283 gsn->restart_counter);
1284 gtpie_tv2(packet.gtp0.p, &length, GTP_MAX, GTPIE_FL_DI,
1285 pdp->fllu);
1286 gtpie_tv2(packet.gtp0.p, &length, GTP_MAX, GTPIE_FL_C,
1287 pdp->fllc);
1288 gtpie_tv4(packet.gtp0.p, &length, GTP_MAX, GTPIE_CHARGING_ID,
1289 0x12345678);
1290 gtpie_tlv(packet.gtp0.p, &length, GTP_MAX, GTPIE_GSN_ADDR,
1291 pdp->gsnlc.l, pdp->gsnlc.v);
1292 gtpie_tlv(packet.gtp0.p, &length, GTP_MAX, GTPIE_GSN_ADDR,
1293 pdp->gsnlu.l, pdp->gsnlu.v);
1294 }
1295
1296 packet.gtp0.h.type = hton8(GTP_UPDATE_PDP_RSP);
1297 packet.gtp0.h.length = hton16(length);
1298 packet.gtp0.h.flow = hton16(pdp->flrc);
1299 packet.gtp0.h.seq = ((union gtp_packet*)pack)->gtp0.h.seq;
1300 packet.gtp0.h.tid = (pdp->imsi & 0x0fffffffffffffff) + ((uint64_t)pdp->nsapi << 60);
1301
1302 return gtp_resp(0, gsn, &packet, GTP0_HEADER_SIZE+length, peer);
1303}
1304
1305/* Handle Update PDP Context Request */
1306int gtp_update_pdp_ind(struct gsn_t *gsn, int version,
1307 struct sockaddr_in *peer, void *pack, unsigned len) {
1308 struct pdp_t *pdp, *pdp2;
1309 struct pdp_t pdp_buf;
1310 union gtpie_member* ie[GTPIE_SIZE];
1311 uint8_t recovery;
1312
1313 uint16_t seq = ntoh16(((union gtp_packet*)pack)->gtp0.h.seq);
1314
1315 /* Is this a dublicate ? */
1316 if(!gtp_dublicate(gsn, 0, peer, seq)) {
1317 return 0; /* We allready send of response once */
1318 }
1319
1320 /* Find the pdp context in question */
1321 if (pdp_getgtp0(&pdp, ntoh16(((union gtp_packet*)pack)->gtp0.h.flow))) {
1322 gsn->err_unknownpdp++;
1323 gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
1324 "Unknown PDP context");
1325 return gtp_update_pdp_resp(gsn, version, peer, pack, len, NULL,
1326 GTPCAUSE_NON_EXIST);
1327 }
1328
1329 /* Decode information elements */
1330 if (gtpie_decaps(ie, pack+GTP0_HEADER_SIZE, len-GTP0_HEADER_SIZE)) {
1331 gsn->invalid++;
1332 gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
1333 "Invalid message format");
1334 if (0 == version)
1335 return EOF;
1336 else
1337 return gtp_update_pdp_resp(gsn, version, peer, pack, len, pdp,
1338 GTPCAUSE_INVALID_MESSAGE);
1339 }
1340
1341 pdp2 = &pdp_buf;
1342 memcpy(pdp2, pdp, sizeof (struct pdp_t)); /* Generate local copy */
1343
1344 if (gtpie_gettv0(ie, GTPIE_QOS_PROFILE0, 0, /* TODO: HACK only gtp0 */
1345 &pdp2->qos_req0, sizeof(pdp2->qos_req0))) {
1346 gsn->missing++;
1347 gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
1348 "Missing mandatory information field");
1349 return gtp_update_pdp_resp(gsn, version, peer, pack, len, pdp2,
1350 GTPCAUSE_MAN_IE_MISSING);
1351 }
1352 /* pdp2->qos_req.l = 3; * TODO: HACK only gtp0 */
1353
1354 /* Extract recovery (optional) */
1355 if (!gtpie_gettv1(ie, GTPIE_RECOVERY, 0, &recovery)) {
1356 /* TODO: Handle received recovery IE */
1357 }
1358
1359 if (gtpie_gettv2(ie, GTPIE_FL_DI, 0, &pdp2->flru)) {
1360 gsn->missing++;
1361 gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
1362 "Missing mandatory information field");
1363 return gtp_update_pdp_resp(gsn, version, peer, pack, len, pdp2,
1364 GTPCAUSE_MAN_IE_MISSING);
1365 }
1366
1367 if (gtpie_gettv2(ie, GTPIE_FL_C, 0, &pdp2->flrc)) {
1368 gsn->missing++;
1369 gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
1370 "Missing mandatory information field");
1371 return gtp_update_pdp_resp(gsn, version, peer, pack, len, pdp2,
1372 GTPCAUSE_MAN_IE_MISSING);
1373 }
1374
1375 if (gtpie_gettlv(ie, GTPIE_GSN_ADDR, 0, &pdp2->gsnrc.l,
1376 &pdp2->gsnrc.v, sizeof(pdp2->gsnrc.v))) {
1377 gsn->missing++;
1378 gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
1379 "Missing mandatory information field");
1380 return gtp_update_pdp_resp(gsn, version, peer, pack, len, pdp2,
1381 GTPCAUSE_MAN_IE_MISSING);
1382 }
1383
1384 if (gtpie_gettlv(ie, GTPIE_GSN_ADDR, 1, &pdp2->gsnru.l,
1385 &pdp2->gsnru.v, sizeof(pdp2->gsnru.v))) {
1386 gsn->missing++;
1387 gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
1388 "Missing mandatory information field");
1389 return gtp_update_pdp_resp(gsn, version, peer, pack, len, pdp2,
1390 GTPCAUSE_MAN_IE_MISSING);
1391 }
1392
1393 /* OK! It seames as if we received a valid message */
1394
1395 memcpy(pdp, pdp2, sizeof (struct pdp_t)); /* Update original pdp */
1396
1397 /* Confirm to peer that things were "successful" */
1398 return gtp_update_pdp_resp(gsn, version, peer, pack, len, pdp,
1399 GTPCAUSE_ACC_REQ);
1400}
1401
1402
1403/* Handle Update PDP Context Response */
1404int gtp_update_pdp_conf(struct gsn_t *gsn, int version,
1405 struct sockaddr_in *peer,
1406 void *pack, unsigned len) {
1407 struct pdp_t *pdp;
1408 union gtpie_member *ie[GTPIE_SIZE];
1409 uint8_t cause, recovery;
1410 void *aid = NULL;
1411 uint8_t type = 0;
1412
1413 /* Remove packet from queue */
1414 if (gtp_conf(gsn, 0, peer, pack, len, &type, &aid)) return EOF;
1415
1416 /* Find the context in question */
1417 if (pdp_getgtp0(&pdp, ntoh16(((union gtp_packet*)pack)->gtp0.h.flow))) {
1418 gsn->err_unknownpdp++;
1419 gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
1420 "Unknown PDP context");
1421 if (gsn->cb_conf) gsn->cb_conf(type, cause, NULL, aid);
1422 return EOF;
1423 }
1424
1425 /* Decode information elements */
1426 if (gtpie_decaps(ie, pack+GTP0_HEADER_SIZE, len-GTP0_HEADER_SIZE)) {
1427 gsn->invalid++;
1428 gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
1429 "Invalid message format");
1430 if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, aid);
1431 if (gsn->cb_delete_context) gsn->cb_delete_context(pdp);
1432 pdp_freepdp(pdp);
1433 return EOF;
1434 }
1435
1436 /* Extract cause value (mandatory) */
1437 if (gtpie_gettv1(ie, GTPIE_CAUSE, 0, &cause)) {
1438 gsn->missing++;
1439 gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
1440 "Missing mandatory information field");
1441 if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, aid);
1442 if (gsn->cb_delete_context) gsn->cb_delete_context(pdp);
1443 pdp_freepdp(pdp);
1444 return EOF;
1445 }
1446
1447 /* Extract recovery (optional) */
1448 if (!gtpie_gettv1(ie, GTPIE_RECOVERY, 0, &recovery)) {
1449 /* TODO: Handle received recovery IE */
1450 }
1451
1452 /* Check all conditional information elements */
1453 if (GTPCAUSE_ACC_REQ != cause) {
1454 if (gsn->cb_conf) gsn->cb_conf(type, cause, pdp, aid);
1455 if (gsn->cb_delete_context) gsn->cb_delete_context(pdp);
1456 pdp_freepdp(pdp);
1457 return 0;
1458 }
1459 else {
1460 /* Check for missing conditionary information elements */
1461 if (!(gtpie_exist(ie, GTPIE_QOS_PROFILE0, 0) &&
1462 gtpie_exist(ie, GTPIE_REORDER, 0) &&
1463 gtpie_exist(ie, GTPIE_FL_DI, 0) &&
1464 gtpie_exist(ie, GTPIE_FL_C, 0) &&
1465 gtpie_exist(ie, GTPIE_CHARGING_ID, 0) &&
1466 gtpie_exist(ie, GTPIE_EUA, 0) &&
1467 gtpie_exist(ie, GTPIE_GSN_ADDR, 0) &&
1468 gtpie_exist(ie, GTPIE_GSN_ADDR, 1))) {
1469 gsn->missing++;
1470 gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
1471 "Missing conditional information field");
1472 if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, aid);
1473 if (gsn->cb_delete_context) gsn->cb_delete_context(pdp);
1474 pdp_freepdp(pdp);
1475 return EOF;
1476 }
1477
1478 /* Update pdp with new values */
1479 gtpie_gettv0(ie, GTPIE_QOS_PROFILE0, 0,
1480 pdp->qos_neg0, sizeof(pdp->qos_neg0));
1481 gtpie_gettv1(ie, GTPIE_REORDER, 0, &pdp->reorder);
1482 gtpie_gettv2(ie, GTPIE_FL_DI, 0, &pdp->flru);
1483 gtpie_gettv2(ie, GTPIE_FL_C, 0, &pdp->flrc);
1484 gtpie_gettv4(ie, GTPIE_CHARGING_ID, 0, &pdp->cid);
1485 gtpie_gettlv(ie, GTPIE_EUA, 0, &pdp->eua.l,
1486 &pdp->eua.v, sizeof(pdp->eua.v));
1487 gtpie_gettlv(ie, GTPIE_GSN_ADDR, 0, &pdp->gsnrc.l,
1488 &pdp->gsnrc.v, sizeof(pdp->gsnrc.v));
1489 gtpie_gettlv(ie, GTPIE_GSN_ADDR, 1, &pdp->gsnru.l,
1490 &pdp->gsnru.v, sizeof(pdp->gsnru.v));
1491
1492 if (gsn->cb_conf) gsn->cb_conf(type, cause, pdp, aid);
1493 return 0; /* Succes */
1494 }
1495}
1496
1497/* Send Delete PDP Context Request */
1498extern int gtp_delete_pdp_req(struct gsn_t *gsn, int version, void *aid,
1499 struct pdp_t *pdp) {
1500 union gtp_packet packet;
1501 int length = 0;
1502 struct in_addr addr;
1503
1504 if (gsna2in_addr(&addr, &pdp->gsnrc)) {
1505 gsn->err_address++;
1506 gtp_err(LOG_ERR, __FILE__, __LINE__, "GSN address conversion failed");
1507 return EOF;
1508 }
1509
1510 get_default_gtp(0, &packet);
1511
1512 packet.gtp0.h.type = hton8(GTP_DELETE_PDP_REQ);
1513 packet.gtp0.h.length = hton16(length);
1514 packet.gtp0.h.flow = hton16(pdp->flrc);
1515 packet.gtp0.h.tid = (pdp->imsi & 0x0fffffffffffffff) + ((uint64_t)pdp->nsapi << 60);
1516
1517 return gtp_req(gsn, 0, &packet, GTP0_HEADER_SIZE+length, &addr, aid);
1518}
1519
1520/* Send Delete PDP Context Response */
1521int gtp_delete_pdp_resp(struct gsn_t *gsn, int version,
1522 struct sockaddr_in *peer,
1523 void *pack, unsigned len,
1524 struct pdp_t *pdp, uint8_t cause)
1525{
1526 union gtp_packet packet;
1527 int length = 0;
1528 uint16_t flow = 0;
1529
1530 if (pdp) flow = hton16(pdp->flrc);
1531
1532 get_default_gtp(0, &packet);
1533
1534 gtpie_tv1(packet.gtp0.p, &length, GTP_MAX, GTPIE_CAUSE, cause);
1535
1536 packet.gtp0.h.type = hton8(GTP_DELETE_PDP_RSP);
1537 packet.gtp0.h.length = hton16(length);
1538 packet.gtp0.h.flow = flow;
1539 packet.gtp0.h.seq = ((union gtp_packet*)pack)->gtp0.h.seq;
1540 packet.gtp0.h.tid = ((union gtp_packet*)pack)->gtp0.h.tid;
1541
1542 if (pdp) {
1543 /* Callback function to allow application to clean up */
1544 if (gsn->cb_delete_context) gsn->cb_delete_context(pdp);
1545 pdp_freepdp(pdp); /* Clean up PDP context */
1546 }
1547
1548 return gtp_resp(0, gsn, &packet, GTP0_HEADER_SIZE+length, peer);
1549}
1550
1551/* Handle Delete PDP Context Request */
1552int gtp_delete_pdp_ind(struct gsn_t *gsn, int version,
1553 struct sockaddr_in *peer, void *pack, unsigned len) {
1554 struct pdp_t *pdp;
1555 union gtpie_member* ie[GTPIE_SIZE];
1556 uint16_t seq = ntoh16(((union gtp_packet*)pack)->gtp0.h.seq);
1557
1558 /* Is this a dublicate ? */
1559 if(!gtp_dublicate(gsn, 0, peer, seq)) {
1560 return 0;
1561 }
1562
1563 /* Find the pdp context in question */
1564 if (pdp_getgtp0(&pdp, ntoh16(((union gtp_packet*)pack)->gtp0.h.flow))) {
1565 gsn->err_unknownpdp++;
1566 gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
1567 "Unknown PDP context");
1568 if (0 == version)
1569 return gtp_delete_pdp_resp(gsn, version, peer, pack, len, NULL,
1570 GTPCAUSE_ACC_REQ);
1571 else
1572 return gtp_delete_pdp_resp(gsn, version, peer, pack, len, NULL,
1573 GTPCAUSE_NON_EXIST);
1574 }
1575
1576 /* Decode information elements */
1577 if (gtpie_decaps(ie, pack+GTP0_HEADER_SIZE, len-GTP0_HEADER_SIZE)) {
1578 gsn->invalid++;
1579 gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
1580 "Invalid message format");
1581 if (0 == version)
1582 return EOF;
1583 else
1584 return gtp_delete_pdp_resp(gsn, version, peer, pack, len, pdp,
1585 GTPCAUSE_INVALID_MESSAGE);
1586 }
1587
1588 return gtp_delete_pdp_resp(gsn, version, peer, pack, len, pdp,
1589 GTPCAUSE_ACC_REQ);
1590}
1591
1592
1593/* Handle Delete PDP Context Response */
1594int gtp_delete_pdp_conf(struct gsn_t *gsn, int version,
1595 struct sockaddr_in *peer,
1596 void *pack, unsigned len) {
1597 struct pdp_t *pdp;
1598 union gtpie_member *ie[GTPIE_SIZE];
1599 uint8_t cause;
1600 void *aid = NULL;
1601 uint8_t type = 0;
1602
1603 /* Remove packet from queue */
1604 if (gtp_conf(gsn, 0, peer, pack, len, &type, &aid)) return EOF;
1605
1606 /* Find the context in question */
1607 if (pdp_getgtp0(&pdp, ntoh16(((union gtp_packet*)pack)->gtp0.h.flow))) {
1608 gsn->err_unknownpdp++;
1609 gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
1610 "Unknown PDP context");
1611 return EOF;
1612 }
1613
1614 /* Decode information elements */
1615 if (gtpie_decaps(ie, pack+GTP0_HEADER_SIZE, len-GTP0_HEADER_SIZE)) {
1616 gsn->invalid++;
1617 gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
1618 "Invalid message format");
1619 return EOF;
1620 }
1621
1622 /* Extract cause value */
1623 if (gtpie_gettv1(ie, GTPIE_CAUSE, 0, &cause)) {
1624 gsn->missing++;
1625 gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
1626 "Missing mandatory information field");
1627 return EOF;
1628 }
1629
1630 /* Check the cause value */
1631 if ((GTPCAUSE_ACC_REQ != cause) && (GTPCAUSE_NON_EXIST != cause)) {
1632 gsn->err_cause++;
1633 gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
1634 "Unexpected cause value received: %d", cause);
1635 return EOF;
1636 }
1637
1638 /* Callback function to allow application to clean up */
1639 if (gsn->cb_conf) gsn->cb_conf(type, cause, pdp, aid);
1640
1641 if (gsn->cb_delete_context) gsn->cb_delete_context(pdp);
1642 pdp_freepdp(pdp);
1643
1644 return 0;
1645}
1646
1647/* Send Error Indication (response to a GPDU message */
1648int gtp_error_ind_resp(struct gsn_t *gsn, int version,
1649 struct sockaddr_in *peer,
1650 void *pack, unsigned len)
1651{
1652 union gtp_packet packet;
1653 int length = 0;
1654
1655 get_default_gtp(0, &packet);
1656
1657 packet.gtp0.h.type = hton8(GTP_ERROR);
1658 packet.gtp0.h.length = hton16(length);
1659 packet.gtp0.h.flow = 0;
1660 packet.gtp0.h.seq = ((union gtp_packet*)pack)->gtp0.h.seq;
1661 packet.gtp0.h.tid = ((union gtp_packet*)pack)->gtp0.h.tid;
1662
1663 return gtp_resp(0, gsn, &packet, GTP0_HEADER_SIZE+length, peer);
1664}
1665
1666/* Handle Error Indication */
1667int gtp_error_ind_conf(struct gsn_t *gsn, int version,
1668 struct sockaddr_in *peer,
1669 void *pack, unsigned len) {
1670 struct pdp_t *pdp;
1671
1672 /* Find the context in question */
1673 if (pdp_tidget(&pdp, ((union gtp_packet*)pack)->gtp0.h.tid)) {
1674 gsn->err_unknownpdp++;
1675 gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
1676 "Unknown PDP context");
1677 return EOF;
1678 }
1679
1680 gsn->err_unknownpdp++; /* TODO: Change counter */
1681 gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
1682 "Received Error Indication");
1683
1684 if (gsn->cb_delete_context) gsn->cb_delete_context(pdp);
1685 pdp_freepdp(pdp);
1686 return 0;
1687}
1688
1689int gtp_gpdu_ind(struct gsn_t *gsn, int version,
1690 struct sockaddr_in *peer,
1691 void *pack,
1692 unsigned len) {
1693
1694 /* Need to include code to verify packet src and dest addresses */
1695 struct pdp_t *pdp;
1696
1697 if (pdp_getgtp0(&pdp, ntoh16(((union gtp_packet*)pack)->gtp0.h.flow))) {
1698 gsn->err_unknownpdp++;
1699 gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
1700 "Unknown PDP context");
1701 return gtp_error_ind_resp(gsn, version, peer, pack, len);
1702
1703 }
1704
1705 /* Callback function */
1706 if (gsn->cb_gpdu !=0)
1707 return gsn->cb_gpdu(pdp, pack+20, len-20); /* TODO ???? */
1708
1709 return 0;
1710}
1711
1712
1713/* Receives GTP packet and sends off for further processing
1714 * Function will check the validity of the header. If the header
1715 * is not valid the packet is either dropped or a version not
1716 * supported is returned to the peer.
1717 * TODO: Need to decide on return values! */
1718int gtp_decaps(struct gsn_t *gsn)
1719{
1720 unsigned char buffer[PACKET_MAX + 64 /*TODO: ip header */ ];
1721 int status, ip_len = 0;
1722 struct sockaddr_in peer;
1723 int peerlen;
1724 struct gtp0_header *pheader;
1725 int version = 0; /* GTP version should be determined from header!*/
1726
1727 peerlen = sizeof(peer);
1728 if ((status =
1729 recvfrom(gsn->fd, buffer, sizeof(buffer), 0,
1730 (struct sockaddr *) &peer, &peerlen)) < 0 ) {
1731 gsn->err_readfrom++;
1732 gtp_err(LOG_ERR, __FILE__, __LINE__, "recvfrom(fd=%d, buffer=%lx, len=%d) failed: status = %d error = %s", gsn->fd, (unsigned long) buffer, sizeof(buffer), status, status ? strerror(errno) : "No error");
1733 return -1;
1734 }
1735
1736 /* Strip off IP header, if present: TODO Is this nessesary? */
1737 if ((buffer[0] & 0xF0) == 0x40) {
1738 ip_len = (buffer[0] & 0xF) * 4;
1739 gtp_errpack(LOG_ERR, __FILE__, __LINE__, &peer, buffer, status,
1740 "IP header found in return from read");
1741 return -1;
1742 }
1743
1744 /* Need at least 1 byte in order to check version */
1745 if (status < (1)) {
1746 gsn->empty++;
1747 gtp_errpack(LOG_ERR, __FILE__, __LINE__, &peer, buffer, status,
1748 "Discarding packet - too small");
1749 return -1;
1750 }
1751
1752 /* TODO: Remove these ERROR MESSAGES
1753 gtp_err(LOG_ERR, __FILE__, __LINE__, "Discarding packet - too small");
1754 gtp_errpack(LOG_ERR, __FILE__, __LINE__, &peer, buffer, status,
1755 "Discarding packet - too small"); */
1756
1757 pheader = (struct gtp0_header *) (buffer + ip_len);
1758
1759 /* Version should be gtp0 (or earlier in theory) */
1760 if (((pheader->flags & 0xe0) > 0x00)) {
1761 gsn->unsup++;
1762 gtp_errpack(LOG_ERR, __FILE__, __LINE__, &peer, buffer, status,
1763 "Unsupported GTP version");
1764 return gtp_unsup_resp(gsn, &peer, buffer, status); /* 29.60: 11.1.1 */
1765 }
1766
1767 /* Check length of gtp0 packet */
1768 if (((pheader->flags & 0xe0) == 0x00) && (status < GTP0_HEADER_SIZE)) {
1769 gsn->tooshort++;
1770 gtp_errpack(LOG_ERR, __FILE__, __LINE__, &peer, buffer, status,
1771 "GTP0 packet too short");
1772 return -1; /* Silently discard 29.60: 11.1.2 */
1773 }
1774
1775 switch (pheader->type) {
1776 case GTP_ECHO_REQ:
1777 return gtp_echo_ind(gsn, &peer, buffer+ip_len, status - ip_len);
1778 case GTP_ECHO_RSP:
1779 return gtp_echo_conf(gsn, &peer, buffer+ip_len, status - ip_len);
1780 case GTP_NOT_SUPPORTED:
1781 return gtp_unsup_conf(gsn, &peer, buffer+ip_len, status - ip_len);
1782 case GTP_CREATE_PDP_REQ:
1783 return gtp_create_pdp_ind(gsn, version, &peer, buffer+ip_len,
1784 status - ip_len);
1785 case GTP_CREATE_PDP_RSP:
1786 return gtp_create_pdp_conf(gsn, version, &peer, buffer+ip_len,
1787 status - ip_len);
1788 case GTP_UPDATE_PDP_REQ:
1789 return gtp_update_pdp_ind(gsn, version, &peer, buffer+ip_len,
1790 status - ip_len);
1791 case GTP_UPDATE_PDP_RSP:
1792 return gtp_update_pdp_conf(gsn, version, &peer, buffer+ip_len,
1793 status - ip_len);
1794 case GTP_DELETE_PDP_REQ:
1795 return gtp_delete_pdp_ind(gsn, version, &peer, buffer+ip_len,
1796 status - ip_len);
1797 case GTP_DELETE_PDP_RSP:
1798 return gtp_delete_pdp_conf(gsn, version, &peer, buffer+ip_len,
1799 status - ip_len);
1800 case GTP_ERROR:
1801 return gtp_error_ind_conf(gsn, version, &peer, buffer+ip_len,
1802 status - ip_len);
1803 case GTP_GPDU:
1804 return gtp_gpdu_ind(gsn, version, &peer, buffer+ip_len, status - ip_len);
1805 default:
1806 {
1807 gsn->unknown++;
1808 gtp_errpack(LOG_ERR, __FILE__, __LINE__, &peer, buffer, status,
1809 "Unknown GTP message type received");
1810 return -1;
1811 }
1812 }
1813}
1814
1815int gtp_gpdu(struct gsn_t *gsn, struct pdp_t* pdp,
1816 void *pack, unsigned len)
1817{
1818 union gtp_packet packet;
1819 struct sockaddr_in addr;
1820
1821 /*printf("gtp_encaps start\n");
1822 print_packet(pack, len);*/
1823
1824 memset(&addr, 0, sizeof(addr));
1825 addr.sin_family = AF_INET;
1826
1827 memcpy(&addr.sin_addr, pdp->gsnru.v,pdp->gsnru.l); /* TODO range check */
1828 addr.sin_port = htons(GTP0_PORT);
1829
1830 get_default_gtp(0, &packet);
1831 packet.gtp0.h.type = hton8(GTP_GPDU);
1832 packet.gtp0.h.length = hton16(len);
1833 packet.gtp0.h.seq = hton16(pdp->gtpsntx++);
1834 packet.gtp0.h.flow = hton16(pdp->flru);
1835 packet.gtp0.h.tid = (pdp->imsi & 0x0fffffffffffffff) + ((uint64_t)pdp->nsapi << 60);
1836
1837 if (len > sizeof (union gtp_packet) - sizeof(struct gtp0_header)) {
1838 gsn->err_memcpy++;
1839 gtp_err(LOG_ERR, __FILE__, __LINE__,
1840 "Memcpy failed");
1841 return EOF;
1842 }
1843
1844 memcpy(packet.gtp0.p, pack, len); /* TODO Should be avoided! */
1845
1846 if (sendto(gsn->fd, &packet, GTP0_HEADER_SIZE+len, 0,
1847 (struct sockaddr *) &addr, sizeof(addr)) < 0) {
1848 gsn->err_sendto++;
1849 gtp_err(LOG_ERR, __FILE__, __LINE__, "Sendto(fd=%d, msg=%lx, len=%d) failed: Error = %s", gsn->fd, (unsigned long) &packet, GTP0_HEADER_SIZE+len, strerror(errno));
1850 return EOF;
1851 }
1852 return 0;
1853}
1854
1855
1856/* ***********************************************************
1857 * Conversion functions
1858 *************************************************************/
1859
1860int char2ul_t(char* src, struct ul_t dst) {
1861 dst.l = strlen(src)+1;
1862 dst.v = malloc(dst.l);
1863 dst.v[0] = dst.l - 1;
1864 memcpy(&dst.v[1], src, dst.v[0]);
1865 return 0;
1866}
1867
1868/* ***********************************************************
1869 * IP address conversion functions
1870 * There exist several types of address representations:
1871 * - eua: End User Address. (29.060, 7.7.27, message type 128)
1872 * Used for signalling address to mobile station. Supports IPv4
1873 * IPv6 x.25 etc. etc.
1874 * - gsna: GSN Address. (29.060, 7.7.32, message type 133): IP address
1875 * of GSN. If length is 4 it is IPv4. If length is 16 it is IPv6.
1876 * - in_addr: IPv4 address struct.
1877 * - sockaddr_in: Socket API representation of IP address and
1878 * port number.
1879 *************************************************************/
1880
1881int ipv42eua(struct ul66_t *eua, struct in_addr *src) {
1882 eua->v[0] = 0xf1; /* IETF */
1883 eua->v[1] = 0x21; /* IPv4 */
1884 if (src) {
1885 eua->l = 6;
1886 memcpy(&eua->v[2], src, 4);
1887 }
1888 else
1889 {
1890 eua->l = 2;
1891 }
1892 return 0;
1893}
1894
1895int eua2ipv4(struct in_addr *dst, struct ul66_t *eua) {
1896 if ((eua->l != 6) ||
1897 (eua->v[0] != 0xf1) ||
1898 (eua->v[1] = 0x21))
1899 return -1; /* Not IPv4 address*/
1900 memcpy(dst, &eua->v[2], 4);
1901 return 0;
1902}
1903
1904int gsna2in_addr(struct in_addr *dst, struct ul16_t *gsna) {
1905 memset(dst, 0, sizeof(struct in_addr));
1906 if (gsna->l != 4) return EOF; /* Return if not IPv4 */
1907 memcpy(dst, gsna->v, gsna->l);
1908 return 0;
1909}
1910
1911int in_addr2gsna(struct ul16_t *gsna, struct in_addr *src) {
1912 memset(gsna, 0, sizeof(struct ul16_t));
1913 gsna->l = 4;
1914 memcpy(gsna->v, src, gsna->l);
1915 return 0;
1916}
1917