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