docs: add Jon as minor contributor
[netsniff-ng.git] / src / mops_mpls.c
blob5a03a0ae17120a5dc68087580572c2272b5a51c6
1 /*
2 * Mausezahn - A fast versatile traffic generator
3 * Copyright (C) 2008-2010 Herbert Haas
4 *
5 * This program is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU General Public License version 2 as published by the
7 * Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12 * details.
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, see http://www.gnu.org/licenses/gpl-2.0.html
20 #include "mz.h"
21 #include "mops.h"
23 // Assigns MPLS tag at position i (starting at zero!) with values:
24 //
25 // m ... total number of tags (important to set BoS in last tag)
26 // Label ... label value
27 // Exp ... EXP field (typically CoS)
28 // TTL ... Time To Live
29 //
30 // NOTE: Two usage possibilities!
31 //
32 // 1.) When called from for-loop to add all tags the total size mpls_s
33 // is updated continuously and the BoS is set in the last tag.
34 // Therefore set m = total number of tags!
35 //
36 // 2.) But when changing a particular tag within an existing MPLS stack
37 // the total number of tags does not change, therefore use m=0.
38 //
39 // RETURN VALUE: 0 upon success, 1 upon failure
40 //
41 int mops_mpls(struct mops *mp, int i, int m, u_int32_t Label, u_int8_t Exp, u_int8_t TTL)
43 u_int8_t *ptr;
45 if ((m) && (i>=m)) return 1; // label index greater than number of labels!
46 if (Label > 1048575) return 1;
47 if (Exp > 7) return 1;
49 // Create binary tag: Label(20) EXP(3) BoS(1) TTL(8)
50 Label <<= 4;
51 ptr = (u_int8_t *) &Label;
52 mp->mpls[4*i+0] = *(ptr+2);
53 mp->mpls[4*i+1] = *(ptr+1);
54 mp->mpls[4*i+2] = *(ptr+0);
55 Exp <<= 1;
56 mp->mpls[4*i+2] |= Exp;
57 mp->mpls[4*i+3] = TTL;
59 if ((m) && (i==(m-1))) // reached last tag!
61 mp->mpls[4*i+2] |= 0x01; // set BoS in last tag
62 mp->mpls_s =4*m;
63 mp->use_MPLS = 1;
64 if ( (mp->eth_type != 0x8847) && (mp->eth_type != 0x8848) )
66 mp->eth_type_backup = mp->eth_type;
68 mp->eth_type = 0x8847;
70 return 0;
74 // Remove MPLS tags from packet mp
75 //
76 // j indicates which tag to be removed (1..n)
77 // j=0 means: remove all tags!
78 //
79 // RETURN VALUE: 1 upon failure, 0 upon success
80 int mops_mpls_remove (struct mops *mp, int j)
82 int a, b, k;
85 if (j==0) // remove all tags
87 if (mp->use_MPLS)
89 mp->mpls_s=0;
90 mp->use_MPLS=0;
91 mp->eth_type = mp->eth_type_backup; // restore original ethertype
92 return 0;
94 else
95 return 1;
98 k = mp->mpls_s/4;
99 if (j>k) return 1; // The packet only consists of k tag(s)
101 if (k==1) // only delete the single tag
103 mp->mpls_s=0;
104 mp->use_MPLS=0;
105 mp->eth_type = mp->eth_type_backup; // restore original ethertype
106 return 0;
109 // if we got here we have more than one tag:
111 if (j==k) // remove last tag (of several)
113 mp->mpls_s -=4;
114 return 0;
117 // remove some non-ending tag: 0, 1, 2, 3
118 a = (j-1)*4; // target
119 b = j*4; // source (what should be copied)
120 memcpy(&mp->mpls[a], &mp->mpls[b], (k-j)*4);
121 mp->mpls_s -=4;
122 return 0;
126 // Set BOS in tag k where k=1..n
127 int mops_mpls_bos (struct mops *mp, int k)
129 int n;
131 n = mp->mpls_s/4; // n = total number of tags
132 if (k>n) return 1;
134 mp->mpls[(k-1)*4+2] |= 0x01;
135 return 0;
139 // Unset BOS in tag k where k=1..n
140 int mops_mpls_nobos (struct mops *mp, int k)
142 int n;
144 n = mp->mpls_s/4; // n = total number of tags
145 if (k>n) return 1;
147 mp->mpls[(k-1)*4+2] &= 0xfe;
148 return 0;