Coverage Report

Created: 2026-03-07 06:40

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/open5gs/lib/gtp/v2/conv.c
Line
Count
Source
1
/*
2
 * Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
3
 *
4
 * This file is part of Open5GS.
5
 *
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU Affero General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
18
 */
19
20
#include "ogs-gtp.h"
21
22
int ogs_gtp2_f_teid_to_sockaddr(
23
    ogs_gtp2_f_teid_t *f_teid, uint16_t port, ogs_sockaddr_t **list)
24
0
{
25
0
    ogs_sockaddr_t *addr = NULL, *addr6 = NULL;
26
27
0
    ogs_assert(f_teid);
28
0
    ogs_assert(list);
29
30
0
    addr = ogs_calloc(1, sizeof(ogs_sockaddr_t));
31
0
    if (!addr) {
32
0
        ogs_error("ogs_calloc() failed");
33
0
        return OGS_ERROR;
34
0
    }
35
0
    addr->ogs_sa_family = AF_INET;
36
0
    addr->ogs_sin_port = htobe16(port);
37
38
0
    addr6 = ogs_calloc(1, sizeof(ogs_sockaddr_t));
39
0
    if (!addr6) {
40
0
        ogs_error("ogs_calloc() failed");
41
0
        ogs_free(addr);
42
0
        return OGS_ERROR;
43
0
    }
44
0
    addr6->ogs_sa_family = AF_INET6;
45
0
    addr6->ogs_sin_port = htobe16(port);
46
47
0
    if (f_teid->ipv4 && f_teid->ipv6) {
48
0
        addr->next = addr6;
49
50
0
        addr->sin.sin_addr.s_addr = f_teid->both.addr;
51
0
        memcpy(addr6->sin6.sin6_addr.s6_addr, f_teid->both.addr6, OGS_IPV6_LEN);
52
53
0
        *list = addr;
54
0
    } else if (f_teid->ipv4) {
55
0
        addr->sin.sin_addr.s_addr = f_teid->addr;
56
0
        ogs_free(addr6);
57
58
0
        *list = addr;
59
0
    } else if (f_teid->ipv6) {
60
0
        memcpy(addr6->sin6.sin6_addr.s6_addr, f_teid->addr6, OGS_IPV6_LEN);
61
0
        ogs_free(addr);
62
63
0
        *list = addr6;
64
0
    } else {
65
0
        ogs_error("No IPv4 or IPv6");
66
0
        ogs_free(addr);
67
0
        ogs_free(addr6);
68
0
        return OGS_ERROR;
69
0
    }
70
71
0
    return OGS_OK;
72
0
}
73
74
int ogs_gtp2_sockaddr_to_f_teid(ogs_sockaddr_t *addr, ogs_sockaddr_t *addr6,
75
        ogs_gtp2_f_teid_t *f_teid, int *len)
76
0
{
77
0
    ogs_assert(f_teid);
78
79
0
    if (addr && addr6) {
80
0
        f_teid->ipv4 = 1;
81
0
        f_teid->both.addr = addr->sin.sin_addr.s_addr;
82
0
        f_teid->ipv6 = 1;
83
0
        memcpy(f_teid->both.addr6, addr6->sin6.sin6_addr.s6_addr, OGS_IPV6_LEN);
84
0
        *len = OGS_GTP2_F_TEID_IPV4V6_LEN;
85
0
    } else if (addr) {
86
0
        f_teid->ipv4 = 1;
87
0
        f_teid->ipv6 = 0;
88
0
        f_teid->addr = addr->sin.sin_addr.s_addr;
89
0
        *len = OGS_GTP2_F_TEID_IPV4_LEN;
90
0
    } else if (addr6) {
91
0
        f_teid->ipv4 = 0;
92
0
        f_teid->ipv6 = 1;
93
0
        memcpy(f_teid->addr6, addr6->sin6.sin6_addr.s6_addr, OGS_IPV6_LEN);
94
0
        *len = OGS_GTP2_F_TEID_IPV6_LEN;
95
0
    } else {
96
0
        ogs_error("No IPv4 or IPv6");
97
0
        return OGS_ERROR;
98
0
    }
99
100
0
    return OGS_OK;
101
0
}
102
103
int ogs_gtp2_f_teid_to_ip(ogs_gtp2_f_teid_t *f_teid, ogs_ip_t *ip)
104
0
{
105
0
    ogs_assert(ip);
106
0
    ogs_assert(f_teid);
107
108
0
    memset(ip, 0, sizeof(ogs_ip_t));
109
110
0
    ip->ipv4 = f_teid->ipv4;
111
0
    ip->ipv6 = f_teid->ipv6;
112
113
0
    if (ip->ipv4 && ip->ipv6) {
114
0
        ip->addr = f_teid->both.addr;
115
0
        memcpy(ip->addr6, f_teid->both.addr6, OGS_IPV6_LEN);
116
0
        ip->len = OGS_IPV4V6_LEN;
117
0
    } else if (ip->ipv4) {
118
0
        ip->addr = f_teid->addr;
119
0
        ip->len = OGS_IPV4_LEN;
120
0
    } else if (ip->ipv6) {
121
0
        memcpy(ip->addr6, f_teid->addr6, OGS_IPV6_LEN);
122
0
        ip->len = OGS_IPV6_LEN;
123
0
    } else {
124
0
        ogs_error("No IPv4 or IPv6");
125
0
        return OGS_ERROR;
126
0
    }
127
128
0
    return OGS_OK;
129
0
}
130
131
int ogs_gtp2_ip_to_f_teid(ogs_ip_t *ip, ogs_gtp2_f_teid_t *f_teid, int *len)
132
0
{
133
0
    ogs_assert(ip);
134
0
    ogs_assert(f_teid);
135
136
0
    f_teid->ipv4 = ip->ipv4;
137
0
    f_teid->ipv6 = ip->ipv6;
138
139
0
    if (f_teid->ipv4 && f_teid->ipv6) {
140
0
        f_teid->both.addr = ip->addr;
141
0
        memcpy(f_teid->both.addr6, ip->addr6, OGS_IPV6_LEN);
142
0
        *len = OGS_GTP2_F_TEID_IPV4V6_LEN;
143
0
    } else if (f_teid->ipv4) {
144
0
        f_teid->addr = ip->addr;
145
0
        *len = OGS_GTP2_F_TEID_IPV4_LEN;
146
0
    } else if (f_teid->ipv6) {
147
0
        memcpy(f_teid->addr6, ip->addr6, OGS_IPV6_LEN);
148
0
        *len = OGS_GTP2_F_TEID_IPV6_LEN;
149
0
    } else {
150
0
        ogs_error("No IPv4 or IPv6");
151
0
        return OGS_ERROR;
152
0
    }
153
154
0
    return OGS_OK;
155
0
}