gtp.c: Don't print ""Unknown packet flags" error message in get_seq()
[openggsn.git] / gtp / gtp.c
blobade746a2dedc5eacda31f8e68cd225c3cd4414cf
1 /*
2 * OpenGGSN - Gateway GPRS Support Node
3 * Copyright (C) 2002, 2003, 2004 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 *
13 * gtp.c: Contains all GTP functionality. Should be able to handle multiple
14 * tunnels in the same program.
16 * TODO:
17 * - Do we need to handle fragmentation?
20 #ifdef __linux__
21 #define _GNU_SOURCE 1
22 #endif
24 #include <osmocom/core/logging.h>
25 #include <osmocom/core/utils.h>
27 #if defined(__FreeBSD__)
28 #include <sys/endian.h>
29 #endif
31 #include "../config.h"
32 #ifdef HAVE_STDINT_H
33 #include <stdint.h>
34 #endif
36 #include <stdio.h>
37 #include <stdarg.h>
38 #include <stdlib.h>
39 #include <sys/time.h>
40 #include <sys/types.h>
41 #include <sys/socket.h>
42 #include <netinet/in.h>
43 #include <arpa/inet.h>
44 #include <sys/stat.h>
45 #include <time.h>
46 #include <unistd.h>
47 #include <string.h>
48 #include <errno.h>
49 #include <fcntl.h>
50 #include <inttypes.h>
52 #include <arpa/inet.h>
54 /* #include <stdint.h> ISO C99 types */
56 #include "pdp.h"
57 #include "gtp.h"
58 #include "gtpie.h"
59 #include "queue.h"
61 /* According to section 14.2 of 3GPP TS 29.006 version 6.9.0 */
62 #define N3_REQUESTS 5
64 #define T3_REQUEST 3
66 /* Error reporting functions */
68 #define GTP_LOGPKG(pri, peer, pack, len, fmt, args...) \
69 logp2(DLGTP, pri, __FILE__, __LINE__, 0, \
70 "Packet from %s:%u, length: %d content: %s: " fmt, \
71 inet_ntoa((peer)->sin_addr), htons((peer)->sin_port), \
72 len, osmo_hexdump((const uint8_t *) pack, len), \
73 ##args);
75 #define LOGP_WITH_ADDR(ss, level, addr, fmt, args...) \
76 LOGP(ss, level, "addr(%s:%d) " fmt, \
77 inet_ntoa((addr).sin_addr), htons((addr).sin_port), \
78 ##args);
80 /* API Functions */
82 const char *gtp_version()
84 return VERSION;
87 /* gtp_new */
88 /* gtp_free */
90 int gtp_newpdp(struct gsn_t *gsn, struct pdp_t **pdp,
91 uint64_t imsi, uint8_t nsapi)
93 return pdp_newpdp(pdp, imsi, nsapi, NULL);
96 int gtp_freepdp(struct gsn_t *gsn, struct pdp_t *pdp)
98 return pdp_freepdp(pdp);
101 /* gtp_gpdu */
103 extern int gtp_fd(struct gsn_t *gsn)
105 return gsn->fd0;
108 /* gtp_decaps */
109 /* gtp_retrans */
110 /* gtp_retranstimeout */
112 int gtp_set_cb_unsup_ind(struct gsn_t *gsn,
113 int (*cb) (struct sockaddr_in * peer))
115 gsn->cb_unsup_ind = cb;
116 return 0;
119 int gtp_set_cb_extheader_ind(struct gsn_t *gsn,
120 int (*cb) (struct sockaddr_in * peer))
122 gsn->cb_extheader_ind = cb;
123 return 0;
126 /* API: Initialise delete context callback */
127 /* Called whenever a pdp context is deleted for any reason */
128 int gtp_set_cb_delete_context(struct gsn_t *gsn, int (*cb) (struct pdp_t * pdp))
130 gsn->cb_delete_context = cb;
131 return 0;
134 int gtp_set_cb_conf(struct gsn_t *gsn,
135 int (*cb) (int type, int cause,
136 struct pdp_t * pdp, void *cbp))
138 gsn->cb_conf = cb;
139 return 0;
142 int gtp_set_cb_recovery(struct gsn_t *gsn,
143 int (*cb) (struct sockaddr_in * peer, uint8_t recovery))
145 gsn->cb_recovery = cb;
146 return 0;
149 extern int gtp_set_cb_data_ind(struct gsn_t *gsn,
150 int (*cb_data_ind) (struct pdp_t * pdp,
151 void *pack, unsigned len))
153 gsn->cb_data_ind = cb_data_ind;
154 return 0;
158 * get_default_gtp()
159 * Generate a GPRS Tunneling Protocol signalling packet header, depending
160 * on GTP version and message type. pdp is used for teid/flow label.
161 * *packet must be allocated by the calling function, and be large enough
162 * to hold the packet header.
163 * returns the length of the header. 0 on error.
165 static unsigned int get_default_gtp(int version, uint8_t type, void *packet)
167 struct gtp0_header *gtp0_default = (struct gtp0_header *)packet;
168 struct gtp1_header_long *gtp1_default =
169 (struct gtp1_header_long *)packet;
170 switch (version) {
171 case 0:
172 /* Initialise "standard" GTP0 header */
173 memset(gtp0_default, 0, sizeof(struct gtp0_header));
174 gtp0_default->flags = 0x1e;
175 gtp0_default->type = hton8(type);
176 gtp0_default->spare1 = 0xff;
177 gtp0_default->spare2 = 0xff;
178 gtp0_default->spare3 = 0xff;
179 gtp0_default->number = 0xff;
180 return GTP0_HEADER_SIZE;
181 case 1:
182 /* Initialise "standard" GTP1 header */
183 /* 29.060: 8.2: S=1 and PN=0 */
184 /* 29.060 9.3.1: For GTP-U messages Echo Request, Echo Response */
185 /* and Supported Extension Headers Notification, the S field shall be */
186 /* set to 1 */
187 /* Currently extension headers are not supported */
188 memset(gtp1_default, 0, sizeof(struct gtp1_header_long));
189 gtp1_default->flags = 0x32; /* No extension, enable sequence, no N-PDU */
190 gtp1_default->type = hton8(type);
191 return GTP1_HEADER_SIZE_LONG;
192 default:
193 LOGP(DLGTP, LOGL_ERROR,
194 "Unknown GTP packet version: %d\n", version);
195 return 0;
200 * get_seq()
201 * Get sequence number of a packet.
202 * Returns 0 on error
204 static uint16_t get_seq(void *pack)
206 union gtp_packet *packet = (union gtp_packet *)pack;
208 if ((packet->flags & 0xe0) == 0x00) { /* Version 0 */
209 return ntoh16(packet->gtp0.h.seq);
210 } else if ((packet->flags & 0xe2) == 0x22) { /* Version 1 with seq */
211 return ntoh16(packet->gtp1l.h.seq);
212 } else {
213 return 0;
218 * get_tid()
219 * Get tunnel identifier of a packet.
220 * Returns 0 on error
222 static uint64_t get_tid(void *pack)
224 union gtp_packet *packet = (union gtp_packet *)pack;
226 if ((packet->flags & 0xe0) == 0x00) { /* Version 0 */
227 return be64toh(packet->gtp0.h.tid);
229 return 0;
233 * get_hlen()
234 * Get the header length of a packet.
235 * Returns 0 on error
237 static uint16_t get_hlen(void *pack)
239 union gtp_packet *packet = (union gtp_packet *)pack;
241 if ((packet->flags & 0xe0) == 0x00) { /* Version 0 */
242 return GTP0_HEADER_SIZE;
243 } else if ((packet->flags & 0xe2) == 0x22) { /* Version 1 with seq */
244 return GTP1_HEADER_SIZE_LONG;
245 } else if ((packet->flags & 0xe7) == 0x20) { /* Short version 1 */
246 return GTP1_HEADER_SIZE_SHORT;
247 } else {
248 LOGP(DLGTP, LOGL_ERROR, "Unknown packet flags: 0x%02x\n", packet->flags);
249 return 0;
254 * get_tei()
255 * Get the tunnel endpoint identifier (flow label) of a packet.
256 * Returns 0xffffffff on error.
258 static uint32_t get_tei(void *pack)
260 union gtp_packet *packet = (union gtp_packet *)pack;
262 if ((packet->flags & 0xe0) == 0x00) { /* Version 0 */
263 return ntoh16(packet->gtp0.h.flow);
264 } else if ((packet->flags & 0xe0) == 0x20) { /* Version 1 */
265 return ntoh32(packet->gtp1l.h.tei);
266 } else {
267 LOGP(DLGTP, LOGL_ERROR, "Unknown packet flags: 0x%02x\n", packet->flags);
268 return 0xffffffff;
272 /* ***********************************************************
273 * Reliable delivery of signalling messages
275 * Sequence numbers are used for both signalling messages and
276 * data messages.
278 * For data messages each tunnel maintains a sequence counter,
279 * which is incremented by one each time a new data message
280 * is sent. The sequence number starts at (0) zero at tunnel
281 * establishment, and wraps around at 65535 (29.060 9.3.1.1
282 * and 09.60 8.1.1.1). The sequence numbers are either ignored,
283 * or can be used to check the validity of the message in the
284 * receiver, or for reordering af packets.
286 * For signalling messages the sequence number is used by
287 * signalling messages for which a response is defined. A response
288 * message should copy the sequence from the corresponding request
289 * message. The sequence number "unambiguously" identifies a request
290 * message within a given path, with a path being defined as a set of
291 * two endpoints (29.060 8.2, 29.060 7.6, 09.60 7.8). "All request
292 * messages shall be responded to, and all response messages associated
293 * with a certain request shall always include the same information"
295 * We take this to mean that the GSN transmitting a request is free to
296 * choose the sequence number, as long as it is unique within a given path.
297 * It means that we are allowed to count backwards, or roll over at 17
298 * if we prefer that. It also means that we can use the same counter for
299 * all paths. This has the advantage that the transmitted request sequence
300 * numbers are unique within each GSN, and also we dont have to mess around
301 * with path setup and teardown.
303 * If a response message is lost, the request will be retransmitted, and
304 * the receiving GSN will receive a "duplicated" request. The standard
305 * requires the receiving GSN to send a response, with the same information
306 * as in the original response. For most messages this happens automatically:
308 * Echo: Automatically dublicates the original response
309 * Create pdp context: The SGSN may send create context request even if
310 * a context allready exist (imsi+nsapi?). This means that the reply will
311 automatically dublicate the original response. It might however have
312 * side effects in the application which is asked twice to validate
313 * the login.
314 * Update pdp context: Automatically dublicates the original response???
315 * Delete pdp context. Automatically in gtp0, but in gtp1 will generate
316 * a nonexist reply message.
318 * The correct solution will be to make a queue containing response messages.
319 * This queue should be checked whenever a request is received. If the
320 * response is allready in the queue that response should be transmitted.
321 * It should be possible to find messages in this queue on the basis of
322 * the sequence number and peer GSN IP address (The sequense number is unique
323 * within each path). This need to be implemented by a hash table. Furthermore
324 * it should be possibly to delete messages based on a timeout. This can be
325 * achieved by means of a linked list. The timeout value need to be larger
326 * than T3-RESPONSE * N3-REQUESTS (recommended value 5). These timers are
327 * set in the peer GSN, so there is no way to know these parameters. On the
328 * other hand the timeout value need to be so small that we do not receive
329 * wraparound sequence numbere before the message is deleted. 60 seconds is
330 * probably not a bad choise.
332 * This queue however is first really needed from gtp1.
334 * gtp_req:
335 * Send off a signalling message with appropiate sequence
336 * number. Store packet in queue.
337 * gtp_conf:
338 * Remove an incoming confirmation from the queue
339 * gtp_resp:
340 * Send off a response to a request. Use the same sequence
341 * number in the response as in the request.
342 * gtp_notification:
343 * Send off a notification message. This is neither a request nor
344 * a response. Both TEI and SEQ are zero.
345 * gtp_retrans:
346 * Retransmit any outstanding packets which have exceeded
347 * a predefined timeout.
348 *************************************************************/
350 int gtp_req(struct gsn_t *gsn, int version, struct pdp_t *pdp,
351 union gtp_packet *packet, int len,
352 struct in_addr *inetaddr, void *cbp)
354 struct sockaddr_in addr;
355 struct qmsg_t *qmsg;
356 int fd;
358 memset(&addr, 0, sizeof(addr));
359 addr.sin_family = AF_INET;
360 addr.sin_addr = *inetaddr;
361 #if defined(__FreeBSD__) || defined(__APPLE__)
362 addr.sin_len = sizeof(addr);
363 #endif
365 if ((packet->flags & 0xe0) == 0x00) { /* Version 0 */
366 addr.sin_port = htons(GTP0_PORT);
367 packet->gtp0.h.length = hton16(len - GTP0_HEADER_SIZE);
368 packet->gtp0.h.seq = hton16(gsn->seq_next);
369 if (pdp) {
370 packet->gtp0.h.tid =
371 htobe64(pdp_gettid(pdp->imsi, pdp->nsapi));
373 if (pdp && ((packet->gtp0.h.type == GTP_GPDU)
374 || (packet->gtp0.h.type == GTP_ERROR)))
375 packet->gtp0.h.flow = hton16(pdp->flru);
376 else if (pdp)
377 packet->gtp0.h.flow = hton16(pdp->flrc);
378 fd = gsn->fd0;
379 } else if ((packet->flags & 0xe2) == 0x22) { /* Version 1 with seq */
380 addr.sin_port = htons(GTP1C_PORT);
381 packet->gtp1l.h.length = hton16(len - GTP1_HEADER_SIZE_SHORT);
382 packet->gtp1l.h.seq = hton16(gsn->seq_next);
383 if (pdp && ((packet->gtp1l.h.type == GTP_GPDU) ||
384 (packet->gtp1l.h.type == GTP_ERROR)))
385 packet->gtp1l.h.tei = hton32(pdp->teid_gn);
386 else if (pdp)
387 packet->gtp1l.h.tei = hton32(pdp->teic_gn);
388 fd = gsn->fd1c;
389 } else {
390 LOGP(DLGTP, LOGL_ERROR, "Unknown packet flags: 0x%02x\n", packet->flags);
391 return -1;
394 if (sendto(fd, packet, len, 0,
395 (struct sockaddr *)&addr, sizeof(addr)) < 0) {
396 gsn->err_sendto++;
397 LOGP(DLGTP, LOGL_ERROR,
398 "Sendto(fd=%d, msg=%lx, len=%d) failed: Error = %s\n", fd,
399 (unsigned long)&packet, len, strerror(errno));
400 return -1;
403 /* Use new queue structure */
404 if (queue_newmsg(gsn->queue_req, &qmsg, &addr, gsn->seq_next)) {
405 gsn->err_queuefull++;
406 LOGP(DLGTP, LOGL_ERROR,
407 "Retransmit queue is full\n");
408 } else {
409 memcpy(&qmsg->p, packet, sizeof(union gtp_packet));
410 qmsg->l = len;
411 qmsg->timeout = time(NULL) + T3_REQUEST; /* When to timeout */
412 qmsg->retrans = 0; /* No retransmissions so far */
413 qmsg->cbp = cbp;
414 qmsg->type = ntoh8(packet->gtp0.h.type);
415 qmsg->fd = fd;
417 gsn->seq_next++; /* Count up this time */
418 return 0;
421 /* gtp_conf
422 * Remove signalling packet from retransmission queue.
423 * return 0 on success, EOF if packet was not found */
425 int gtp_conf(struct gsn_t *gsn, int version, struct sockaddr_in *peer,
426 union gtp_packet *packet, int len, uint8_t * type, void **cbp)
429 uint16_t seq;
431 if ((packet->gtp0.h.flags & 0xe0) == 0x00)
432 seq = ntoh16(packet->gtp0.h.seq);
433 else if ((packet->gtp1l.h.flags & 0xe2) == 0x22)
434 seq = ntoh16(packet->gtp1l.h.seq);
435 else {
436 GTP_LOGPKG(LOGL_ERROR, peer, packet, len,
437 "Unknown GTP packet version\n");
438 return EOF;
441 if (queue_freemsg_seq(gsn->queue_req, peer, seq, type, cbp)) {
442 gsn->err_seq++;
443 GTP_LOGPKG(LOGL_ERROR, peer, packet, len,
444 "Confirmation packet not found in queue\n");
445 return EOF;
448 return 0;
451 int gtp_retrans(struct gsn_t *gsn)
453 /* Retransmit any outstanding packets */
454 /* Remove from queue if maxretrans exceeded */
455 time_t now;
456 struct qmsg_t *qmsg;
457 now = time(NULL);
458 /*printf("Retrans: New beginning %d\n", (int) now); */
460 /* get first element in queue, as long as the timeout of that
461 * element has expired */
462 while ((!queue_getfirst(gsn->queue_req, &qmsg)) &&
463 (qmsg->timeout <= now)) {
464 /*printf("Retrans timeout found: %d\n", (int) time(NULL)); */
465 if (qmsg->retrans > N3_REQUESTS) { /* To many retrans */
466 if (gsn->cb_conf)
467 gsn->cb_conf(qmsg->type, EOF, NULL, qmsg->cbp);
468 queue_freemsg(gsn->queue_req, qmsg);
469 } else {
470 if (sendto(qmsg->fd, &qmsg->p, qmsg->l, 0,
471 (struct sockaddr *)&qmsg->peer,
472 sizeof(struct sockaddr_in)) < 0) {
473 gsn->err_sendto++;
474 LOGP(DLGTP, LOGL_ERROR,
475 "Sendto(fd0=%d, msg=%lx, len=%d) failed: Error = %s\n",
476 gsn->fd0, (unsigned long)&qmsg->p,
477 qmsg->l, strerror(errno));
479 queue_back(gsn->queue_req, qmsg);
480 qmsg->timeout = now + T3_REQUEST;
481 qmsg->retrans++;
485 /* Also clean up reply timeouts */
486 while ((!queue_getfirst(gsn->queue_resp, &qmsg)) &&
487 (qmsg->timeout < now)) {
488 /*printf("Retrans (reply) timeout found: %d\n", (int) time(NULL)); */
489 queue_freemsg(gsn->queue_resp, qmsg);
492 return 0;
495 int gtp_retranstimeout(struct gsn_t *gsn, struct timeval *timeout)
497 time_t now, later;
498 struct qmsg_t *qmsg;
500 if (queue_getfirst(gsn->queue_req, &qmsg)) {
501 timeout->tv_sec = 10;
502 timeout->tv_usec = 0;
503 } else {
504 now = time(NULL);
505 later = qmsg->timeout;
506 timeout->tv_sec = later - now;
507 timeout->tv_usec = 0;
508 if (timeout->tv_sec < 0)
509 timeout->tv_sec = 0; /* No negative allowed */
510 if (timeout->tv_sec > 10)
511 timeout->tv_sec = 10; /* Max sleep for 10 sec */
513 return 0;
516 int gtp_resp(int version, struct gsn_t *gsn, struct pdp_t *pdp,
517 union gtp_packet *packet, int len,
518 struct sockaddr_in *peer, int fd, uint16_t seq, uint64_t tid)
520 struct qmsg_t *qmsg;
522 if ((packet->flags & 0xe0) == 0x00) { /* Version 0 */
523 packet->gtp0.h.length = hton16(len - GTP0_HEADER_SIZE);
524 packet->gtp0.h.seq = hton16(seq);
525 packet->gtp0.h.tid = htobe64(tid);
526 if (pdp && ((packet->gtp0.h.type == GTP_GPDU) ||
527 (packet->gtp0.h.type == GTP_ERROR)))
528 packet->gtp0.h.flow = hton16(pdp->flru);
529 else if (pdp)
530 packet->gtp0.h.flow = hton16(pdp->flrc);
531 } else if ((packet->flags & 0xe2) == 0x22) { /* Version 1 with seq */
532 packet->gtp1l.h.length = hton16(len - GTP1_HEADER_SIZE_SHORT);
533 packet->gtp1l.h.seq = hton16(seq);
534 if (pdp && (fd == gsn->fd1u))
535 packet->gtp1l.h.tei = hton32(pdp->teid_gn);
536 else if (pdp)
537 packet->gtp1l.h.tei = hton32(pdp->teic_gn);
538 } else {
539 LOGP(DLGTP, LOGL_ERROR, "Unknown packet flags: 0x%02x\n", packet->flags);
540 return -1;
543 if (fcntl(fd, F_SETFL, 0)) {
544 LOGP(DLGTP, LOGL_ERROR, "fnctl()\n");
545 return -1;
548 if (sendto(fd, packet, len, 0,
549 (struct sockaddr *)peer, sizeof(struct sockaddr_in)) < 0) {
550 gsn->err_sendto++;
551 LOGP(DLGTP, LOGL_ERROR,
552 "Sendto(fd=%d, msg=%lx, len=%d) failed: Error = %s\n", fd,
553 (unsigned long)&packet, len, strerror(errno));
554 return -1;
557 /* Use new queue structure */
558 if (queue_newmsg(gsn->queue_resp, &qmsg, peer, seq)) {
559 gsn->err_queuefull++;
560 LOGP(DLGTP, LOGL_ERROR, "Retransmit queue is full\n");
561 } else {
562 memcpy(&qmsg->p, packet, sizeof(union gtp_packet));
563 qmsg->l = len;
564 qmsg->timeout = time(NULL) + 60; /* When to timeout */
565 qmsg->retrans = 0; /* No retransmissions so far */
566 qmsg->cbp = NULL;
567 qmsg->type = 0;
568 qmsg->fd = fd;
570 return 0;
573 int gtp_notification(struct gsn_t *gsn, int version,
574 union gtp_packet *packet, int len,
575 struct sockaddr_in *peer, int fd, uint16_t seq)
578 struct sockaddr_in addr;
580 memcpy(&addr, peer, sizeof(addr));
582 /* In GTP0 notifications are treated as replies. In GTP1 they
583 are requests for which there is no reply */
585 if (fd == gsn->fd1c)
586 addr.sin_port = htons(GTP1C_PORT);
587 else if (fd == gsn->fd1u)
588 addr.sin_port = htons(GTP1C_PORT);
590 if ((packet->flags & 0xe0) == 0x00) { /* Version 0 */
591 packet->gtp0.h.length = hton16(len - GTP0_HEADER_SIZE);
592 packet->gtp0.h.seq = hton16(seq);
593 } else if ((packet->flags & 0xe2) == 0x22) { /* Version 1 with seq */
594 packet->gtp1l.h.length = hton16(len - GTP1_HEADER_SIZE_SHORT);
595 packet->gtp1l.h.seq = hton16(seq);
596 } else {
597 LOGP(DLGTP, LOGL_ERROR, "Unknown packet flags: 0x%02x\n", packet->flags);
598 return -1;
601 if (fcntl(fd, F_SETFL, 0)) {
602 LOGP(DLGTP, LOGL_ERROR, "fnctl()\n");
603 return -1;
606 if (sendto(fd, packet, len, 0,
607 (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0) {
608 gsn->err_sendto++;
609 LOGP(DLGTP, LOGL_ERROR,
610 "Sendto(fd=%d, msg=%lx, len=%d) failed: Error = %s\n", fd,
611 (unsigned long)&packet, len, strerror(errno));
612 return -1;
614 return 0;
617 int gtp_dublicate(struct gsn_t *gsn, int version,
618 struct sockaddr_in *peer, uint16_t seq)
620 struct qmsg_t *qmsg;
622 if (queue_seqget(gsn->queue_resp, &qmsg, peer, seq)) {
623 return EOF; /* Notfound */
626 if (fcntl(qmsg->fd, F_SETFL, 0)) {
627 LOGP(DLGTP, LOGL_ERROR, "fnctl()\n");
628 return -1;
631 if (sendto(qmsg->fd, &qmsg->p, qmsg->l, 0,
632 (struct sockaddr *)peer, sizeof(struct sockaddr_in)) < 0) {
633 gsn->err_sendto++;
634 LOGP(DLGTP, LOGL_ERROR,
635 "Sendto(fd=%d, msg=%lx, len=%d) failed: Error = %s\n",
636 qmsg->fd, (unsigned long)&qmsg->p, qmsg->l,
637 strerror(errno));
639 return 0;
642 /* Perform restoration and recovery error handling as described in 29.060 */
643 static void log_restart(struct gsn_t *gsn)
645 FILE *f;
646 int i, rc;
647 int counter = 0;
648 char *filename;
650 filename = talloc_asprintf(NULL, "%s/%s", gsn->statedir, RESTART_FILE);
651 OSMO_ASSERT(filename);
653 /* We try to open file. On failure we will later try to create file */
654 if (!(f = fopen(filename, "r"))) {
655 LOGP(DLGTP, LOGL_NOTICE,
656 "State information file (%s) not found. Creating new file.\n",
657 filename);
658 } else {
659 rc = fscanf(f, "%d", &counter);
660 if (rc != 1) {
661 LOGP(DLGTP, LOGL_ERROR,
662 "fscanf failed to read counter value\n");
663 goto close_file;
665 if (fclose(f)) {
666 LOGP(DLGTP, LOGL_ERROR,
667 "fclose failed: Error = %s\n", strerror(errno));
671 gsn->restart_counter = (unsigned char)counter;
672 gsn->restart_counter++;
674 /* Keep the umask closely wrapped around our fopen() call in case the
675 * log outputs cause file creation. */
676 i = umask(022);
677 f = fopen(filename, "w");
678 umask(i);
679 if (!f) {
680 LOGP(DLGTP, LOGL_ERROR,
681 "fopen(path=%s, mode=%s) failed: Error = %s\n", filename,
682 "w", strerror(errno));
683 goto free_filename;
686 fprintf(f, "%d\n", gsn->restart_counter);
687 close_file:
688 if (fclose(f))
689 LOGP(DLGTP, LOGL_ERROR,
690 "fclose failed: Error = %s\n", strerror(errno));
691 free_filename:
692 talloc_free(filename);
695 int gtp_new(struct gsn_t **gsn, char *statedir, struct in_addr *listen,
696 int mode)
698 struct sockaddr_in addr;
700 LOGP(DLGTP, LOGL_NOTICE, "GTP: gtp_newgsn() started\n");
702 *gsn = calloc(sizeof(struct gsn_t), 1); /* TODO */
704 (*gsn)->statedir = statedir;
705 log_restart(*gsn);
707 /* Initialise sequence number */
708 (*gsn)->seq_next = (*gsn)->restart_counter * 1024;
710 /* Initialise request retransmit queue */
711 queue_new(&(*gsn)->queue_req);
712 queue_new(&(*gsn)->queue_resp);
714 /* Initialise pdp table */
715 pdp_init();
717 /* Initialise call back functions */
718 (*gsn)->cb_create_context_ind = 0;
719 (*gsn)->cb_delete_context = 0;
720 (*gsn)->cb_unsup_ind = 0;
721 (*gsn)->cb_conf = 0;
722 (*gsn)->cb_data_ind = 0;
724 /* Store function parameters */
725 (*gsn)->gsnc = *listen;
726 (*gsn)->gsnu = *listen;
727 (*gsn)->mode = mode;
729 /* Create GTP version 0 socket */
730 if (((*gsn)->fd0 = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
731 (*gsn)->err_socket++;
732 LOGP(DLGTP, LOGL_ERROR,
733 "socket(domain=%d, type=%d, protocol=%d) failed: Error = %s\n",
734 AF_INET, SOCK_DGRAM, 0, strerror(errno));
735 return -1;
738 memset(&addr, 0, sizeof(addr));
739 addr.sin_family = AF_INET;
740 addr.sin_addr = *listen; /* Same IP for user traffic and signalling */
741 addr.sin_port = htons(GTP0_PORT);
742 #if defined(__FreeBSD__) || defined(__APPLE__)
743 addr.sin_len = sizeof(addr);
744 #endif
746 if (bind((*gsn)->fd0, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
747 (*gsn)->err_socket++;
748 LOGP_WITH_ADDR(DLGTP, LOGL_ERROR, addr,
749 "bind(fd0=%d) failed: Error = %s\n",
750 (*gsn)->fd0, strerror(errno));
751 return -1;
754 /* Create GTP version 1 control plane socket */
755 if (((*gsn)->fd1c = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
756 (*gsn)->err_socket++;
757 LOGP(DLGTP, LOGL_ERROR,
758 "socket(domain=%d, type=%d, protocol=%d) failed: Error = %s\n",
759 AF_INET, SOCK_DGRAM, 0, strerror(errno));
760 return -1;
763 memset(&addr, 0, sizeof(addr));
764 addr.sin_family = AF_INET;
765 addr.sin_addr = *listen; /* Same IP for user traffic and signalling */
766 addr.sin_port = htons(GTP1C_PORT);
767 #if defined(__FreeBSD__) || defined(__APPLE__)
768 addr.sin_len = sizeof(addr);
769 #endif
771 if (bind((*gsn)->fd1c, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
772 (*gsn)->err_socket++;
773 LOGP_WITH_ADDR(DLGTP, LOGL_ERROR, addr,
774 "bind(fd1c=%d) failed: Error = %s\n",
775 (*gsn)->fd1c, strerror(errno));
776 return -1;
779 /* Create GTP version 1 user plane socket */
780 if (((*gsn)->fd1u = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
781 (*gsn)->err_socket++;
782 LOGP(DLGTP, LOGL_ERROR,
783 "socket(domain=%d, type=%d, protocol=%d) failed: Error = %s\n",
784 AF_INET, SOCK_DGRAM, 0, strerror(errno));
785 return -1;
788 memset(&addr, 0, sizeof(addr));
789 addr.sin_family = AF_INET;
790 addr.sin_addr = *listen; /* Same IP for user traffic and signalling */
791 addr.sin_port = htons(GTP1U_PORT);
792 #if defined(__FreeBSD__) || defined(__APPLE__)
793 addr.sin_len = sizeof(addr);
794 #endif
796 if (bind((*gsn)->fd1u, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
797 (*gsn)->err_socket++;
798 LOGP_WITH_ADDR(DLGTP, LOGL_ERROR, addr,
799 "bind(fd1u=%d) failed: Error = %s\n",
800 (*gsn)->fd1u, strerror(errno));
801 return -1;
804 return 0;
807 int gtp_free(struct gsn_t *gsn)
810 /* Clean up retransmit queues */
811 queue_free(gsn->queue_req);
812 queue_free(gsn->queue_resp);
814 close(gsn->fd0);
815 close(gsn->fd1c);
816 close(gsn->fd1u);
818 free(gsn);
819 return 0;
822 /* ***********************************************************
823 * Path management messages
824 * Messages: echo and version not supported.
825 * A path is connection between two UDP/IP endpoints
827 * A path is either using GTP0 or GTP1. A path can be
828 * established by any kind of GTP message??
830 * Which source port to use?
831 * GTP-C request destination port is 2123/3386
832 * GTP-U request destination port is 2152/3386
833 * T-PDU destination port is 2152/3386.
834 * For the above messages the source port is locally allocated.
835 * For response messages src=rx-dst and dst=rx-src.
836 * For simplicity we should probably use 2123+2152/3386 as
837 * src port even for the cases where src can be locally
838 * allocated. This also means that we have to listen only to
839 * the same ports.
840 * For response messages we need to be able to respond to
841 * the relevant src port even if it is locally allocated by
842 * the peer.
844 * The need for path management!
845 * We might need to keep a list of active paths. This might
846 * be in the form of remote IP address + UDP port numbers.
847 * (We will consider a path astablished if we have a context
848 * with the node in question)
849 *************************************************************/
851 /* Send off an echo request */
852 int gtp_echo_req(struct gsn_t *gsn, int version, void *cbp,
853 struct in_addr *inetaddr)
855 union gtp_packet packet;
856 unsigned int length = get_default_gtp(version, GTP_ECHO_REQ, &packet);
857 return gtp_req(gsn, version, NULL, &packet, length, inetaddr, cbp);
860 /* Send off an echo reply */
861 int gtp_echo_resp(struct gsn_t *gsn, int version,
862 struct sockaddr_in *peer, int fd, void *pack, unsigned len)
864 union gtp_packet packet;
865 unsigned int length = get_default_gtp(version, GTP_ECHO_RSP, &packet);
866 gtpie_tv1(&packet, &length, GTP_MAX, GTPIE_RECOVERY,
867 gsn->restart_counter);
868 return gtp_resp(version, gsn, NULL, &packet, length, peer, fd,
869 get_seq(pack), get_tid(pack));
872 /* Handle a received echo request */
873 int gtp_echo_ind(struct gsn_t *gsn, int version, struct sockaddr_in *peer,
874 int fd, void *pack, unsigned len)
877 /* Check if it was a dublicate request */
878 if (!gtp_dublicate(gsn, 0, peer, get_seq(pack)))
879 return 0;
881 /* Send off reply to request */
882 return gtp_echo_resp(gsn, version, peer, fd, pack, len);
885 /* Handle a received echo reply */
886 int gtp_echo_conf(struct gsn_t *gsn, int version, struct sockaddr_in *peer,
887 void *pack, unsigned len)
889 union gtpie_member *ie[GTPIE_SIZE];
890 unsigned char recovery;
891 void *cbp = NULL;
892 uint8_t type = 0;
893 int hlen = get_hlen(pack);
895 /* Remove packet from queue */
896 if (gtp_conf(gsn, version, peer, pack, len, &type, &cbp))
897 return EOF;
899 /* Extract information elements into a pointer array */
900 if (gtpie_decaps(ie, version, pack + hlen, len - hlen)) {
901 gsn->invalid++;
902 GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
903 "Invalid message format\n");
904 if (gsn->cb_conf)
905 gsn->cb_conf(type, EOF, NULL, cbp);
906 return EOF;
909 if (gtpie_gettv1(ie, GTPIE_RECOVERY, 0, &recovery)) {
910 gsn->missing++;
911 GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
912 "Missing mandatory field\n");
913 if (gsn->cb_conf)
914 gsn->cb_conf(type, EOF, NULL, cbp);
915 return EOF;
918 /* Echo reply packages does not have a cause information element */
919 /* Instead we return the recovery number in the callback function */
920 if (gsn->cb_conf)
921 gsn->cb_conf(type, recovery, NULL, cbp);
923 if (gsn->cb_recovery)
924 gsn->cb_recovery(peer, recovery);
926 return 0;
929 /* Send off a Version Not Supported message */
930 /* This message is somewhat special in that it actually is a
931 * response to some other message with unsupported GTP version
932 * For this reason it has parameters like a response, and does
933 * its own message transmission. No signalling queue is used
934 * The reply is sent to the peer IP and peer UDP. This means that
935 * the peer will be receiving a GTP0 message on a GTP1 port!
936 * In practice however this will never happen as a GTP0 GSN will
937 * only listen to the GTP0 port, and therefore will never receive
938 * anything else than GTP0 */
940 int gtp_unsup_req(struct gsn_t *gsn, int version, struct sockaddr_in *peer,
941 int fd, void *pack, unsigned len)
943 union gtp_packet packet;
945 /* GTP 1 is the highest supported protocol */
946 unsigned int length = get_default_gtp(1, GTP_NOT_SUPPORTED, &packet);
947 return gtp_notification(gsn, version, &packet, length, peer, fd, 0);
950 /* Handle a Version Not Supported message */
951 int gtp_unsup_ind(struct gsn_t *gsn, struct sockaddr_in *peer,
952 void *pack, unsigned len)
955 if (gsn->cb_unsup_ind)
956 gsn->cb_unsup_ind(peer);
958 return 0;
961 /* Send off an Supported Extension Headers Notification */
962 int gtp_extheader_req(struct gsn_t *gsn, int version, struct sockaddr_in *peer,
963 int fd, void *pack, unsigned len)
965 union gtp_packet packet;
966 unsigned int length =
967 get_default_gtp(version, GTP_SUPP_EXT_HEADER, &packet);
969 uint8_t pdcp_pdu = GTP_EXT_PDCP_PDU;
971 if (version < 1)
972 return 0;
974 /* We report back that we support only PDCP PDU headers */
975 gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_EXT_HEADER_T,
976 sizeof(pdcp_pdu), &pdcp_pdu);
978 return gtp_notification(gsn, version, &packet, length,
979 peer, fd, get_seq(pack));
982 /* Handle a Supported Extension Headers Notification */
983 int gtp_extheader_ind(struct gsn_t *gsn, struct sockaddr_in *peer,
984 void *pack, unsigned len)
987 if (gsn->cb_extheader_ind)
988 gsn->cb_extheader_ind(peer);
990 return 0;
993 /* ***********************************************************
994 * Session management messages
995 * Messages: create, update and delete PDP context
997 * Information storage
998 * Information storage for each PDP context is defined in
999 * 23.060 section 13.3. Includes IMSI, MSISDN, APN, PDP-type,
1000 * PDP-address (IP address), sequence numbers, charging ID.
1001 * For the SGSN it also includes radio related mobility
1002 * information.
1003 *************************************************************/
1005 /* API: Send Create PDP Context Request (7.3.1) */
1006 extern int gtp_create_context_req(struct gsn_t *gsn, struct pdp_t *pdp,
1007 void *cbp)
1009 union gtp_packet packet;
1010 unsigned int length =
1011 get_default_gtp(pdp->version, GTP_CREATE_PDP_REQ, &packet);
1012 struct pdp_t *linked_pdp = NULL;
1014 /* TODO: Secondary PDP Context Activation Procedure */
1015 /* In secondary activation procedure the PDP context is identified
1016 by tei in the header. The following fields are omitted: Selection
1017 mode, IMSI, MSISDN, End User Address, Access Point Name and
1018 Protocol Configuration Options */
1020 if (pdp->secondary) {
1021 if (pdp_getgtp1(&linked_pdp, pdp->teic_own)) {
1022 LOGP(DLGTP, LOGL_ERROR,
1023 "Unknown linked PDP context: %u\n", pdp->teic_own);
1024 return EOF;
1028 if (pdp->version == 0) {
1029 gtpie_tv0(&packet, &length, GTP_MAX, GTPIE_QOS_PROFILE0,
1030 sizeof(pdp->qos_req0), pdp->qos_req0);
1033 /* Section 7.7.2 */
1034 if (pdp->version == 1) {
1035 if (!pdp->secondary) /* Not Secondary PDP Context Activation Procedure */
1036 gtpie_tv0(&packet, &length, GTP_MAX, GTPIE_IMSI,
1037 sizeof(pdp->imsi), (uint8_t *) & pdp->imsi);
1040 /* Section 7.7.3 Routing Area Information */
1041 if (pdp->rai_given == 1)
1042 gtpie_tv0(&packet, &length, GTP_MAX, GTPIE_RAI,
1043 pdp->rai.l, (uint8_t *) & pdp->rai.v);
1045 /* Section 7.7.11 */
1046 if (pdp->norecovery_given == 0)
1047 gtpie_tv1(&packet, &length, GTP_MAX, GTPIE_RECOVERY,
1048 gsn->restart_counter);
1050 /* Section 7.7.12 */
1051 if (!pdp->secondary) /* Not Secondary PDP Context Activation Procedure */
1052 gtpie_tv1(&packet, &length, GTP_MAX, GTPIE_SELECTION_MODE,
1053 pdp->selmode);
1055 if (pdp->version == 0) {
1056 gtpie_tv2(&packet, &length, GTP_MAX, GTPIE_FL_DI, pdp->fllu);
1057 gtpie_tv2(&packet, &length, GTP_MAX, GTPIE_FL_C, pdp->fllc);
1060 /* Section 7.7.13 */
1061 if (pdp->version == 1) {
1062 gtpie_tv4(&packet, &length, GTP_MAX, GTPIE_TEI_DI,
1063 pdp->teid_own);
1065 /* Section 7.7.14 */
1066 if (!pdp->teic_confirmed)
1067 gtpie_tv4(&packet, &length, GTP_MAX, GTPIE_TEI_C,
1068 pdp->teic_own);
1070 /* Section 7.7.17 */
1071 gtpie_tv1(&packet, &length, GTP_MAX, GTPIE_NSAPI, pdp->nsapi);
1073 /* Section 7.7.17 */
1074 if (pdp->secondary) /* Secondary PDP Context Activation Procedure */
1075 gtpie_tv1(&packet, &length, GTP_MAX, GTPIE_NSAPI,
1076 linked_pdp->nsapi);
1078 /* Section 7.7.23 */
1079 if (pdp->cch_pdp) /* Only include charging if flags are set */
1080 gtpie_tv2(&packet, &length, GTP_MAX, GTPIE_CHARGING_C,
1081 pdp->cch_pdp);
1084 /* TODO
1085 gtpie_tv2(&packet, &length, GTP_MAX, GTPIE_TRACE_REF,
1086 pdp->traceref);
1087 gtpie_tv2(&packet, &length, GTP_MAX, GTPIE_TRACE_TYPE,
1088 pdp->tracetype); */
1090 /* Section 7.7.27 */
1091 if (!pdp->secondary) /* Not Secondary PDP Context Activation Procedure */
1092 gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_EUA,
1093 pdp->eua.l, pdp->eua.v);
1095 /* Section 7.7.30 */
1096 if (!pdp->secondary) /* Not Secondary PDP Context Activation Procedure */
1097 gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_APN,
1098 pdp->apn_use.l, pdp->apn_use.v);
1100 /* Section 7.7.31 */
1101 if (!pdp->secondary) /* Not Secondary PDP Context Activation Procedure */
1102 if (pdp->pco_req.l)
1103 gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_PCO,
1104 pdp->pco_req.l, pdp->pco_req.v);
1106 /* Section 7.7.32 */
1107 gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_GSN_ADDR,
1108 pdp->gsnlc.l, pdp->gsnlc.v);
1109 /* Section 7.7.32 */
1110 gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_GSN_ADDR,
1111 pdp->gsnlu.l, pdp->gsnlu.v);
1113 /* Section 7.7.33 */
1114 if (!pdp->secondary) /* Not Secondary PDP Context Activation Procedure */
1115 gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_MSISDN,
1116 pdp->msisdn.l, pdp->msisdn.v);
1118 /* Section 7.7.34 */
1119 if (pdp->version == 1)
1120 gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_QOS_PROFILE,
1121 pdp->qos_req.l, pdp->qos_req.v);
1123 /* Section 7.7.36 */
1124 if ((pdp->version == 1) && pdp->tft.l)
1125 gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_TFT,
1126 pdp->tft.l, pdp->tft.v);
1128 /* Section 7.7.41 */
1129 if ((pdp->version == 1) && pdp->triggerid.l)
1130 gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_TRIGGER_ID,
1131 pdp->triggerid.l, pdp->triggerid.v);
1133 /* Section 7.7.42 */
1134 if ((pdp->version == 1) && pdp->omcid.l)
1135 gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_OMC_ID,
1136 pdp->omcid.l, pdp->omcid.v);
1138 /* new R7 fields */
1139 if (pdp->rattype_given == 1)
1140 gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_RAT_TYPE,
1141 pdp->rattype.l, pdp->rattype.v);
1143 if (pdp->userloc_given == 1)
1144 gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_USER_LOC,
1145 pdp->userloc.l, pdp->userloc.v);
1147 if (pdp->mstz_given == 1)
1148 gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_MS_TZ,
1149 pdp->mstz.l, pdp->mstz.v);
1151 if (pdp->imeisv_given == 1)
1152 gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_IMEI_SV,
1153 pdp->imeisv.l, pdp->imeisv.v);
1155 /* TODO hisaddr0 */
1156 gtp_req(gsn, pdp->version, pdp, &packet, length, &pdp->hisaddr0, cbp);
1158 return 0;
1161 /* API: Application response to context indication */
1162 int gtp_create_context_resp(struct gsn_t *gsn, struct pdp_t *pdp, int cause)
1165 /* Now send off a reply to the peer */
1166 gtp_create_pdp_resp(gsn, pdp->version, pdp, cause);
1168 if (cause != GTPCAUSE_ACC_REQ) {
1169 pdp_freepdp(pdp);
1172 return 0;
1175 /* API: Register create context indication callback */
1176 int gtp_set_cb_create_context_ind(struct gsn_t *gsn,
1177 int (*cb_create_context_ind) (struct pdp_t *
1178 pdp))
1180 gsn->cb_create_context_ind = cb_create_context_ind;
1181 return 0;
1184 /* Send Create PDP Context Response */
1185 int gtp_create_pdp_resp(struct gsn_t *gsn, int version, struct pdp_t *pdp,
1186 uint8_t cause)
1188 union gtp_packet packet;
1189 unsigned int length =
1190 get_default_gtp(version, GTP_CREATE_PDP_RSP, &packet);
1192 gtpie_tv1(&packet, &length, GTP_MAX, GTPIE_CAUSE, cause);
1194 if (cause == GTPCAUSE_ACC_REQ) {
1196 if (version == 0)
1197 gtpie_tv0(&packet, &length, GTP_MAX, GTPIE_QOS_PROFILE0,
1198 sizeof(pdp->qos_neg0), pdp->qos_neg0);
1200 gtpie_tv1(&packet, &length, GTP_MAX, GTPIE_REORDER,
1201 pdp->reorder);
1202 gtpie_tv1(&packet, &length, GTP_MAX, GTPIE_RECOVERY,
1203 gsn->restart_counter);
1205 if (version == 0) {
1206 gtpie_tv2(&packet, &length, GTP_MAX, GTPIE_FL_DI,
1207 pdp->fllu);
1208 gtpie_tv2(&packet, &length, GTP_MAX, GTPIE_FL_C,
1209 pdp->fllc);
1212 if (version == 1) {
1213 gtpie_tv4(&packet, &length, GTP_MAX, GTPIE_TEI_DI,
1214 pdp->teid_own);
1215 gtpie_tv4(&packet, &length, GTP_MAX, GTPIE_TEI_C,
1216 pdp->teic_own);
1219 /* TODO: We use teic_own as charging ID */
1220 gtpie_tv4(&packet, &length, GTP_MAX, GTPIE_CHARGING_ID,
1221 pdp->teic_own);
1223 gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_EUA,
1224 pdp->eua.l, pdp->eua.v);
1226 if (pdp->pco_neg.l) { /* Optional PCO */
1227 gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_PCO,
1228 pdp->pco_neg.l, pdp->pco_neg.v);
1231 gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_GSN_ADDR,
1232 pdp->gsnlc.l, pdp->gsnlc.v);
1233 gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_GSN_ADDR,
1234 pdp->gsnlu.l, pdp->gsnlu.v);
1236 if (version == 1)
1237 gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_QOS_PROFILE,
1238 pdp->qos_neg.l, pdp->qos_neg.v);
1240 /* TODO: Charging gateway address */
1243 return gtp_resp(version, gsn, pdp, &packet, length, &pdp->sa_peer,
1244 pdp->fd, pdp->seq, pdp->tid);
1247 /* Handle Create PDP Context Request */
1248 int gtp_create_pdp_ind(struct gsn_t *gsn, int version,
1249 struct sockaddr_in *peer, int fd,
1250 void *pack, unsigned len)
1252 struct pdp_t *pdp, *pdp_old;
1253 struct pdp_t pdp_buf;
1254 union gtpie_member *ie[GTPIE_SIZE];
1255 uint8_t recovery;
1257 uint16_t seq = get_seq(pack);
1258 int hlen = get_hlen(pack);
1259 uint8_t linked_nsapi = 0;
1260 struct pdp_t *linked_pdp = NULL;
1262 if (!gtp_dublicate(gsn, version, peer, seq))
1263 return 0;
1265 pdp = &pdp_buf;
1266 memset(pdp, 0, sizeof(struct pdp_t));
1268 if (version == 0) {
1269 uint64_t tid = be64toh(((union gtp_packet *)pack)->gtp0.h.tid);
1271 pdp_set_imsi_nsapi(pdp, tid);
1274 pdp->seq = seq;
1275 pdp->sa_peer = *peer;
1276 pdp->fd = fd;
1277 pdp->version = version;
1279 /* Decode information elements */
1280 if (gtpie_decaps(ie, version, pack + hlen, len - hlen)) {
1281 gsn->invalid++;
1282 GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
1283 "Invalid message format\n");
1284 if (0 == version)
1285 return EOF;
1286 else
1287 return gtp_create_pdp_resp(gsn, version, pdp,
1288 GTPCAUSE_INVALID_MESSAGE);
1291 if (version == 1) {
1292 /* Linked NSAPI (conditional) */
1293 /* If included this is the Secondary PDP Context Activation Procedure */
1294 /* In secondary activation IMSI is not included, so the context must be */
1295 /* identified by the tei */
1296 if (!gtpie_gettv1(ie, GTPIE_NSAPI, 1, &linked_nsapi)) {
1298 /* Find the primary PDP context */
1299 if (pdp_getgtp1(&linked_pdp, get_tei(pack))) {
1300 gsn->incorrect++;
1301 GTP_LOGPKG(LOGL_ERROR, peer,
1302 pack, len,
1303 "Incorrect optional information field\n");
1304 return gtp_create_pdp_resp(gsn, version, pdp,
1305 GTPCAUSE_OPT_IE_INCORRECT);
1308 /* Check that the primary PDP context matches linked nsapi */
1309 if (linked_pdp->nsapi != linked_nsapi) {
1310 gsn->incorrect++;
1311 GTP_LOGPKG(LOGL_ERROR, peer,
1312 pack, len,
1313 "Incorrect optional information field\n");
1314 return gtp_create_pdp_resp(gsn, version, pdp,
1315 GTPCAUSE_OPT_IE_INCORRECT);
1318 /* Copy parameters from primary context */
1319 pdp->selmode = linked_pdp->selmode;
1320 pdp->imsi = linked_pdp->imsi;
1321 pdp->msisdn = linked_pdp->msisdn;
1322 pdp->eua = linked_pdp->eua;
1323 pdp->pco_req = linked_pdp->pco_req;
1324 pdp->apn_req = linked_pdp->apn_req;
1325 pdp->teic_gn = linked_pdp->teic_gn;
1326 pdp->secondary = 1;
1329 /* if (version == 1) */
1330 if (version == 0) {
1331 if (gtpie_gettv0(ie, GTPIE_QOS_PROFILE0, 0,
1332 pdp->qos_req0, sizeof(pdp->qos_req0))) {
1333 gsn->missing++;
1334 GTP_LOGPKG(LOGL_ERROR, peer, pack,
1335 len, "Missing mandatory information field\n");
1336 return gtp_create_pdp_resp(gsn, version, pdp,
1337 GTPCAUSE_MAN_IE_MISSING);
1341 if ((version == 1) && (!linked_pdp)) {
1342 /* Not Secondary PDP Context Activation Procedure */
1343 /* IMSI (conditional) */
1344 if (gtpie_gettv0
1345 (ie, GTPIE_IMSI, 0, &pdp->imsi, sizeof(pdp->imsi))) {
1346 gsn->missing++;
1347 GTP_LOGPKG(LOGL_ERROR, peer, pack,
1348 len, "Missing mandatory information field\n");
1349 return gtp_create_pdp_resp(gsn, version, pdp,
1350 GTPCAUSE_MAN_IE_MISSING);
1354 /* Recovery (optional) */
1355 if (!gtpie_gettv1(ie, GTPIE_RECOVERY, 0, &recovery)) {
1356 if (gsn->cb_recovery)
1357 gsn->cb_recovery(peer, recovery);
1360 /* Selection mode (conditional) */
1361 if (!linked_pdp) { /* Not Secondary PDP Context Activation Procedure */
1362 if (gtpie_gettv0(ie, GTPIE_SELECTION_MODE, 0,
1363 &pdp->selmode, sizeof(pdp->selmode))) {
1364 gsn->missing++;
1365 GTP_LOGPKG(LOGL_ERROR, peer, pack,
1366 len, "Missing mandatory information field\n");
1367 return gtp_create_pdp_resp(gsn, version, pdp,
1368 GTPCAUSE_MAN_IE_MISSING);
1372 if (version == 0) {
1373 if (gtpie_gettv2(ie, GTPIE_FL_DI, 0, &pdp->flru)) {
1374 gsn->missing++;
1375 GTP_LOGPKG(LOGL_ERROR, peer, pack,
1376 len, "Missing mandatory information field\n");
1377 return gtp_create_pdp_resp(gsn, version, pdp,
1378 GTPCAUSE_MAN_IE_MISSING);
1381 if (gtpie_gettv2(ie, GTPIE_FL_C, 0, &pdp->flrc)) {
1382 gsn->missing++;
1383 GTP_LOGPKG(LOGL_ERROR, peer, pack,
1384 len, "Missing mandatory information field\n");
1385 return gtp_create_pdp_resp(gsn, version, pdp,
1386 GTPCAUSE_MAN_IE_MISSING);
1390 if (version == 1) {
1391 /* TEID (mandatory) */
1392 if (gtpie_gettv4(ie, GTPIE_TEI_DI, 0, &pdp->teid_gn)) {
1393 gsn->missing++;
1394 GTP_LOGPKG(LOGL_ERROR, peer, pack,
1395 len, "Missing mandatory information field\n");
1396 return gtp_create_pdp_resp(gsn, version, pdp,
1397 GTPCAUSE_MAN_IE_MISSING);
1400 /* TEIC (conditional) */
1401 if (!linked_pdp) { /* Not Secondary PDP Context Activation Procedure */
1402 if (gtpie_gettv4(ie, GTPIE_TEI_C, 0, &pdp->teic_gn)) {
1403 gsn->missing++;
1404 GTP_LOGPKG(LOGL_ERROR, peer,
1405 pack, len,
1406 "Missing mandatory information field\n");
1407 return gtp_create_pdp_resp(gsn, version, pdp,
1408 GTPCAUSE_MAN_IE_MISSING);
1412 /* NSAPI (mandatory) */
1413 if (gtpie_gettv1(ie, GTPIE_NSAPI, 0, &pdp->nsapi)) {
1414 gsn->missing++;
1415 GTP_LOGPKG(LOGL_ERROR, peer, pack,
1416 len, "Missing mandatory information field\n");
1417 return gtp_create_pdp_resp(gsn, version, pdp,
1418 GTPCAUSE_MAN_IE_MISSING);
1422 /* Charging Characteriatics (optional) */
1423 /* Trace reference (optional) */
1424 /* Trace type (optional) */
1425 /* Charging Characteriatics (optional) */
1427 if (!linked_pdp) { /* Not Secondary PDP Context Activation Procedure */
1428 /* End User Address (conditional) */
1429 if (gtpie_gettlv(ie, GTPIE_EUA, 0, &pdp->eua.l,
1430 &pdp->eua.v, sizeof(pdp->eua.v))) {
1431 gsn->missing++;
1432 GTP_LOGPKG(LOGL_ERROR, peer, pack,
1433 len, "Missing mandatory information field\n");
1434 return gtp_create_pdp_resp(gsn, version, pdp,
1435 GTPCAUSE_MAN_IE_MISSING);
1438 /* APN */
1439 if (gtpie_gettlv(ie, GTPIE_APN, 0, &pdp->apn_req.l,
1440 &pdp->apn_req.v, sizeof(pdp->apn_req.v))) {
1441 gsn->missing++;
1442 GTP_LOGPKG(LOGL_ERROR, peer, pack,
1443 len, "Missing mandatory information field\n");
1444 return gtp_create_pdp_resp(gsn, version, pdp,
1445 GTPCAUSE_MAN_IE_MISSING);
1448 /* Extract protocol configuration options (optional) */
1449 if (!gtpie_gettlv(ie, GTPIE_PCO, 0, &pdp->pco_req.l,
1450 &pdp->pco_req.v, sizeof(pdp->pco_req.v))) {
1454 /* SGSN address for signalling (mandatory) */
1455 if (gtpie_gettlv(ie, GTPIE_GSN_ADDR, 0, &pdp->gsnrc.l,
1456 &pdp->gsnrc.v, sizeof(pdp->gsnrc.v))) {
1457 gsn->missing++;
1458 GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
1459 "Missing mandatory information field\n");
1460 return gtp_create_pdp_resp(gsn, version, pdp,
1461 GTPCAUSE_MAN_IE_MISSING);
1464 /* SGSN address for user traffic (mandatory) */
1465 if (gtpie_gettlv(ie, GTPIE_GSN_ADDR, 1, &pdp->gsnru.l,
1466 &pdp->gsnru.v, sizeof(pdp->gsnru.v))) {
1467 gsn->missing++;
1468 GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
1469 "Missing mandatory information field\n");
1470 return gtp_create_pdp_resp(gsn, version, pdp,
1471 GTPCAUSE_MAN_IE_MISSING);
1474 if (!linked_pdp) { /* Not Secondary PDP Context Activation Procedure */
1475 /* MSISDN (conditional) */
1476 if (gtpie_gettlv(ie, GTPIE_MSISDN, 0, &pdp->msisdn.l,
1477 &pdp->msisdn.v, sizeof(pdp->msisdn.v))) {
1478 gsn->missing++;
1479 GTP_LOGPKG(LOGL_ERROR, peer, pack,
1480 len, "Missing mandatory information field\n");
1481 return gtp_create_pdp_resp(gsn, version, pdp,
1482 GTPCAUSE_MAN_IE_MISSING);
1486 if (version == 1) {
1487 /* QoS (mandatory) */
1488 if (gtpie_gettlv(ie, GTPIE_QOS_PROFILE, 0, &pdp->qos_req.l,
1489 &pdp->qos_req.v, sizeof(pdp->qos_req.v))) {
1490 gsn->missing++;
1491 GTP_LOGPKG(LOGL_ERROR, peer, pack,
1492 len, "Missing mandatory information field\n");
1493 return gtp_create_pdp_resp(gsn, version, pdp,
1494 GTPCAUSE_MAN_IE_MISSING);
1497 /* TFT (conditional) */
1498 if (gtpie_gettlv(ie, GTPIE_TFT, 0, &pdp->tft.l,
1499 &pdp->tft.v, sizeof(pdp->tft.v))) {
1502 /* Trigger ID */
1503 /* OMC identity */
1506 /* Initialize our own IP addresses */
1507 in_addr2gsna(&pdp->gsnlc, &gsn->gsnc);
1508 in_addr2gsna(&pdp->gsnlu, &gsn->gsnu);
1510 DEBUGP(DLGTP, "gtp_create_pdp_ind: Before pdp_tidget\n");
1512 if (!pdp_getimsi(&pdp_old, pdp->imsi, pdp->nsapi)) {
1513 /* Found old pdp with same tid. Now the voodoo begins! */
1514 /* 09.60 / 29.060 allows create on existing context to "steal" */
1515 /* the context which was allready established */
1516 /* We check that the APN, selection mode and MSISDN is the same */
1517 DEBUGP(DLGTP, "gtp_create_pdp_ind: Old context found\n");
1518 if ((pdp->apn_req.l == pdp_old->apn_req.l)
1520 (!memcmp
1521 (pdp->apn_req.v, pdp_old->apn_req.v, pdp->apn_req.l))
1522 && (pdp->selmode == pdp_old->selmode)
1523 && (pdp->msisdn.l == pdp_old->msisdn.l)
1525 (!memcmp(pdp->msisdn.v, pdp_old->msisdn.v, pdp->msisdn.l)))
1527 /* OK! We are dealing with the same APN. We will copy new
1528 * parameters to the old pdp and send off confirmation
1529 * We ignore the following information elements:
1530 * QoS: MS will get originally negotiated QoS.
1531 * End user address (EUA). MS will get old EUA anyway.
1532 * Protocol configuration option (PCO): Only application can verify */
1533 DEBUGP(DLGTP, "gtp_create_pdp_ind: Old context found\n");
1535 /* Copy remote flow label */
1536 pdp_old->flru = pdp->flru;
1537 pdp_old->flrc = pdp->flrc;
1539 /* Copy remote tei */
1540 pdp_old->teid_gn = pdp->teid_gn;
1541 pdp_old->teic_gn = pdp->teic_gn;
1543 /* Copy peer GSN address */
1544 pdp_old->gsnrc.l = pdp->gsnrc.l;
1545 memcpy(&pdp_old->gsnrc.v, &pdp->gsnrc.v, pdp->gsnrc.l);
1546 pdp_old->gsnru.l = pdp->gsnru.l;
1547 memcpy(&pdp_old->gsnru.v, &pdp->gsnru.v, pdp->gsnru.l);
1549 /* Copy request parameters */
1550 pdp_old->seq = pdp->seq;
1551 pdp_old->sa_peer = pdp->sa_peer;
1552 pdp_old->fd = pdp->fd = fd;
1553 pdp_old->version = pdp->version = version;
1555 /* Switch to using the old pdp context */
1556 pdp = pdp_old;
1558 /* Confirm to peer that things were "successful" */
1559 return gtp_create_pdp_resp(gsn, version, pdp,
1560 GTPCAUSE_ACC_REQ);
1561 } else { /* This is not the same PDP context. Delete the old one. */
1563 DEBUGP(DLGTP, "gtp_create_pdp_ind: Deleting old context\n");
1565 if (gsn->cb_delete_context)
1566 gsn->cb_delete_context(pdp_old);
1567 pdp_freepdp(pdp_old);
1569 DEBUGP(DLGTP, "gtp_create_pdp_ind: Deleted...\n");
1573 pdp_newpdp(&pdp, pdp->imsi, pdp->nsapi, pdp);
1575 /* Callback function to validata login */
1576 if (gsn->cb_create_context_ind != 0)
1577 return gsn->cb_create_context_ind(pdp);
1578 else {
1579 GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
1580 "No create_context_ind callback defined\n");
1581 return gtp_create_pdp_resp(gsn, version, pdp,
1582 GTPCAUSE_NOT_SUPPORTED);
1586 /* Handle Create PDP Context Response */
1587 int gtp_create_pdp_conf(struct gsn_t *gsn, int version,
1588 struct sockaddr_in *peer, void *pack, unsigned len)
1590 struct pdp_t *pdp;
1591 union gtpie_member *ie[GTPIE_SIZE];
1592 uint8_t cause, recovery;
1593 void *cbp = NULL;
1594 uint8_t type = 0;
1595 int hlen = get_hlen(pack);
1597 /* Remove packet from queue */
1598 if (gtp_conf(gsn, version, peer, pack, len, &type, &cbp))
1599 return EOF;
1601 /* Find the context in question */
1602 if (pdp_getgtp1(&pdp, get_tei(pack))) {
1603 gsn->err_unknownpdp++;
1604 GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
1605 "Unknown PDP context: %u\n", get_tei(pack));
1606 if (gsn->cb_conf)
1607 gsn->cb_conf(type, EOF, NULL, cbp);
1608 return EOF;
1611 /* Register that we have received a valid teic from GGSN */
1612 pdp->teic_confirmed = 1;
1614 /* Decode information elements */
1615 if (gtpie_decaps(ie, version, pack + hlen, len - hlen)) {
1616 gsn->invalid++;
1617 GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
1618 "Invalid message format\n");
1619 if (gsn->cb_conf)
1620 gsn->cb_conf(type, EOF, pdp, cbp);
1621 /* if (gsn->cb_delete_context) gsn->cb_delete_context(pdp);
1622 pdp_freepdp(pdp); */
1623 return EOF;
1626 /* Extract cause value (mandatory) */
1627 if (gtpie_gettv1(ie, GTPIE_CAUSE, 0, &cause)) {
1628 gsn->missing++;
1629 GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
1630 "Missing mandatory information field\n");
1631 if (gsn->cb_conf)
1632 gsn->cb_conf(type, EOF, pdp, cbp);
1633 /* if (gsn->cb_delete_context) gsn->cb_delete_context(pdp);
1634 pdp_freepdp(pdp); */
1635 return EOF;
1638 /* Extract recovery (optional) */
1639 if (!gtpie_gettv1(ie, GTPIE_RECOVERY, 0, &recovery)) {
1640 if (gsn->cb_recovery)
1641 gsn->cb_recovery(peer, recovery);
1644 /* Extract protocol configuration options (optional) */
1645 if (!gtpie_gettlv(ie, GTPIE_PCO, 0, &pdp->pco_req.l,
1646 &pdp->pco_req.v, sizeof(pdp->pco_req.v))) {
1649 /* Check all conditional information elements */
1650 if (GTPCAUSE_ACC_REQ == cause) {
1652 if (version == 0) {
1653 if (gtpie_gettv0(ie, GTPIE_QOS_PROFILE0, 0,
1654 &pdp->qos_neg0,
1655 sizeof(pdp->qos_neg0))) {
1656 gsn->missing++;
1657 GTP_LOGPKG(LOGL_ERROR, peer,
1658 pack, len,
1659 "Missing conditional information field\n");
1660 if (gsn->cb_conf)
1661 gsn->cb_conf(type, EOF, pdp, cbp);
1662 /* if (gsn->cb_delete_context) gsn->cb_delete_context(pdp);
1663 pdp_freepdp(pdp); */
1664 return EOF;
1668 if (gtpie_gettv1(ie, GTPIE_REORDER, 0, &pdp->reorder)) {
1669 gsn->missing++;
1670 GTP_LOGPKG(LOGL_ERROR, peer, pack,
1671 len,
1672 "Missing conditional information field\n");
1673 if (gsn->cb_conf)
1674 gsn->cb_conf(type, EOF, pdp, cbp);
1675 /* if (gsn->cb_delete_context) gsn->cb_delete_context(pdp);
1676 pdp_freepdp(pdp); */
1677 return EOF;
1680 if (version == 0) {
1681 if (gtpie_gettv2(ie, GTPIE_FL_DI, 0, &pdp->flru)) {
1682 gsn->missing++;
1683 GTP_LOGPKG(LOGL_ERROR, peer,
1684 pack, len,
1685 "Missing conditional information field\n");
1686 if (gsn->cb_conf)
1687 gsn->cb_conf(type, EOF, pdp, cbp);
1688 /* if (gsn->cb_delete_context) gsn->cb_delete_context(pdp);
1689 pdp_freepdp(pdp); */
1690 return EOF;
1693 if (gtpie_gettv2(ie, GTPIE_FL_C, 0, &pdp->flrc)) {
1694 gsn->missing++;
1695 GTP_LOGPKG(LOGL_ERROR, peer,
1696 pack, len,
1697 "Missing conditional information field\n");
1698 if (gsn->cb_conf)
1699 gsn->cb_conf(type, EOF, pdp, cbp);
1700 /* if (gsn->cb_delete_context) gsn->cb_delete_context(pdp);
1701 pdp_freepdp(pdp); */
1702 return EOF;
1706 if (version == 1) {
1707 if (gtpie_gettv4(ie, GTPIE_TEI_DI, 0, &pdp->teid_gn)) {
1708 gsn->missing++;
1709 GTP_LOGPKG(LOGL_ERROR, peer,
1710 pack, len,
1711 "Missing conditional information field\n");
1712 if (gsn->cb_conf)
1713 gsn->cb_conf(type, EOF, pdp, cbp);
1714 /* if (gsn->cb_delete_context) gsn->cb_delete_context(pdp);
1715 pdp_freepdp(pdp); */
1716 return EOF;
1719 if (gtpie_gettv4(ie, GTPIE_TEI_C, 0, &pdp->teic_gn)) {
1720 gsn->missing++;
1721 GTP_LOGPKG(LOGL_ERROR, peer,
1722 pack, len,
1723 "Missing conditional information field\n");
1724 if (gsn->cb_conf)
1725 gsn->cb_conf(type, EOF, pdp, cbp);
1726 /* if (gsn->cb_delete_context) gsn->cb_delete_context(pdp);
1727 pdp_freepdp(pdp); */
1728 return EOF;
1732 if (gtpie_gettv4(ie, GTPIE_CHARGING_ID, 0, &pdp->cid)) {
1733 gsn->missing++;
1734 GTP_LOGPKG(LOGL_ERROR, peer, pack,
1735 len,
1736 "Missing conditional information field\n");
1737 if (gsn->cb_conf)
1738 gsn->cb_conf(type, EOF, pdp, cbp);
1739 /* if (gsn->cb_delete_context) gsn->cb_delete_context(pdp);
1740 pdp_freepdp(pdp); */
1743 if (gtpie_gettlv(ie, GTPIE_EUA, 0, &pdp->eua.l,
1744 &pdp->eua.v, sizeof(pdp->eua.v))) {
1745 gsn->missing++;
1746 GTP_LOGPKG(LOGL_ERROR, peer, pack,
1747 len,
1748 "Missing conditional information field\n");
1749 if (gsn->cb_conf)
1750 gsn->cb_conf(type, EOF, pdp, cbp);
1751 /* if (gsn->cb_delete_context) gsn->cb_delete_context(pdp);
1752 pdp_freepdp(pdp); */
1753 return EOF;
1756 if (gtpie_gettlv(ie, GTPIE_GSN_ADDR, 0, &pdp->gsnrc.l,
1757 &pdp->gsnrc.v, sizeof(pdp->gsnrc.v))) {
1758 gsn->missing++;
1759 GTP_LOGPKG(LOGL_ERROR, peer, pack,
1760 len,
1761 "Missing conditional information field\n");
1762 if (gsn->cb_conf)
1763 gsn->cb_conf(type, EOF, pdp, cbp);
1764 /* if (gsn->cb_delete_context) gsn->cb_delete_context(pdp);
1765 pdp_freepdp(pdp); */
1766 return EOF;
1769 if (gtpie_gettlv(ie, GTPIE_GSN_ADDR, 1, &pdp->gsnru.l,
1770 &pdp->gsnru.v, sizeof(pdp->gsnru.v))) {
1771 gsn->missing++;
1772 GTP_LOGPKG(LOGL_ERROR, peer, pack,
1773 len,
1774 "Missing conditional information field\n");
1775 if (gsn->cb_conf)
1776 gsn->cb_conf(type, EOF, pdp, cbp);
1777 /* if (gsn->cb_delete_context) gsn->cb_delete_context(pdp);
1778 pdp_freepdp(pdp); */
1779 return EOF;
1782 if (version == 1) {
1783 if (gtpie_gettlv
1784 (ie, GTPIE_QOS_PROFILE, 0, &pdp->qos_neg.l,
1785 &pdp->qos_neg.v, sizeof(pdp->qos_neg.v))) {
1786 gsn->missing++;
1787 GTP_LOGPKG(LOGL_ERROR, peer,
1788 pack, len,
1789 "Missing conditional information field\n");
1790 if (gsn->cb_conf)
1791 gsn->cb_conf(type, EOF, pdp, cbp);
1792 /* if (gsn->cb_delete_context) gsn->cb_delete_context(pdp);
1793 pdp_freepdp(pdp); */
1794 return EOF;
1800 if (gsn->cb_conf)
1801 gsn->cb_conf(type, cause, pdp, cbp);
1803 return 0;
1806 /* API: Send Update PDP Context Request */
1807 int gtp_update_context(struct gsn_t *gsn, struct pdp_t *pdp, void *cbp,
1808 struct in_addr *inetaddr)
1810 union gtp_packet packet;
1811 unsigned int length =
1812 get_default_gtp(pdp->version, GTP_UPDATE_PDP_REQ, &packet);
1814 if (pdp->version == 0)
1815 gtpie_tv0(&packet, &length, GTP_MAX, GTPIE_QOS_PROFILE0,
1816 sizeof(pdp->qos_req0), pdp->qos_req0);
1818 /* Include IMSI if updating with unknown teic_gn */
1819 if ((pdp->version == 1) && (!pdp->teic_gn))
1820 gtpie_tv0(&packet, &length, GTP_MAX, GTPIE_IMSI,
1821 sizeof(pdp->imsi), (uint8_t *) & pdp->imsi);
1823 gtpie_tv1(&packet, &length, GTP_MAX, GTPIE_RECOVERY,
1824 gsn->restart_counter);
1826 if (pdp->version == 0) {
1827 gtpie_tv2(&packet, &length, GTP_MAX, GTPIE_FL_DI, pdp->fllu);
1828 gtpie_tv2(&packet, &length, GTP_MAX, GTPIE_FL_C, pdp->fllc);
1831 if (pdp->version == 1) {
1832 gtpie_tv4(&packet, &length, GTP_MAX, GTPIE_TEI_DI,
1833 pdp->teid_own);
1835 if (!pdp->teic_confirmed)
1836 gtpie_tv4(&packet, &length, GTP_MAX, GTPIE_TEI_C,
1837 pdp->teic_own);
1840 gtpie_tv1(&packet, &length, GTP_MAX, GTPIE_NSAPI, pdp->nsapi);
1842 /* TODO
1843 gtpie_tv2(&packet, &length, GTP_MAX, GTPIE_TRACE_REF,
1844 pdp->traceref);
1845 gtpie_tv2(&packet, &length, GTP_MAX, GTPIE_TRACE_TYPE,
1846 pdp->tracetype); */
1848 /* TODO if ggsn update message
1849 gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_EUA,
1850 pdp->eua.l, pdp->eua.v);
1853 gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_GSN_ADDR,
1854 pdp->gsnlc.l, pdp->gsnlc.v);
1855 gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_GSN_ADDR,
1856 pdp->gsnlu.l, pdp->gsnlu.v);
1858 if (pdp->version == 1)
1859 gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_QOS_PROFILE,
1860 pdp->qos_req.l, pdp->qos_req.v);
1862 if ((pdp->version == 1) && pdp->tft.l)
1863 gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_TFT,
1864 pdp->tft.l, pdp->tft.v);
1866 if ((pdp->version == 1) && pdp->triggerid.l)
1867 gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_TRIGGER_ID,
1868 pdp->triggerid.l, pdp->triggerid.v);
1870 if ((pdp->version == 1) && pdp->omcid.l)
1871 gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_OMC_ID,
1872 pdp->omcid.l, pdp->omcid.v);
1874 gtp_req(gsn, pdp->version, pdp, &packet, length, inetaddr, cbp);
1876 return 0;
1879 /* Send Update PDP Context Response */
1880 int gtp_update_pdp_resp(struct gsn_t *gsn, int version,
1881 struct sockaddr_in *peer, int fd,
1882 void *pack, unsigned len,
1883 struct pdp_t *pdp, uint8_t cause)
1886 union gtp_packet packet;
1887 unsigned int length =
1888 get_default_gtp(version, GTP_UPDATE_PDP_RSP, &packet);
1890 gtpie_tv1(&packet, &length, GTP_MAX, GTPIE_CAUSE, cause);
1892 if (cause == GTPCAUSE_ACC_REQ) {
1894 if (version == 0)
1895 gtpie_tv0(&packet, &length, GTP_MAX, GTPIE_QOS_PROFILE0,
1896 sizeof(pdp->qos_neg0), pdp->qos_neg0);
1898 gtpie_tv1(&packet, &length, GTP_MAX, GTPIE_RECOVERY,
1899 gsn->restart_counter);
1901 if (version == 0) {
1902 gtpie_tv2(&packet, &length, GTP_MAX, GTPIE_FL_DI,
1903 pdp->fllu);
1904 gtpie_tv2(&packet, &length, GTP_MAX, GTPIE_FL_C,
1905 pdp->fllc);
1908 if (version == 1) {
1909 gtpie_tv4(&packet, &length, GTP_MAX, GTPIE_TEI_DI,
1910 pdp->teid_own);
1912 if (!pdp->teic_confirmed)
1913 gtpie_tv4(&packet, &length, GTP_MAX,
1914 GTPIE_TEI_C, pdp->teic_own);
1917 /* TODO we use teid_own as charging ID address */
1918 gtpie_tv4(&packet, &length, GTP_MAX, GTPIE_CHARGING_ID,
1919 pdp->teid_own);
1921 /* If ggsn
1922 gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_EUA,
1923 pdp->eua.l, pdp->eua.v); */
1925 gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_GSN_ADDR,
1926 pdp->gsnlc.l, pdp->gsnlc.v);
1927 gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_GSN_ADDR,
1928 pdp->gsnlu.l, pdp->gsnlu.v);
1930 if (version == 1)
1931 gtpie_tlv(&packet, &length, GTP_MAX, GTPIE_QOS_PROFILE,
1932 pdp->qos_neg.l, pdp->qos_neg.v);
1934 /* TODO: Charging gateway address */
1937 return gtp_resp(version, gsn, pdp, &packet, length, peer,
1938 fd, get_seq(pack), get_tid(pack));
1941 /* Handle Update PDP Context Request */
1942 int gtp_update_pdp_ind(struct gsn_t *gsn, int version,
1943 struct sockaddr_in *peer, int fd,
1944 void *pack, unsigned len)
1946 struct pdp_t *pdp;
1947 struct pdp_t pdp_backup;
1948 union gtpie_member *ie[GTPIE_SIZE];
1949 uint8_t recovery;
1951 uint16_t seq = get_seq(pack);
1952 int hlen = get_hlen(pack);
1954 uint64_t imsi;
1955 uint8_t nsapi;
1957 /* Is this a dublicate ? */
1958 if (!gtp_dublicate(gsn, version, peer, seq)) {
1959 return 0; /* We allready send of response once */
1962 /* Decode information elements */
1963 if (gtpie_decaps(ie, version, pack + hlen, len - hlen)) {
1964 gsn->invalid++;
1965 GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
1966 "Invalid message format\n");
1967 if (0 == version)
1968 return EOF;
1969 else
1970 return gtp_update_pdp_resp(gsn, version, peer, fd, pack,
1971 len, NULL,
1972 GTPCAUSE_INVALID_MESSAGE);
1975 /* Finding PDP: */
1976 /* For GTP0 we use the tunnel identifier to provide imsi and nsapi. */
1977 /* For GTP1 we must use imsi and nsapi if imsi is present. Otherwise */
1978 /* we have to use the tunnel endpoint identifier */
1979 if (version == 0) {
1980 uint64_t tid = be64toh(((union gtp_packet *)pack)->gtp0.h.tid);
1982 pdp_set_imsi_nsapi(pdp, tid);
1984 /* Find the context in question */
1985 if (pdp_getimsi(&pdp, imsi, nsapi)) {
1986 gsn->err_unknownpdp++;
1987 GTP_LOGPKG(LOGL_ERROR, peer, pack,
1988 len, "Unknown PDP context\n");
1989 return gtp_update_pdp_resp(gsn, version, peer, fd, pack,
1990 len, NULL,
1991 GTPCAUSE_NON_EXIST);
1993 } else if (version == 1) {
1994 /* NSAPI (mandatory) */
1995 if (gtpie_gettv1(ie, GTPIE_NSAPI, 0, &nsapi)) {
1996 gsn->missing++;
1997 GTP_LOGPKG(LOGL_ERROR, peer, pack,
1998 len, "Missing mandatory information field\n");
1999 return gtp_update_pdp_resp(gsn, version, peer, fd, pack,
2000 len, NULL,
2001 GTPCAUSE_MAN_IE_MISSING);
2004 /* IMSI (conditional) */
2005 if (gtpie_gettv0(ie, GTPIE_IMSI, 0, &imsi, sizeof(imsi))) {
2006 /* Find the context in question */
2007 if (pdp_getgtp1(&pdp, get_tei(pack))) {
2008 gsn->err_unknownpdp++;
2009 GTP_LOGPKG(LOGL_ERROR, peer,
2010 pack, len, "Unknown PDP context: %u\n",
2011 get_tei(pack));
2012 return gtp_update_pdp_resp(gsn, version, peer,
2013 fd, pack, len, NULL,
2014 GTPCAUSE_NON_EXIST);
2016 } else {
2017 /* Find the context in question */
2018 if (pdp_getimsi(&pdp, imsi, nsapi)) {
2019 gsn->err_unknownpdp++;
2020 GTP_LOGPKG(LOGL_ERROR, peer,
2021 pack, len, "Unknown PDP context\n");
2022 return gtp_update_pdp_resp(gsn, version, peer,
2023 fd, pack, len, NULL,
2024 GTPCAUSE_NON_EXIST);
2027 } else {
2028 LOGP(DLGTP, LOGL_ERROR, "Unknown version: %d\n", version);
2029 return EOF;
2032 /* Make a backup copy in case anything is wrong */
2033 memcpy(&pdp_backup, pdp, sizeof(pdp_backup));
2035 if (version == 0) {
2036 if (gtpie_gettv0(ie, GTPIE_QOS_PROFILE0, 0,
2037 pdp->qos_req0, sizeof(pdp->qos_req0))) {
2038 gsn->missing++;
2039 GTP_LOGPKG(LOGL_ERROR, peer, pack,
2040 len, "Missing mandatory information field\n");
2041 memcpy(pdp, &pdp_backup, sizeof(pdp_backup));
2042 return gtp_update_pdp_resp(gsn, version, peer, fd, pack,
2043 len, pdp,
2044 GTPCAUSE_MAN_IE_MISSING);
2048 /* Recovery (optional) */
2049 if (!gtpie_gettv1(ie, GTPIE_RECOVERY, 0, &recovery)) {
2050 if (gsn->cb_recovery)
2051 gsn->cb_recovery(peer, recovery);
2054 if (version == 0) {
2055 if (gtpie_gettv2(ie, GTPIE_FL_DI, 0, &pdp->flru)) {
2056 gsn->missing++;
2057 GTP_LOGPKG(LOGL_ERROR, peer, pack,
2058 len, "Missing mandatory information field\n");
2059 memcpy(pdp, &pdp_backup, sizeof(pdp_backup));
2060 return gtp_update_pdp_resp(gsn, version, peer, fd, pack,
2061 len, pdp,
2062 GTPCAUSE_MAN_IE_MISSING);
2065 if (gtpie_gettv2(ie, GTPIE_FL_C, 0, &pdp->flrc)) {
2066 gsn->missing++;
2067 GTP_LOGPKG(LOGL_ERROR, peer, pack,
2068 len, "Missing mandatory information field\n");
2069 memcpy(pdp, &pdp_backup, sizeof(pdp_backup));
2070 return gtp_update_pdp_resp(gsn, version, peer, fd, pack,
2071 len, pdp,
2072 GTPCAUSE_MAN_IE_MISSING);
2076 if (version == 1) {
2077 /* TEID (mandatory) */
2078 if (gtpie_gettv4(ie, GTPIE_TEI_DI, 0, &pdp->teid_gn)) {
2079 gsn->missing++;
2080 GTP_LOGPKG(LOGL_ERROR, peer, pack,
2081 len, "Missing mandatory information field\n");
2082 memcpy(pdp, &pdp_backup, sizeof(pdp_backup));
2083 return gtp_update_pdp_resp(gsn, version, peer, fd, pack,
2084 len, pdp,
2085 GTPCAUSE_MAN_IE_MISSING);
2088 /* TEIC (conditional) */
2089 /* If TEIC is not included it means that we have allready received it */
2090 /* TODO: From 29.060 it is not clear if TEI_C MUST be included for */
2091 /* all updated contexts, or only for one of the linked contexts */
2092 gtpie_gettv4(ie, GTPIE_TEI_C, 0, &pdp->teic_gn);
2094 /* NSAPI (mandatory) */
2095 if (gtpie_gettv1(ie, GTPIE_NSAPI, 0, &pdp->nsapi)) {
2096 gsn->missing++;
2097 GTP_LOGPKG(LOGL_ERROR, peer, pack,
2098 len, "Missing mandatory information field\n");
2099 memcpy(pdp, &pdp_backup, sizeof(pdp_backup));
2100 return gtp_update_pdp_resp(gsn, version, peer, fd, pack,
2101 len, pdp,
2102 GTPCAUSE_MAN_IE_MISSING);
2106 /* Trace reference (optional) */
2107 /* Trace type (optional) */
2109 /* End User Address (conditional) TODO: GGSN Initiated
2110 if (gtpie_gettlv(ie, GTPIE_EUA, 0, &pdp->eua.l,
2111 &pdp->eua.v, sizeof(pdp->eua.v))) {
2112 gsn->missing++;
2113 GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
2114 "Missing mandatory information field");
2115 memcpy(pdp, &pdp_backup, sizeof(pdp_backup));
2116 return gtp_update_pdp_resp(gsn, version, pdp,
2117 GTPCAUSE_MAN_IE_MISSING);
2118 } */
2120 /* SGSN address for signalling (mandatory) */
2121 /* It is weird that this is mandatory when TEIC is conditional */
2122 if (gtpie_gettlv(ie, GTPIE_GSN_ADDR, 0, &pdp->gsnrc.l,
2123 &pdp->gsnrc.v, sizeof(pdp->gsnrc.v))) {
2124 gsn->missing++;
2125 GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
2126 "Missing mandatory information field\n");
2127 memcpy(pdp, &pdp_backup, sizeof(pdp_backup));
2128 return gtp_update_pdp_resp(gsn, version, peer, fd, pack, len,
2129 pdp, GTPCAUSE_MAN_IE_MISSING);
2132 /* SGSN address for user traffic (mandatory) */
2133 if (gtpie_gettlv(ie, GTPIE_GSN_ADDR, 1, &pdp->gsnru.l,
2134 &pdp->gsnru.v, sizeof(pdp->gsnru.v))) {
2135 gsn->missing++;
2136 GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
2137 "Missing mandatory information field\n");
2138 memcpy(pdp, &pdp_backup, sizeof(pdp_backup));
2139 return gtp_update_pdp_resp(gsn, version, peer, fd, pack, len,
2140 pdp, GTPCAUSE_MAN_IE_MISSING);
2143 if (version == 1) {
2144 /* QoS (mandatory) */
2145 if (gtpie_gettlv(ie, GTPIE_QOS_PROFILE, 0, &pdp->qos_req.l,
2146 &pdp->qos_req.v, sizeof(pdp->qos_req.v))) {
2147 gsn->missing++;
2148 GTP_LOGPKG(LOGL_ERROR, peer, pack,
2149 len, "Missing mandatory information field\n");
2150 memcpy(pdp, &pdp_backup, sizeof(pdp_backup));
2151 return gtp_update_pdp_resp(gsn, version, peer, fd, pack,
2152 len, pdp,
2153 GTPCAUSE_MAN_IE_MISSING);
2156 /* TFT (conditional) */
2157 if (gtpie_gettlv(ie, GTPIE_TFT, 0, &pdp->tft.l,
2158 &pdp->tft.v, sizeof(pdp->tft.v))) {
2161 /* OMC identity */
2164 /* Confirm to peer that things were "successful" */
2165 return gtp_update_pdp_resp(gsn, version, peer, fd, pack, len, pdp,
2166 GTPCAUSE_ACC_REQ);
2169 /* Handle Update PDP Context Response */
2170 int gtp_update_pdp_conf(struct gsn_t *gsn, int version,
2171 struct sockaddr_in *peer, void *pack, unsigned len)
2173 struct pdp_t *pdp;
2174 union gtpie_member *ie[GTPIE_SIZE];
2175 uint8_t cause, recovery;
2176 void *cbp = NULL;
2177 uint8_t type = 0;
2178 int hlen = get_hlen(pack);
2180 /* Remove packet from queue */
2181 if (gtp_conf(gsn, 0, peer, pack, len, &type, &cbp))
2182 return EOF;
2184 /* Find the context in question */
2185 if (pdp_getgtp1(&pdp, get_tei(pack))) {
2186 gsn->err_unknownpdp++;
2187 GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
2188 "Unknown PDP context: %u\n", get_tei(pack));
2189 pdp = NULL;
2190 goto err_out;
2193 /* Register that we have received a valid teic from GGSN */
2194 pdp->teic_confirmed = 1;
2196 /* Decode information elements */
2197 if (gtpie_decaps(ie, version, pack + hlen, len - hlen)) {
2198 gsn->invalid++;
2199 GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
2200 "Invalid message format\n");
2201 goto err_out;
2204 /* Extract cause value (mandatory) */
2205 if (gtpie_gettv1(ie, GTPIE_CAUSE, 0, &cause)) {
2206 goto err_missing;
2209 /* Extract recovery (optional) */
2210 if (!gtpie_gettv1(ie, GTPIE_RECOVERY, 0, &recovery)) {
2211 if (gsn->cb_recovery)
2212 gsn->cb_recovery(peer, recovery);
2215 /* Check all conditional information elements */
2216 /* TODO: This does not handle GGSN-initiated update responses */
2217 if (GTPCAUSE_ACC_REQ == cause) {
2218 if (version == 0) {
2219 if (gtpie_gettv0(ie, GTPIE_QOS_PROFILE0, 0,
2220 &pdp->qos_neg0,
2221 sizeof(pdp->qos_neg0))) {
2222 goto err_missing;
2225 if (gtpie_gettv2(ie, GTPIE_FL_DI, 0, &pdp->flru)) {
2226 goto err_missing;
2229 if (gtpie_gettv2(ie, GTPIE_FL_C, 0, &pdp->flrc)) {
2230 goto err_missing;
2234 if (version == 1) {
2235 if (gtpie_gettv4(ie, GTPIE_TEI_DI, 0, &pdp->teid_gn)) {
2236 goto err_missing;
2239 if (gtpie_gettv4(ie, GTPIE_TEI_C, 0, &pdp->teic_gn)) {
2240 goto err_missing;
2244 if (gtpie_gettv4(ie, GTPIE_CHARGING_ID, 0, &pdp->cid)) {
2245 goto err_missing;
2248 if (gtpie_gettlv(ie, GTPIE_GSN_ADDR, 0, &pdp->gsnrc.l,
2249 &pdp->gsnrc.v, sizeof(pdp->gsnrc.v))) {
2250 goto err_missing;
2253 if (gtpie_gettlv(ie, GTPIE_GSN_ADDR, 1, &pdp->gsnru.l,
2254 &pdp->gsnru.v, sizeof(pdp->gsnru.v))) {
2255 goto err_missing;
2258 if (version == 1) {
2259 if (gtpie_gettlv
2260 (ie, GTPIE_QOS_PROFILE, 0, &pdp->qos_neg.l,
2261 &pdp->qos_neg.v, sizeof(pdp->qos_neg.v))) {
2262 goto err_missing;
2267 if (gsn->cb_conf)
2268 gsn->cb_conf(type, cause, pdp, cbp);
2269 return 0; /* Succes */
2271 err_missing:
2272 gsn->missing++;
2273 GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
2274 "Missing information field\n");
2275 err_out:
2276 if (gsn->cb_conf)
2277 gsn->cb_conf(type, EOF, pdp, cbp);
2278 return EOF;
2281 /* API: Send Delete PDP Context Request */
2282 int gtp_delete_context_req(struct gsn_t *gsn, struct pdp_t *pdp, void *cbp,
2283 int teardown)
2285 union gtp_packet packet;
2286 unsigned int length =
2287 get_default_gtp(pdp->version, GTP_DELETE_PDP_REQ, &packet);
2288 struct in_addr addr;
2289 struct pdp_t *linked_pdp;
2290 struct pdp_t *secondary_pdp;
2291 int n;
2292 int count = 0;
2294 if (gsna2in_addr(&addr, &pdp->gsnrc)) {
2295 gsn->err_address++;
2296 LOGP(DLGTP, LOGL_ERROR,
2297 "GSN address conversion failed\n");
2298 return EOF;
2301 if (pdp_getgtp1(&linked_pdp, pdp->teic_own)) {
2302 LOGP(DLGTP, LOGL_ERROR,
2303 "Unknown linked PDP context: %u\n", pdp->teic_own);
2304 return EOF;
2307 if (!teardown) {
2308 for (n = 0; n < PDP_MAXNSAPI; n++)
2309 if (linked_pdp->secondary_tei[n])
2310 count++;
2311 if (count <= 1) {
2312 LOGP(DLGTP, LOGL_ERROR,
2313 "Must use teardown for last context: %d\n", count);
2314 return EOF;
2318 if (pdp->version == 1) {
2319 if (teardown)
2320 gtpie_tv1(&packet, &length, GTP_MAX, GTPIE_TEARDOWN,
2321 0xff);
2323 gtpie_tv1(&packet, &length, GTP_MAX, GTPIE_NSAPI, pdp->nsapi);
2326 gtp_req(gsn, pdp->version, pdp, &packet, length, &addr, cbp);
2328 if (teardown) { /* Remove all contexts */
2329 for (n = 0; n < PDP_MAXNSAPI; n++) {
2330 if (linked_pdp->secondary_tei[n]) {
2331 if (pdp_getgtp1
2332 (&secondary_pdp,
2333 linked_pdp->secondary_tei[n])) {
2334 LOGP(DLGTP, LOGL_ERROR,
2335 "Unknown secondary PDP context\n");
2336 return EOF;
2338 if (linked_pdp != secondary_pdp) {
2339 if (gsn->cb_delete_context)
2340 gsn->cb_delete_context
2341 (secondary_pdp);
2342 pdp_freepdp(secondary_pdp);
2346 if (gsn->cb_delete_context)
2347 gsn->cb_delete_context(linked_pdp);
2348 pdp_freepdp(linked_pdp);
2349 } else {
2350 if (gsn->cb_delete_context)
2351 gsn->cb_delete_context(pdp);
2352 if (pdp == linked_pdp) {
2353 linked_pdp->secondary_tei[pdp->nsapi & 0xf0] = 0;
2354 linked_pdp->nodata = 1;
2355 } else
2356 pdp_freepdp(pdp);
2359 return 0;
2362 /* Send Delete PDP Context Response */
2363 int gtp_delete_pdp_resp(struct gsn_t *gsn, int version,
2364 struct sockaddr_in *peer, int fd,
2365 void *pack, unsigned len,
2366 struct pdp_t *pdp, struct pdp_t *linked_pdp,
2367 uint8_t cause, int teardown)
2369 union gtp_packet packet;
2370 struct pdp_t *secondary_pdp;
2371 unsigned int length =
2372 get_default_gtp(version, GTP_DELETE_PDP_RSP, &packet);
2373 int n;
2375 gtpie_tv1(&packet, &length, GTP_MAX, GTPIE_CAUSE, cause);
2377 gtp_resp(version, gsn, pdp, &packet, length, peer, fd,
2378 get_seq(pack), get_tid(pack));
2380 if (cause == GTPCAUSE_ACC_REQ) {
2381 if ((teardown) || (version == 0)) { /* Remove all contexts */
2382 for (n = 0; n < PDP_MAXNSAPI; n++) {
2383 if (linked_pdp->secondary_tei[n]) {
2384 if (pdp_getgtp1
2385 (&secondary_pdp,
2386 linked_pdp->secondary_tei[n])) {
2387 LOGP(DLGTP, LOGL_ERROR,
2388 "Unknown secondary PDP context\n");
2389 return EOF;
2391 if (linked_pdp != secondary_pdp) {
2392 if (gsn->cb_delete_context)
2393 gsn->cb_delete_context
2394 (secondary_pdp);
2395 pdp_freepdp(secondary_pdp);
2399 if (gsn->cb_delete_context)
2400 gsn->cb_delete_context(linked_pdp);
2401 pdp_freepdp(linked_pdp);
2402 } else { /* Remove only current context */
2403 if (gsn->cb_delete_context)
2404 gsn->cb_delete_context(pdp);
2405 if (pdp == linked_pdp) {
2406 linked_pdp->secondary_tei[pdp->nsapi & 0xf0] =
2408 linked_pdp->nodata = 1;
2409 } else
2410 pdp_freepdp(pdp);
2413 /* if (cause == GTPCAUSE_ACC_REQ) */
2414 return 0;
2417 /* Handle Delete PDP Context Request */
2418 int gtp_delete_pdp_ind(struct gsn_t *gsn, int version,
2419 struct sockaddr_in *peer, int fd,
2420 void *pack, unsigned len)
2422 struct pdp_t *pdp = NULL;
2423 struct pdp_t *linked_pdp = NULL;
2424 union gtpie_member *ie[GTPIE_SIZE];
2426 uint16_t seq = get_seq(pack);
2427 int hlen = get_hlen(pack);
2429 uint8_t nsapi;
2430 uint8_t teardown = 0;
2431 int n;
2432 int count = 0;
2434 /* Is this a dublicate ? */
2435 if (!gtp_dublicate(gsn, version, peer, seq)) {
2436 return 0; /* We allready send off response once */
2439 /* Find the linked context in question */
2440 if (pdp_getgtp1(&linked_pdp, get_tei(pack))) {
2441 gsn->err_unknownpdp++;
2442 GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
2443 "Unknown PDP context: %u\n", get_tei(pack));
2444 return gtp_delete_pdp_resp(gsn, version, peer, fd, pack, len,
2445 NULL, NULL, GTPCAUSE_NON_EXIST,
2446 teardown);
2449 /* If version 0 this is also the secondary context */
2450 if (version == 0)
2451 pdp = linked_pdp;
2453 /* Decode information elements */
2454 if (gtpie_decaps(ie, version, pack + hlen, len - hlen)) {
2455 gsn->invalid++;
2456 GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
2457 "Invalid message format\n");
2458 if (0 == version)
2459 return EOF;
2460 else
2461 return gtp_delete_pdp_resp(gsn, version, peer, fd, pack,
2462 len, NULL, NULL,
2463 GTPCAUSE_INVALID_MESSAGE,
2464 teardown);
2467 if (version == 1) {
2468 /* NSAPI (mandatory) */
2469 if (gtpie_gettv1(ie, GTPIE_NSAPI, 0, &nsapi)) {
2470 gsn->missing++;
2471 GTP_LOGPKG(LOGL_ERROR, peer, pack,
2472 len, "Missing mandatory information field\n");
2473 return gtp_delete_pdp_resp(gsn, version, peer, fd, pack,
2474 len, NULL, NULL,
2475 GTPCAUSE_MAN_IE_MISSING,
2476 teardown);
2479 /* Find the context in question */
2480 if (pdp_getgtp1(&pdp, linked_pdp->secondary_tei[nsapi & 0x0f])) {
2481 gsn->err_unknownpdp++;
2482 GTP_LOGPKG(LOGL_ERROR, peer, pack,
2483 len, "Unknown PDP context\n");
2484 return gtp_delete_pdp_resp(gsn, version, peer, fd, pack,
2485 len, NULL, NULL,
2486 GTPCAUSE_NON_EXIST,
2487 teardown);
2490 /* Teardown (conditional) */
2491 gtpie_gettv1(ie, GTPIE_TEARDOWN, 0, &teardown);
2493 if (!teardown) {
2494 for (n = 0; n < PDP_MAXNSAPI; n++)
2495 if (linked_pdp->secondary_tei[n])
2496 count++;
2497 if (count <= 1) {
2498 return 0; /* 29.060 7.3.5 Ignore message */
2503 return gtp_delete_pdp_resp(gsn, version, peer, fd, pack, len,
2504 pdp, linked_pdp, GTPCAUSE_ACC_REQ, teardown);
2507 /* Handle Delete PDP Context Response */
2508 int gtp_delete_pdp_conf(struct gsn_t *gsn, int version,
2509 struct sockaddr_in *peer, void *pack, unsigned len)
2511 union gtpie_member *ie[GTPIE_SIZE];
2512 uint8_t cause;
2513 void *cbp = NULL;
2514 uint8_t type = 0;
2515 int hlen = get_hlen(pack);
2517 /* Remove packet from queue */
2518 if (gtp_conf(gsn, version, peer, pack, len, &type, &cbp))
2519 return EOF;
2521 /* Decode information elements */
2522 if (gtpie_decaps(ie, version, pack + hlen, len - hlen)) {
2523 gsn->invalid++;
2524 GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
2525 "Invalid message format\n");
2526 if (gsn->cb_conf)
2527 gsn->cb_conf(type, EOF, NULL, cbp);
2528 return EOF;
2531 /* Extract cause value (mandatory) */
2532 if (gtpie_gettv1(ie, GTPIE_CAUSE, 0, &cause)) {
2533 gsn->missing++;
2534 GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
2535 "Missing mandatory information field\n");
2536 if (gsn->cb_conf)
2537 gsn->cb_conf(type, EOF, NULL, cbp);
2538 return EOF;
2541 /* Check the cause value (again) */
2542 if ((GTPCAUSE_ACC_REQ != cause) && (GTPCAUSE_NON_EXIST != cause)) {
2543 gsn->err_cause++;
2544 GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
2545 "Unexpected cause value received: %d\n", cause);
2546 if (gsn->cb_conf)
2547 gsn->cb_conf(type, cause, NULL, cbp);
2548 return EOF;
2551 /* Callback function to notify application */
2552 if (gsn->cb_conf)
2553 gsn->cb_conf(type, cause, NULL, cbp);
2555 return 0;
2558 /* Send Error Indication (response to a GPDU message */
2559 int gtp_error_ind_resp(struct gsn_t *gsn, int version,
2560 struct sockaddr_in *peer, int fd,
2561 void *pack, unsigned len)
2563 union gtp_packet packet;
2564 unsigned int length = get_default_gtp(version, GTP_ERROR, &packet);
2566 return gtp_resp(version, gsn, NULL, &packet, length, peer, fd,
2567 get_seq(pack), get_tid(pack));
2570 /* Handle Error Indication */
2571 int gtp_error_ind_conf(struct gsn_t *gsn, int version,
2572 struct sockaddr_in *peer, void *pack, unsigned len)
2574 struct pdp_t *pdp;
2576 /* Find the context in question */
2577 if (pdp_tidget(&pdp, be64toh(((union gtp_packet *)pack)->gtp0.h.tid))) {
2578 gsn->err_unknownpdp++;
2579 GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
2580 "Unknown PDP context\n");
2581 return EOF;
2584 gsn->err_unknownpdp++; /* TODO: Change counter */
2585 GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
2586 "Received Error Indication\n");
2588 if (gsn->cb_delete_context)
2589 gsn->cb_delete_context(pdp);
2590 pdp_freepdp(pdp);
2591 return 0;
2594 int gtp_gpdu_ind(struct gsn_t *gsn, int version,
2595 struct sockaddr_in *peer, int fd, void *pack, unsigned len)
2598 int hlen = GTP1_HEADER_SIZE_SHORT;
2600 /* Need to include code to verify packet src and dest addresses */
2601 struct pdp_t *pdp;
2603 if (version == 0) {
2604 if (pdp_getgtp0
2605 (&pdp, ntoh16(((union gtp_packet *)pack)->gtp0.h.flow))) {
2606 gsn->err_unknownpdp++;
2607 GTP_LOGPKG(LOGL_ERROR, peer, pack,
2608 len, "Unknown PDP context\n");
2609 return gtp_error_ind_resp(gsn, version, peer, fd, pack,
2610 len);
2612 hlen = GTP0_HEADER_SIZE;
2613 } else if (version == 1) {
2614 if (pdp_getgtp1
2615 (&pdp, ntoh32(((union gtp_packet *)pack)->gtp1l.h.tei))) {
2616 gsn->err_unknownpdp++;
2617 GTP_LOGPKG(LOGL_ERROR, peer, pack,
2618 len, "Unknown PDP context\n");
2619 return gtp_error_ind_resp(gsn, version, peer, fd, pack,
2620 len);
2623 /* Is this a long or a short header ? */
2624 if (((union gtp_packet *)pack)->gtp1l.h.flags & 0x07)
2625 hlen = GTP1_HEADER_SIZE_LONG;
2626 else
2627 hlen = GTP1_HEADER_SIZE_SHORT;
2628 } else {
2629 GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
2630 "Unknown version: %d\n", version);
2633 /* If the GPDU was not from the peer GSN tell him to delete context */
2634 if (memcmp(&peer->sin_addr, pdp->gsnru.v, pdp->gsnru.l)) { /* TODO Range? */
2635 gsn->err_unknownpdp++;
2636 GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
2637 "Unknown PDP context\n");
2638 return gtp_error_ind_resp(gsn, version, peer, fd, pack, len);
2641 /* Callback function */
2642 if (gsn->cb_data_ind != 0)
2643 return gsn->cb_data_ind(pdp, pack + hlen, len - hlen);
2645 return 0;
2648 /* Receives GTP packet and sends off for further processing
2649 * Function will check the validity of the header. If the header
2650 * is not valid the packet is either dropped or a version not
2651 * supported is returned to the peer.
2652 * TODO: Need to decide on return values! */
2653 int gtp_decaps0(struct gsn_t *gsn)
2655 unsigned char buffer[PACKET_MAX];
2656 struct sockaddr_in peer;
2657 socklen_t peerlen;
2658 int status;
2659 struct gtp0_header *pheader;
2660 int version = 0; /* GTP version should be determined from header! */
2661 int fd = gsn->fd0;
2663 /* TODO: Need strategy of userspace buffering and blocking */
2664 /* Currently read is non-blocking and send is blocking. */
2665 /* This means that the program have to wait for busy send calls... */
2667 while (1) { /* Loop until no more to read */
2668 if (fcntl(gsn->fd0, F_SETFL, O_NONBLOCK)) {
2669 LOGP(DLGTP, LOGL_ERROR, "fnctl()\n");
2670 return -1;
2672 peerlen = sizeof(peer);
2673 if ((status =
2674 recvfrom(gsn->fd0, buffer, sizeof(buffer), 0,
2675 (struct sockaddr *)&peer, &peerlen)) < 0) {
2676 if (errno == EAGAIN)
2677 return 0;
2678 gsn->err_readfrom++;
2679 LOGP(DLGTP, LOGL_ERROR,
2680 "recvfrom(fd0=%d, buffer=%lx, len=%zu) failed: status = %d error = %s\n",
2681 gsn->fd0, (unsigned long)buffer, sizeof(buffer),
2682 status, status ? strerror(errno) : "No error");
2683 return -1;
2686 /* Need at least 1 byte in order to check version */
2687 if (status < (1)) {
2688 gsn->empty++;
2689 GTP_LOGPKG(LOGL_ERROR, &peer, buffer,
2690 status, "Discarding packet - too small\n");
2691 continue;
2694 pheader = (struct gtp0_header *)(buffer);
2696 /* Version should be gtp0 (or earlier) */
2697 /* 09.60 is somewhat unclear on this issue. On gsn->fd0 we expect only */
2698 /* GTP 0 messages. If other version message is received we reply that we */
2699 /* only support version 0, implying that this is the only version */
2700 /* supported on this port */
2701 if (((pheader->flags & 0xe0) > 0x00)) {
2702 gsn->unsup++;
2703 GTP_LOGPKG(LOGL_ERROR, &peer, buffer,
2704 status, "Unsupported GTP version\n");
2705 gtp_unsup_req(gsn, 0, &peer, gsn->fd0, buffer, status); /* 29.60: 11.1.1 */
2706 continue;
2709 /* Check length of gtp0 packet */
2710 if (status < GTP0_HEADER_SIZE) {
2711 gsn->tooshort++;
2712 GTP_LOGPKG(LOGL_ERROR, &peer, buffer,
2713 status, "GTP0 packet too short\n");
2714 continue; /* Silently discard 29.60: 11.1.2 */
2717 /* Check packet length field versus length of packet */
2718 if (status != (ntoh16(pheader->length) + GTP0_HEADER_SIZE)) {
2719 gsn->tooshort++;
2720 GTP_LOGPKG(LOGL_ERROR, &peer, buffer,
2721 status,
2722 "GTP packet length field does not match actual length\n");
2723 continue; /* Silently discard */
2726 if ((gsn->mode == GTP_MODE_GGSN) &&
2727 ((pheader->type == GTP_CREATE_PDP_RSP) ||
2728 (pheader->type == GTP_UPDATE_PDP_RSP) ||
2729 (pheader->type == GTP_DELETE_PDP_RSP))) {
2730 gsn->unexpect++;
2731 GTP_LOGPKG(LOGL_ERROR, &peer, buffer,
2732 status,
2733 "Unexpected GTP Signalling Message\n");
2734 continue; /* Silently discard 29.60: 11.1.4 */
2737 if ((gsn->mode == GTP_MODE_SGSN) &&
2738 ((pheader->type == GTP_CREATE_PDP_REQ) ||
2739 (pheader->type == GTP_UPDATE_PDP_REQ) ||
2740 (pheader->type == GTP_DELETE_PDP_REQ))) {
2741 gsn->unexpect++;
2742 GTP_LOGPKG(LOGL_ERROR, &peer, buffer,
2743 status,
2744 "Unexpected GTP Signalling Message\n");
2745 continue; /* Silently discard 29.60: 11.1.4 */
2748 switch (pheader->type) {
2749 case GTP_ECHO_REQ:
2750 gtp_echo_ind(gsn, version, &peer, fd, buffer, status);
2751 break;
2752 case GTP_ECHO_RSP:
2753 gtp_echo_conf(gsn, version, &peer, buffer, status);
2754 break;
2755 case GTP_NOT_SUPPORTED:
2756 gtp_unsup_ind(gsn, &peer, buffer, status);
2757 break;
2758 case GTP_CREATE_PDP_REQ:
2759 gtp_create_pdp_ind(gsn, version, &peer, fd, buffer,
2760 status);
2761 break;
2762 case GTP_CREATE_PDP_RSP:
2763 gtp_create_pdp_conf(gsn, version, &peer, buffer,
2764 status);
2765 break;
2766 case GTP_UPDATE_PDP_REQ:
2767 gtp_update_pdp_ind(gsn, version, &peer, fd, buffer,
2768 status);
2769 break;
2770 case GTP_UPDATE_PDP_RSP:
2771 gtp_update_pdp_conf(gsn, version, &peer, buffer,
2772 status);
2773 break;
2774 case GTP_DELETE_PDP_REQ:
2775 gtp_delete_pdp_ind(gsn, version, &peer, fd, buffer,
2776 status);
2777 break;
2778 case GTP_DELETE_PDP_RSP:
2779 gtp_delete_pdp_conf(gsn, version, &peer, buffer,
2780 status);
2781 break;
2782 case GTP_ERROR:
2783 gtp_error_ind_conf(gsn, version, &peer, buffer, status);
2784 break;
2785 case GTP_GPDU:
2786 gtp_gpdu_ind(gsn, version, &peer, fd, buffer, status);
2787 break;
2788 default:
2789 gsn->unknown++;
2790 GTP_LOGPKG(LOGL_ERROR, &peer, buffer, status,
2791 "Unknown GTP message type received: %d\n",
2792 pheader->type);
2793 break;
2798 int gtp_decaps1c(struct gsn_t *gsn)
2800 unsigned char buffer[PACKET_MAX];
2801 struct sockaddr_in peer;
2802 socklen_t peerlen;
2803 int status;
2804 struct gtp1_header_short *pheader;
2805 int version = 1; /* TODO GTP version should be determined from header! */
2806 int fd = gsn->fd1c;
2808 /* TODO: Need strategy of userspace buffering and blocking */
2809 /* Currently read is non-blocking and send is blocking. */
2810 /* This means that the program have to wait for busy send calls... */
2812 while (1) { /* Loop until no more to read */
2813 if (fcntl(fd, F_SETFL, O_NONBLOCK)) {
2814 LOGP(DLGTP, LOGL_ERROR, "fnctl()\n");
2815 return -1;
2817 peerlen = sizeof(peer);
2818 if ((status =
2819 recvfrom(fd, buffer, sizeof(buffer), 0,
2820 (struct sockaddr *)&peer, &peerlen)) < 0) {
2821 if (errno == EAGAIN)
2822 return 0;
2823 gsn->err_readfrom++;
2824 LOGP(DLGTP, LOGL_ERROR,
2825 "recvfrom(fd=%d, buffer=%lx, len=%zu) failed: status = %d error = %s\n",
2826 fd, (unsigned long)buffer, sizeof(buffer),
2827 status, status ? strerror(errno) : "No error");
2828 return -1;
2831 /* Need at least 1 byte in order to check version */
2832 if (status < (1)) {
2833 gsn->empty++;
2834 GTP_LOGPKG(LOGL_ERROR, &peer, buffer,
2835 status, "Discarding packet - too small\n");
2836 continue;
2839 pheader = (struct gtp1_header_short *)(buffer);
2841 /* Version must be no larger than GTP 1 */
2842 if (((pheader->flags & 0xe0) > 0x20)) {
2843 gsn->unsup++;
2844 GTP_LOGPKG(LOGL_ERROR, &peer, buffer,
2845 status, "Unsupported GTP version\n");
2846 gtp_unsup_req(gsn, version, &peer, fd, buffer, status);
2847 /*29.60: 11.1.1 */
2848 continue;
2851 /* Version must be at least GTP 1 */
2852 /* 29.060 is somewhat unclear on this issue. On gsn->fd1c we expect only */
2853 /* GTP 1 messages. If GTP 0 message is received we silently discard */
2854 /* the message */
2855 if (((pheader->flags & 0xe0) < 0x20)) {
2856 gsn->unsup++;
2857 GTP_LOGPKG(LOGL_ERROR, &peer, buffer,
2858 status, "Unsupported GTP version\n");
2859 continue;
2862 /* Check packet flag field */
2863 if (((pheader->flags & 0xf7) != 0x32)) {
2864 gsn->unsup++;
2865 GTP_LOGPKG(LOGL_ERROR, &peer, buffer,
2866 status, "Unsupported packet flags: 0x%02x\n", pheader->flags);
2867 continue;
2870 /* Check length of packet */
2871 if (status < GTP1_HEADER_SIZE_LONG) {
2872 gsn->tooshort++;
2873 GTP_LOGPKG(LOGL_ERROR, &peer, buffer,
2874 status, "GTP packet too short\n");
2875 continue; /* Silently discard 29.60: 11.1.2 */
2878 /* Check packet length field versus length of packet */
2879 if (status !=
2880 (ntoh16(pheader->length) + GTP1_HEADER_SIZE_SHORT)) {
2881 gsn->tooshort++;
2882 GTP_LOGPKG(LOGL_ERROR, &peer, buffer,
2883 status,
2884 "GTP packet length field does not match actual length\n");
2885 continue; /* Silently discard */
2888 /* Check for extension headers */
2889 /* TODO: We really should cycle through the headers and determine */
2890 /* if any have the comprehension required flag set */
2891 if (((pheader->flags & 0x04) != 0x00)) {
2892 gsn->unsup++;
2893 GTP_LOGPKG(LOGL_ERROR, &peer, buffer,
2894 status, "Unsupported extension header\n");
2895 gtp_extheader_req(gsn, version, &peer, fd, buffer,
2896 status);
2898 continue;
2901 if ((gsn->mode == GTP_MODE_GGSN) &&
2902 ((pheader->type == GTP_CREATE_PDP_RSP) ||
2903 (pheader->type == GTP_UPDATE_PDP_RSP) ||
2904 (pheader->type == GTP_DELETE_PDP_RSP))) {
2905 gsn->unexpect++;
2906 GTP_LOGPKG(LOGL_ERROR, &peer, buffer,
2907 status,
2908 "Unexpected GTP Signalling Message\n");
2909 continue; /* Silently discard 29.60: 11.1.4 */
2912 if ((gsn->mode == GTP_MODE_SGSN) &&
2913 ((pheader->type == GTP_CREATE_PDP_REQ) ||
2914 (pheader->type == GTP_UPDATE_PDP_REQ) ||
2915 (pheader->type == GTP_DELETE_PDP_REQ))) {
2916 gsn->unexpect++;
2917 GTP_LOGPKG(LOGL_ERROR, &peer, buffer,
2918 status,
2919 "Unexpected GTP Signalling Message\n");
2920 continue; /* Silently discard 29.60: 11.1.4 */
2923 switch (pheader->type) {
2924 case GTP_ECHO_REQ:
2925 gtp_echo_ind(gsn, version, &peer, fd, buffer, status);
2926 break;
2927 case GTP_ECHO_RSP:
2928 gtp_echo_conf(gsn, version, &peer, buffer, status);
2929 break;
2930 case GTP_NOT_SUPPORTED:
2931 gtp_unsup_ind(gsn, &peer, buffer, status);
2932 break;
2933 case GTP_SUPP_EXT_HEADER:
2934 gtp_extheader_ind(gsn, &peer, buffer, status);
2935 break;
2936 case GTP_CREATE_PDP_REQ:
2937 gtp_create_pdp_ind(gsn, version, &peer, fd, buffer,
2938 status);
2939 break;
2940 case GTP_CREATE_PDP_RSP:
2941 gtp_create_pdp_conf(gsn, version, &peer, buffer,
2942 status);
2943 break;
2944 case GTP_UPDATE_PDP_REQ:
2945 gtp_update_pdp_ind(gsn, version, &peer, fd, buffer,
2946 status);
2947 break;
2948 case GTP_UPDATE_PDP_RSP:
2949 gtp_update_pdp_conf(gsn, version, &peer, buffer,
2950 status);
2951 break;
2952 case GTP_DELETE_PDP_REQ:
2953 gtp_delete_pdp_ind(gsn, version, &peer, fd, buffer,
2954 status);
2955 break;
2956 case GTP_DELETE_PDP_RSP:
2957 gtp_delete_pdp_conf(gsn, version, &peer, buffer,
2958 status);
2959 break;
2960 case GTP_ERROR:
2961 gtp_error_ind_conf(gsn, version, &peer, buffer, status);
2962 break;
2963 default:
2964 gsn->unknown++;
2965 GTP_LOGPKG(LOGL_ERROR, &peer, buffer, status,
2966 "Unknown GTP message type received: %u\n",
2967 pheader->type);
2968 break;
2973 int gtp_decaps1u(struct gsn_t *gsn)
2975 unsigned char buffer[PACKET_MAX];
2976 struct sockaddr_in peer;
2977 socklen_t peerlen;
2978 int status;
2979 struct gtp1_header_short *pheader;
2980 int version = 1; /* GTP version should be determined from header! */
2981 int fd = gsn->fd1u;
2983 /* TODO: Need strategy of userspace buffering and blocking */
2984 /* Currently read is non-blocking and send is blocking. */
2985 /* This means that the program have to wait for busy send calls... */
2987 while (1) { /* Loop until no more to read */
2988 if (fcntl(gsn->fd1u, F_SETFL, O_NONBLOCK)) {
2989 LOGP(DLGTP, LOGL_ERROR, "fnctl()\n");
2990 return -1;
2992 peerlen = sizeof(peer);
2993 if ((status =
2994 recvfrom(gsn->fd1u, buffer, sizeof(buffer), 0,
2995 (struct sockaddr *)&peer, &peerlen)) < 0) {
2996 if (errno == EAGAIN)
2997 return 0;
2998 gsn->err_readfrom++;
2999 LOGP(DLGTP, LOGL_ERROR,
3000 "recvfrom(fd1u=%d, buffer=%lx, len=%zu) failed: status = %d error = %s\n",
3001 gsn->fd1u, (unsigned long)buffer,
3002 sizeof(buffer), status,
3003 status ? strerror(errno) : "No error");
3004 return -1;
3007 /* Need at least 1 byte in order to check version */
3008 if (status < (1)) {
3009 gsn->empty++;
3010 GTP_LOGPKG(LOGL_ERROR, &peer, buffer,
3011 status, "Discarding packet - too small\n");
3012 continue;
3015 pheader = (struct gtp1_header_short *)(buffer);
3017 /* Version must be no larger than GTP 1 */
3018 if (((pheader->flags & 0xe0) > 0x20)) {
3019 gsn->unsup++;
3020 GTP_LOGPKG(LOGL_ERROR, &peer, buffer,
3021 status, "Unsupported GTP version\n");
3022 gtp_unsup_req(gsn, 1, &peer, gsn->fd1c, buffer, status); /*29.60: 11.1.1 */
3023 continue;
3026 /* Version must be at least GTP 1 */
3027 /* 29.060 is somewhat unclear on this issue. On gsn->fd1c we expect only */
3028 /* GTP 1 messages. If GTP 0 message is received we silently discard */
3029 /* the message */
3030 if (((pheader->flags & 0xe0) < 0x20)) {
3031 gsn->unsup++;
3032 GTP_LOGPKG(LOGL_ERROR, &peer, buffer,
3033 status, "Unsupported GTP version\n");
3034 continue;
3037 /* Check packet flag field (allow both with and without sequence number) */
3038 if (((pheader->flags & 0xf5) != 0x30)) {
3039 gsn->unsup++;
3040 GTP_LOGPKG(LOGL_ERROR, &peer, buffer,
3041 status, "Unsupported packet flags 0x%02x\n", pheader->flags);
3042 continue;
3045 /* Check length of packet */
3046 if (status < GTP1_HEADER_SIZE_SHORT) {
3047 gsn->tooshort++;
3048 GTP_LOGPKG(LOGL_ERROR, &peer, buffer,
3049 status, "GTP packet too short\n");
3050 continue; /* Silently discard 29.60: 11.1.2 */
3053 /* Check packet length field versus length of packet */
3054 if (status !=
3055 (ntoh16(pheader->length) + GTP1_HEADER_SIZE_SHORT)) {
3056 gsn->tooshort++;
3057 GTP_LOGPKG(LOGL_ERROR, &peer, buffer,
3058 status,
3059 "GTP packet length field does not match actual length\n");
3060 continue; /* Silently discard */
3063 /* Check for extension headers */
3064 /* TODO: We really should cycle through the headers and determine */
3065 /* if any have the comprehension required flag set */
3066 if (((pheader->flags & 0x04) != 0x00)) {
3067 gsn->unsup++;
3068 GTP_LOGPKG(LOGL_ERROR, &peer, buffer,
3069 status, "Unsupported extension header\n");
3070 gtp_extheader_req(gsn, version, &peer, fd, buffer,
3071 status);
3073 continue;
3076 switch (pheader->type) {
3077 case GTP_ECHO_REQ:
3078 gtp_echo_ind(gsn, version, &peer, fd, buffer, status);
3079 break;
3080 case GTP_ECHO_RSP:
3081 gtp_echo_conf(gsn, version, &peer, buffer, status);
3082 break;
3083 case GTP_SUPP_EXT_HEADER:
3084 gtp_extheader_ind(gsn, &peer, buffer, status);
3085 break;
3086 case GTP_ERROR:
3087 gtp_error_ind_conf(gsn, version, &peer, buffer, status);
3088 break;
3089 /* Supported header extensions */
3090 case GTP_GPDU:
3091 gtp_gpdu_ind(gsn, version, &peer, fd, buffer, status);
3092 break;
3093 default:
3094 gsn->unknown++;
3095 GTP_LOGPKG(LOGL_ERROR, &peer, buffer, status,
3096 "Unknown GTP message type received: %u\n",
3097 pheader->type);
3098 break;
3103 int gtp_data_req(struct gsn_t *gsn, struct pdp_t *pdp, void *pack, unsigned len)
3105 union gtp_packet packet;
3106 struct sockaddr_in addr;
3107 int fd;
3108 int length;
3110 memset(&addr, 0, sizeof(addr));
3111 addr.sin_family = AF_INET;
3112 #if defined(__FreeBSD__) || defined(__APPLE__)
3113 addr.sin_len = sizeof(addr);
3114 #endif
3116 memcpy(&addr.sin_addr, pdp->gsnru.v, pdp->gsnru.l); /* TODO range check */
3118 if (pdp->version == 0) {
3120 length = GTP0_HEADER_SIZE + len;
3121 addr.sin_port = htons(GTP0_PORT);
3122 fd = gsn->fd0;
3124 get_default_gtp(0, GTP_GPDU, &packet);
3125 packet.gtp0.h.length = hton16(len);
3126 packet.gtp0.h.seq = hton16(pdp->gtpsntx++);
3127 packet.gtp0.h.flow = hton16(pdp->flru);
3128 packet.gtp0.h.tid = htobe64(pdp_gettid(pdp->imsi, pdp->nsapi));
3130 if (len > sizeof(union gtp_packet) - sizeof(struct gtp0_header)) {
3131 gsn->err_memcpy++;
3132 LOGP(DLGTP, LOGL_ERROR,
3133 "Memcpy failed: %u > %zu\n", len,
3134 sizeof(union gtp_packet) -
3135 sizeof(struct gtp0_header));
3136 return EOF;
3138 memcpy(packet.gtp0.p, pack, len); /* TODO Should be avoided! */
3139 } else if (pdp->version == 1) {
3141 length = GTP1_HEADER_SIZE_LONG + len;
3142 addr.sin_port = htons(GTP1U_PORT);
3143 fd = gsn->fd1u;
3145 get_default_gtp(1, GTP_GPDU, &packet);
3146 packet.gtp1l.h.length = hton16(len - GTP1_HEADER_SIZE_SHORT +
3147 GTP1_HEADER_SIZE_LONG);
3148 packet.gtp1l.h.seq = hton16(pdp->gtpsntx++);
3149 packet.gtp1l.h.tei = hton32(pdp->teid_gn);
3151 if (len >
3152 sizeof(union gtp_packet) -
3153 sizeof(struct gtp1_header_long)) {
3154 gsn->err_memcpy++;
3155 LOGP(DLGTP, LOGL_ERROR,
3156 "Memcpy failed: %u > %zu\n", len,
3157 sizeof(union gtp_packet) -
3158 sizeof(struct gtp0_header));
3159 return EOF;
3161 memcpy(packet.gtp1l.p, pack, len); /* TODO Should be avoided! */
3162 } else {
3163 LOGP(DLGTP, LOGL_ERROR, "Unknown version: %d\n", pdp->version);
3164 return EOF;
3167 if (fcntl(fd, F_SETFL, 0)) {
3168 LOGP(DLGTP, LOGL_ERROR, "fnctl()\n");
3169 return -1;
3172 if (sendto(fd, &packet, length, 0,
3173 (struct sockaddr *)&addr, sizeof(addr)) < 0) {
3174 gsn->err_sendto++;
3175 LOGP(DLGTP, LOGL_ERROR,
3176 "Sendto(fd=%d, msg=%lx, len=%d) failed: Error = %s\n", fd,
3177 (unsigned long)&packet, GTP0_HEADER_SIZE + len,
3178 strerror(errno));
3179 return EOF;
3181 return 0;
3184 /* ***********************************************************
3185 * Conversion functions
3186 *************************************************************/
3188 int char2ul_t(char *src, struct ul_t dst)
3190 dst.l = strlen(src) + 1;
3191 dst.v = malloc(dst.l);
3192 dst.v[0] = dst.l - 1;
3193 memcpy(&dst.v[1], src, dst.v[0]);
3194 return 0;
3197 /* ***********************************************************
3198 * IP address conversion functions
3199 * There exist several types of address representations:
3200 * - eua: End User Address. (29.060, 7.7.27, message type 128)
3201 * Used for signalling address to mobile station. Supports IPv4
3202 * IPv6 x.25 etc. etc.
3203 * - gsna: GSN Address. (29.060, 7.7.32, message type 133): IP address
3204 * of GSN. If length is 4 it is IPv4. If length is 16 it is IPv6.
3205 * - in_addr: IPv4 address struct.
3206 * - sockaddr_in: Socket API representation of IP address and
3207 * port number.
3208 *************************************************************/
3210 int ipv42eua(struct ul66_t *eua, struct in_addr *src)
3212 eua->v[0] = 0xf1; /* IETF */
3213 eua->v[1] = 0x21; /* IPv4 */
3214 if (src) {
3215 eua->l = 6;
3216 memcpy(&eua->v[2], src, 4);
3217 } else {
3218 eua->l = 2;
3220 return 0;
3223 int eua2ipv4(struct in_addr *dst, struct ul66_t *eua)
3225 if ((eua->l != 6) || (eua->v[0] != 0xf1) || (eua->v[1] = 0x21))
3226 return -1; /* Not IPv4 address */
3227 memcpy(dst, &eua->v[2], 4);
3228 return 0;
3231 int gsna2in_addr(struct in_addr *dst, struct ul16_t *gsna)
3233 memset(dst, 0, sizeof(struct in_addr));
3234 if (gsna->l != 4)
3235 return EOF; /* Return if not IPv4 */
3236 memcpy(dst, gsna->v, gsna->l);
3237 return 0;
3240 int in_addr2gsna(struct ul16_t *gsna, struct in_addr *src)
3242 memset(gsna, 0, sizeof(struct ul16_t));
3243 gsna->l = 4;
3244 memcpy(gsna->v, src, gsna->l);
3245 return 0;